Dart Lesson 90 of 102 4 min read
Date and Time in Dart: DateTime and Duration
Work with dates and times in Dart: create, parse, format, compare and calculate with DateTime and Duration, including UTC and time zones.
On this page
Dart handles dates with two classes. DateTime is a moment in time. Duration is a length of time.
Creating a DateTime #
void main() {
final now = DateTime.now();
final birthday = DateTime(1998, 4, 23);
final meeting = DateTime(2026, 10, 15, 14, 30);
final parsed = DateTime.parse('2026-12-31T23:59:00');
print(now.year >= 2026);
print(birthday);
print(meeting);
print(parsed);
}
true
1998-04-23 00:00:00.000
2026-10-15 14:30:00.000
2026-12-31 23:59:00.000
Months are numbered 1 to 12 and days start at 1, as you would expect.
DateTime.parse throws on text it cannot read. Use DateTime.tryParse, which returns null, for input you do not control.
Reading the parts #
void main() {
final date = DateTime(2026, 10, 15, 14, 30, 45);
print(date.year);
print(date.month);
print(date.day);
print(date.hour);
print(date.minute);
print(date.second);
print(date.weekday); // 1 = Monday ... 7 = Sunday
print(date.weekday == DateTime.thursday);
}
2026
10
15
14
30
45
4
true
Duration #
void main() {
const lesson = Duration(minutes: 45);
const breakTime = Duration(minutes: 15);
final total = lesson * 3 + breakTime * 2;
print(total);
print(total.inMinutes);
print(total.inHours);
print('${total.inHours}h ${total.inMinutes.remainder(60)}m');
print(lesson > breakTime);
}
2:45:00.000000
165
2
2h 45m
true
Date arithmetic #
A DateTime cannot be changed. add and subtract return a new one.
void main() {
final start = DateTime(2026, 1, 30, 9, 0);
print(start.add(Duration(days: 7)));
print(start.subtract(Duration(hours: 10)));
// Adding months or years: build a new date.
print(DateTime(start.year, start.month + 1, start.day));
print(DateTime(start.year + 1, start.month, start.day));
}
2026-02-06 09:00:00.000
2026-01-29 23:00:00.000
2026-03-02 00:00:00.000
2027-01-30 00:00:00.000
Look at the third line. There is no 30 February, so Dart rolls over into March. Out-of-range values always overflow like this, which gives a neat trick: day 0 of a month is the last day of the month before.
void main() {
final lastDayOfFeb = DateTime(2028, 3, 0);
print(lastDayOfFeb.day); // 2028 is a leap year
}
29
Difference between two dates #
void main() {
final from = DateTime.utc(2026, 10, 10);
final exam = DateTime.utc(2026, 12, 1, 9, 30);
final remaining = exam.difference(from);
print(remaining.inDays);
print(remaining.inHours);
print('${remaining.inDays} days and ${remaining.inHours % 24} hours');
}
52
1257
52 days and 9 hours
Comparing #
void main() {
final a = DateTime(2026, 5, 1);
final b = DateTime(2026, 8, 1);
print(a.isBefore(b));
print(a.isAfter(b));
print(a.isAtSameMomentAs(DateTime(2026, 5, 1)));
print(a.compareTo(b)); // negative: a is earlier
final dates = [b, a, DateTime(2025, 12, 25)]..sort();
print(dates.first.year);
}
true
false
true
-1
2025
To test whether two moments fall on the same calendar day, compare year, month and day.
Local time and UTC #
Every DateTime is either in the device’s local time zone or in UTC. Store and send times in UTC. Convert to local only when showing them to a person.
void main() {
final utc = DateTime.utc(2026, 10, 10, 12, 0);
final local = utc.toLocal();
print(utc.isUtc);
print(utc.toIso8601String()); // the Z means UTC
print(local.isUtc);
print(local.timeZoneName.isNotEmpty);
print(utc.isAtSameMomentAs(local)); // the same instant, shown differently
}
true
2026-10-10T12:00:00.000Z
false
true
true
toIso8601String() is the format to use in JSON and databases, and DateTime.parse reads it back.
Timestamps #
void main() {
final moment = DateTime.utc(2026, 1, 1);
final millis = moment.millisecondsSinceEpoch;
print(millis);
print(DateTime.fromMillisecondsSinceEpoch(millis, isUtc: true));
}
1767225600000
2026-01-01 00:00:00.000Z
Formatting for people #
By hand, for simple cases:
String two(int n) => n.toString().padLeft(2, '0');
String formatDate(DateTime d) => '${two(d.day)}/${two(d.month)}/${d.year}';
String formatTime(DateTime d) => '${two(d.hour)}:${two(d.minute)}';
void main() {
final d = DateTime(2026, 3, 7, 9, 5);
print(formatDate(d));
print(formatTime(d));
}
07/03/2026
09:05
For month names, weekdays and other languages, use the intl package.
import 'package:intl/intl.dart';
void main() {
final d = DateTime(2026, 10, 10, 18, 45);
print(DateFormat('d MMMM yyyy').format(d));
print(DateFormat('EEE, MMM d').format(d));
print(DateFormat('hh:mm a').format(d));
print(DateFormat.yMMMd().format(d));
}
10 October 2026
Sat, Oct 10
06:45 PM
Oct 10, 2026
Measuring how long code takes #
Use Stopwatch, not DateTime.now(), for timing.
void main() {
final watch = Stopwatch()..start();
var sum = 0;
for (var i = 0; i < 10000000; i++) {
sum += i;
}
watch.stop();
print('Sum $sum computed in ${watch.elapsedMilliseconds} ms');
}
Try it yourself #
Write int ageOn(DateTime birthDate, DateTime today) that returns a person’s age in whole years, taking into account whether their birthday has happened yet this year. Then write a function that returns how many days remain until the next New Year.