Search code examples
flutterdatetimedartintl

Using Dart / Flutter, how would I compare the values of two textfields to provide a time duration output?


Imagine I have 2 textfields that a user can input a 24 hour time in the format 1400 for example. Textfield 1 is the start time of a shift and textfield 2 is the end time. Ideally I'd like the duration between the two times to be displayed in a text widget when either textfields onSubmit is called or even if 1 of the textfields loses focus. I'm able to calculate and display the duration of 2 hard coded strings using the intl package with x.difference(y) but I'm struggling to get to this point with the textfields. Thanks for your help.

edit thinking about it after the initial post, the need for textfields isn't 100% required. the two times to compare could come from something like a datetime picker instead. what matters is that i've tried textfields, datetime picker and the time picker but can't arrive a a solution.

import 'package:flutter/material.dart';

class ActivityLog extends StatefulWidget {
  @override
  _ActivityLogState createState() => _ActivityLogState();
}

class _ActivityLogState extends State<ActivityLog> {
  TextEditingController _controller1 = TextEditingController();
  TextEditingController _controller2 = TextEditingController();

  String duration = '0000';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Activity Log'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _controller1,
              maxLength: 4,
              maxLines: 1,
              keyboardType: TextInputType.datetime,
              decoration: InputDecoration(
                labelText: 'Start time',
                hintText: 'hhmm',
                counterText: '',
              ),
            ),
            TextField(
              controller: _controller2,
              maxLength: 4,
              maxLines: 1,
              keyboardType: TextInputType.datetime,
              decoration: InputDecoration(
                labelText: 'Finish time',
                hintText: 'hhmm',
                counterText: '',
              ),
            ),
            Text('Duration: $duration'),
            /*
            can't figure out how to get the input from the textfields in the format of
            HHmm (hours and minutes) and calculate the duration which is to be displayed
            in the text widget above 
            */
          ],
        ),
      ),
    );
  }
}

Solution

  • See if below works for you. Clearly I am not doing any validation, but this could be the start and you can build from that. Here is alsp an image of how it looks here.

    import 'package:flutter/material.dart';
    import 'package:intl/intl.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      final _controller1 = TextEditingController();
      final _controller2 = TextEditingController();
    
      var _result = "";
    
      String addColon(String s) {
        return s.substring(0, 2) + ":" + s.substring(2);
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: SafeArea(
              child: Column(
                children: [
                  TextField(controller: _controller1),
                  TextField(controller: _controller2),
                  ElevatedButton(
                      onPressed: () {
                        var _d1 =
                            DateFormat.Hm().parse(addColon(_controller1.text));
                        var _d2 =
                            DateFormat.Hm().parse(addColon(_controller2.text));
    
                        setState(() {
                          _result =
                              '${_d2.difference(_d1).inSeconds.toString()} seconds';
                        });
                      },
                      child: const Text("Diff")),
                  const SizedBox(height: 50),
                  Text(_result),
                ],
              ),
            ),
          ),
        );
      }
    }