Q:

Flutter: Keeping Time

Trying to show a static timer that resets itself weekly based on current eastern time, For example the screen shows a timer, Days : Hours : Minutes : seconds (Example: 7: 00 : 00 : 00), counting down and resets itself at the end of every Sunday or at the start of Monday. I have a general concept that it involves DateTime, Timer and Stopwatch but having a hard time putting it together.

A:

Create a StatefulWidget that gets and stores the current time whenever your Timer updates. In the build method, calculate and format the time difference:
import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Week Countdown',
      home: TestPage(),
    );
  }
}

class TestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Week Countdown')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(
              'Time until next week:',
              style: Theme.of(context).textTheme.headline,
            ),
            WeekCountdown()
          ],
        ),
      ),
    );
  }
}

class WeekCountdown extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _WeekCountdownState();
}

class _WeekCountdownState extends State<WeekCountdown> {
  Timer _timer;
  DateTime _currentTime;

  @override
  void initState() {
    super.initState();
    _currentTime = DateTime.now();
    _timer = Timer.periodic(Duration(seconds: 1), _onTimeChange);
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

  void _onTimeChange(Timer timer) {
    setState(() {
      _currentTime = DateTime.now();
    });
  }

  @override
  Widget build(BuildContext context) {
    final startOfNextWeek = calculateStartOfNextWeek(_currentTime);
    final remaining = startOfNextWeek.difference(_currentTime);

    final days = remaining.inDays;
    final hours = remaining.inHours - remaining.inDays * 24;
    final minutes = remaining.inMinutes - remaining.inHours * 60;
    final seconds = remaining.inSeconds - remaining.inMinutes * 60;

    final formattedRemaining = '$days : $hours : $minutes : $seconds';

    return Text(formattedRemaining);
  }
}

DateTime calculateStartOfNextWeek(DateTime time) {
  final daysUntilNextWeek = 8 - time.weekday;
  return DateTime(time.year, time.month, time.day + daysUntilNextWeek);
}

