On this page23 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. What Is a Duration?
- 2. Reading a Duration
- 3. Duration Arithmetic
- 4. Moving a Date with add and subtract
- 5. The Gap Between Two Dates
- 6. Days Until an Event
- 7. Calculating Age
- 8. The Daylight Saving Trap
- 9. Formatting a Duration as h:mm:ss
- 10. Stopwatch Gives a Duration
- 11. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 111 — Duration & Time Calculations
| Category | 18 — Files, JSON & Core Utilities |
| Lecture | 111 of 140 |
| Estimated video length | 8 min |
| Target | Dart 3.12.2 |
| Level | Intermediate |
A
DateTimesays when something happens, but not how long it lasts or how far away it is. ADurationmeasures the gap — and lets you add it, compare it, and print it.
Contents
Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways
Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.
Prerequisites
Students should already understand, from Lectures 001–110:
- integer division
~/, remainder%, andpadLeft(Lectures 008, 017) Future.delayed,Duration(seconds: …)andStopwatch(Lectures 087, 091)- creating dates with
DateTime(…)andDateTime.utc(…), and readingyear,month,day(Lecture 110)
Connection With Previous Lectures
In Lecture 110 we created exact moments:
void main() {
var examDay = DateTime.utc(2026, 12, 20);
print(examDay);
}2026-12-20 00:00:00.000ZNow Sara asks: how many days until the exam? What date is 30 days after today? How old is
Ali? Each question is about the distance between two moments, and a DateTime alone
cannot answer it.
Learning Objectives
By the end of this lecture you will be able to:
- Create a
Durationfrom days, hours, minutes and seconds - Read a duration with
inDays,inHours,inMinutesandinSeconds - Explain why those properties cut off the remainder
- Add, subtract, multiply and compare durations
- Move a date with
addandsubtract, and measure a gap withdifference - Calculate days until an event and a person's age
- Avoid the daylight saving trap when adding calendar days
- Format a duration as
h:mm:ss
1. What Is a Duration?
A Duration is a length of time with no date attached: "90 minutes", not "Tuesday at
9".
Analogy — a
DateTimeis a spot on a ruler; aDurationis the distance between two spots. "2 cm" means the same wherever you measure it.
Every parameter is named and optional, and they add up:
void main() {
var lecture = Duration(hours: 1, minutes: 30);
var trip = Duration(days: 2, hours: 5);
print(lecture);
print(trip);
}1:30:00.000000
53:00:00.000000print shows hours, minutes, seconds and microseconds. Days are turned into hours: 2 days
and 5 hours is 53 hours.
2. Reading a Duration
The in… properties give the whole length in one unit, as an int:
void main() {
var movie = Duration(minutes: 150);
print(movie.inHours);
print(movie.inMinutes);
print(movie.inSeconds);
}2
150
9000150 minutes is 2.5 hours, yet inHours says 2. These properties truncate: they drop
the part that does not make a full unit, exactly like ~/. They never round up.
void main() {
var almostTwoDays = Duration(hours: 47, minutes: 59);
print(almostTwoDays.inDays);
}13. Duration Arithmetic
Durations work with +, -, * and the comparison operators:
void main() {
var morning = Duration(hours: 2, minutes: 15);
var evening = Duration(hours: 1, minutes: 50);
var total = morning + evening;
print(total);
print(morning - evening);
print(evening * 3);
print(total > Duration(hours: 4));
}4:05:00.000000
0:25:00.000000
5:30:00.000000
trueSubtracting a longer duration gives a negative one. isNegative detects it, and abs()
removes the sign:
void main() {
var gap = Duration(minutes: 10) - Duration(minutes: 25);
print(gap);
print(gap.isNegative);
print(gap.abs());
}-0:15:00.000000
true
0:15:00.0000004. Moving a Date with add and subtract
A DateTime plus a Duration is a new DateTime. The original date never changes:
void main() {
var orderTime = DateTime.utc(2026, 10, 17, 9, 0);
var delivery = orderTime.add(Duration(hours: 50));
var reminder = orderTime.subtract(Duration(minutes: 30));
print(delivery);
print(reminder);
print(orderTime);
}2026-10-19 11:00:00.000Z
2026-10-17 08:30:00.000Z
2026-10-17 09:00:00.000Z50 hours after 9:00 on the 17th is 11:00 on the 19th — Dart handles the days for you.
5. The Gap Between Two Dates
a.difference(b) returns the Duration from b to a:
void main() {
var start = DateTime.utc(2026, 10, 17, 9, 0);
var end = DateTime.utc(2026, 10, 17, 17, 45);
var worked = end.difference(start);
print(worked);
print(worked.inMinutes);
print(start.difference(end));
}8:45:00.000000
525
-8:45:00.000000Read it as "end minus start". Swap them and the result is negative.
6. Days Until an Event
Combine difference with inDays:
void main() {
var today = DateTime.utc(2026, 10, 17);
var exam = DateTime.utc(2026, 12, 20);
var daysLeft = exam.difference(today).inDays;
print('$daysLeft days until the exam');
}64 days until the examIn a real app, today comes from DateTime.now(). Strip the time first —
DateTime.utc(now.year, now.month, now.day) — otherwise 14:00 today to midnight on exam day
is 63 days and 10 hours, and inDays truncates it to 63.
7. Calculating Age
Age is not difference(...).inDays ~/ 365 — leap years make that wrong around
birthdays. Count calendar years instead, then subtract one if this year's birthday has not
happened yet:
int ageOn(DateTime birth, DateTime today) {
var age = today.year - birth.year;
var hadBirthday =
today.month > birth.month ||
(today.month == birth.month && today.day >= birth.day);
if (!hadBirthday) age--;
return age;
}
void main() {
var ali = DateTime.utc(2004, 12, 5);
var sara = DateTime.utc(2006, 3, 14);
var today = DateTime.utc(2026, 10, 17);
print('Ali: ${ageOn(ali, today)}');
print('Sara: ${ageOn(sara, today)}');
}Ali: 21
Sara: 202026 − 2004 is 22, but Ali's birthday in December has not arrived, so he is 21.
8. The Daylight Saving Trap
Duration(days: 1) means exactly 24 hours. In countries with daylight saving time, a
local calendar day is sometimes 23 or 25 hours long. On a computer set to New York time,
clocks go back one hour on 1 November 2026:
void main() {
var day = DateTime(2026, 11, 1);
print(day.add(Duration(days: 1)));
print(DateTime(day.year, day.month, day.day + 1));
}2026-11-01 23:00:00.000
2026-11-02 00:00:00.000Adding 24 hours landed on the same date. The second line asks for "the next calendar
day" directly, and Dart gets it right. Your output depends on your computer's time zone —
in Pakistan, for example, both lines print 2026-11-02, because there is no daylight saving.
The constructor also rolls over months and years for you, so d + 1 is always safe:
void main() {
print(DateTime.utc(2026, 1, 31 + 1));
print(DateTime.utc(2026, 12, 31 + 1));
}2026-02-01 00:00:00.000Z
2027-01-01 00:00:00.000ZRule: for calendar days, use
DateTime(y, m, d + n). For exact lengths of time (hours, minutes, a timer), useadd(Duration(...)). UTC dates never shift, which is why this lecture counts days withDateTime.utc.
Time zones and local time were introduced in Lecture 110.
9. Formatting a Duration as h:mm:ss
print adds microseconds nobody wants. Build the text from whole units and the remainder
%:
String formatDuration(Duration d) {
var hours = d.inHours;
var minutes = (d.inMinutes % 60).toString().padLeft(2, '0');
var seconds = (d.inSeconds % 60).toString().padLeft(2, '0');
return '$hours:$minutes:$seconds';
}
void main() {
print(formatDuration(Duration(seconds: 3725)));
print(formatDuration(Duration(minutes: 7, seconds: 5)));
}1:02:05
0:07:05inMinutes of 3725 seconds is 62; % 60 keeps the 2 that does not fit in a full hour.
padLeft turns 2 into 02.
10. Stopwatch Gives a Duration
In Lecture 091 we read stopwatch.elapsedMilliseconds. The elapsed property returns a
full Duration, so everything in this lecture works on it:
void main() async {
var stopwatch = Stopwatch()..start();
await Future.delayed(Duration(milliseconds: 1500));
stopwatch.stop();
var elapsed = stopwatch.elapsed;
print(elapsed.inSeconds);
print(elapsed > Duration(seconds: 1));
}1
trueelapsed is about 1.5 seconds, and inSeconds truncates it to 1.
11. A Real-World Example
Zayan logs his study sessions. Each has a start and an end; the program totals them and checks the weekly goal:
String formatDuration(Duration d) {
var minutes = (d.inMinutes % 60).toString().padLeft(2, '0');
var seconds = (d.inSeconds % 60).toString().padLeft(2, '0');
return '${d.inHours}:$minutes:$seconds';
}
void main() {
var sessions = [
(DateTime.utc(2026, 10, 12, 16, 0), DateTime.utc(2026, 10, 12, 17, 20)),
(DateTime.utc(2026, 10, 14, 18, 30), DateTime.utc(2026, 10, 14, 19, 15)),
(DateTime.utc(2026, 10, 16, 15, 10), DateTime.utc(2026, 10, 16, 17, 0)),
];
var goal = Duration(hours: 4);
var total = Duration.zero;
for (var (start, end) in sessions) {
total += end.difference(start);
}
print('Studied: ${formatDuration(total)}');
if (total >= goal) {
print('Goal reached!');
} else {
print('Still to go: ${formatDuration(goal - total)}');
}
}Studied: 3:55:00
Still to go: 0:05:00Duration.zero is an empty starting total, difference measures each session, += adds
them, and comparison and subtraction decide the message.
Code Examples
Example 1 — Creating Durations
void main() {
print(Duration(minutes: 45));
print(Duration(hours: 2, seconds: 30));
print(Duration(milliseconds: 1500));
}0:45:00.000000
2:00:30.000000
0:00:01.500000Example 2 — Truncating Properties
void main() {
var d = Duration(hours: 3, minutes: 59);
print(d.inHours);
print(d.inMinutes);
}3
239Example 3 — Adding Durations
void main() {
var cooking = Duration(minutes: 40);
var baking = Duration(minutes: 35);
print(cooking + baking);
}1:15:00.000000Example 4 — Comparing Durations
void main() {
var aliRun = Duration(minutes: 24, seconds: 10);
var saraRun = Duration(minutes: 23, seconds: 55);
print(saraRun < aliRun ? 'Sara wins' : 'Ali wins');
}Sara winsExample 5 — A Date 30 Days Later
void main() {
var issued = DateTime.utc(2026, 10, 17);
var due = issued.add(Duration(days: 30));
print(due);
}2026-11-16 00:00:00.000ZExample 6 — Next Month, the Safe Way
void main() {
var payday = DateTime.utc(2026, 11, 25);
var next = DateTime.utc(payday.year, payday.month + 2, payday.day);
print(next);
}2027-01-25 00:00:00.000ZMonth 13 rolls over into January of the next year.
Example 7 — Student Exam Time
void main() {
var start = DateTime.utc(2026, 10, 17, 9, 0);
var handedIn = DateTime.utc(2026, 10, 17, 11, 25);
var limit = Duration(hours: 2, minutes: 30);
var used = handedIn.difference(start);
print('Used ${used.inMinutes} of ${limit.inMinutes} minutes');
print(used <= limit ? 'On time' : 'Late');
}Used 145 of 150 minutes
On timeExample 8 — Shopping Delivery Date
void main() {
var ordered = DateTime.utc(2026, 10, 30);
var shippingDays = 5;
var arrives = DateTime.utc(
ordered.year,
ordered.month,
ordered.day + shippingDays,
);
print('Arrives: ${arrives.day}/${arrives.month}/${arrives.year}');
}Arrives: 4/11/2026Example 9 — Bank Interest Days
void main() {
var deposited = DateTime.utc(2026, 1, 1);
var withdrawn = DateTime.utc(2026, 7, 1);
var days = withdrawn.difference(deposited).inDays;
var balance = 10000.0;
var interest = balance * 0.05 * days / 365;
print('Days: $days');
print('Interest: ${interest.toStringAsFixed(2)}');
}Days: 181
Interest: 247.95Example 10 — Temperature Readings Every 90 Minutes
void main() {
var first = DateTime.utc(2026, 10, 17, 6, 0);
var temps = [18.5, 21.0, 24.5, 26.0];
for (var i = 0; i < temps.length; i++) {
var time = first.add(Duration(minutes: 90) * i);
var minute = time.minute.toString().padLeft(2, '0');
print('${time.hour}:$minute → ${temps[i]}°C');
}
}6:00 → 18.5°C
7:30 → 21.0°C
9:00 → 24.5°C
10:30 → 26.0°CCommon Beginner Mistakes
1. Expecting inHours to round
Duration(minutes: 119).inHours is 1, not 2. The in… properties always truncate.
Use inMinutes (or smaller) when the remainder matters.
2. Passing a decimal to a Duration parameter
void main() {
// var d = Duration(hours: 1.5); // ✗
}Error: The argument type 'double' can't be assigned to the parameter type 'int'.Every parameter is an int. Write Duration(hours: 1, minutes: 30) or
Duration(minutes: 90).
3. Using + on a DateTime
void main() {
var day = DateTime.utc(2026, 10, 17);
// print(day + Duration(days: 1)); // ✗
}Error: The operator '+' isn't defined for the type 'DateTime'.Use day.add(Duration(days: 1)). Only two durations can be added with +.
4. Getting difference backwards
start.difference(end) is negative. Always write the later date first.
5. Adding 24-hour days to local dates
localDate.add(Duration(days: 1)) can land on 23:00 of the same day. For calendar days use
DateTime(y, m, d + 1).
6. Forgetting % 60 when formatting
'${d.inHours}:${d.inMinutes}' prints 1:62 for 62 minutes. The minutes part needs
d.inMinutes % 60.
Best Practices
- Use named units that read naturally:
Duration(minutes: 90), notDuration(seconds: 5400). - Use
add(Duration(...))for exact lengths of time,DateTime(y, m, d + n)for calendar days. - Count days between dates with UTC dates at midnight.
- Calculate age from years, months and days — never by dividing days by 365.
- Write your own
formatDurationinstead of printing raw microseconds to users. - Start totals at
Duration.zero.
Mini Challenge
Sara's train leaves at 22:40 on 17 October 2026 and the trip takes 9 hours 35 minutes.
Print the arrival time and the trip length as h:mm:ss. Use UTC dates.
Your program should print exactly:
Arrives: 2026-10-18 08:15:00.000Z
Trip: 9:35:00Try it yourself before opening the solution.
Show solution
void main() {
var departs = DateTime.utc(2026, 10, 17, 22, 40);
var trip = Duration(hours: 9, minutes: 35);
var arrives = departs.add(trip);
var minutes = (trip.inMinutes % 60).toString().padLeft(2, '0');
var seconds = (trip.inSeconds % 60).toString().padLeft(2, '0');
print('Arrives: $arrives');
print('Trip: ${trip.inHours}:$minutes:$seconds');
}Arrives: 2026-10-18 08:15:00.000Z
Trip: 9:35:00How it works
addmoves the departure forward by exactly 9 h 35 min, crossing midnight.inHoursgives9;inMinutes % 60gives35; seconds are00.
Practice Questions
Work through these in order — they run from beginner to application to challenge.
Beginner
- Create a
Durationof 2 hours 45 minutes and print it. - For
Duration(seconds: 200), printinMinutesandinSeconds. - Add
Duration(minutes: 50)andDuration(minutes: 25)and print the result.
Application
- Print the date 100 days after
DateTime.utc(2026, 10, 17). - Print how many minutes passed between 08:15 and 13:40 on 17 October 2026 (UTC).
- Print how many days are left from 17 October 2026 until 1 January 2027 (UTC).
- Zayan was born on 17 October 2020. Using the
ageOnfunction from section 7, print his age on 16 October 2026 and on 17 October 2026.
Challenge
- Using
DateTime.utc(y, m, d + n), print the date 3 days after 30 December 2026. - Ali ran 5 laps of
Duration(minutes: 1, seconds: 48)each. Print the total ash:mm:ss. - A parking garage charges 100 rupees per started hour. A car parked from 10:05 to
12:20 (UTC, same day). Print the duration in minutes and the fee (
300).
Practice Answers
Question 1 — Solution
void main() {
print(Duration(hours: 2, minutes: 45));
}2:45:00.000000Question 2 — Solution
void main() {
var d = Duration(seconds: 200);
print(d.inMinutes);
print(d.inSeconds);
}3
200Question 3 — Solution
void main() {
print(Duration(minutes: 50) + Duration(minutes: 25));
}1:15:00.000000Question 4 — Solution
void main() {
print(DateTime.utc(2026, 10, 17).add(Duration(days: 100)));
}2027-01-25 00:00:00.000ZQuestion 5 — Solution
void main() {
var start = DateTime.utc(2026, 10, 17, 8, 15);
var end = DateTime.utc(2026, 10, 17, 13, 40);
print(end.difference(start).inMinutes);
}325Question 6 — Solution
void main() {
var today = DateTime.utc(2026, 10, 17);
var newYear = DateTime.utc(2027, 1, 1);
print(newYear.difference(today).inDays);
}76Question 7 — Solution
int ageOn(DateTime birth, DateTime today) {
var age = today.year - birth.year;
var hadBirthday =
today.month > birth.month ||
(today.month == birth.month && today.day >= birth.day);
if (!hadBirthday) age--;
return age;
}
void main() {
var zayan = DateTime.utc(2020, 10, 17);
print(ageOn(zayan, DateTime.utc(2026, 10, 16)));
print(ageOn(zayan, DateTime.utc(2026, 10, 17)));
}5
6Question 8 — Solution
void main() {
var day = DateTime.utc(2026, 12, 30);
print(DateTime.utc(day.year, day.month, day.day + 3));
}2027-01-02 00:00:00.000ZQuestion 9 — Solution
void main() {
var total = Duration(minutes: 1, seconds: 48) * 5;
var minutes = (total.inMinutes % 60).toString().padLeft(2, '0');
var seconds = (total.inSeconds % 60).toString().padLeft(2, '0');
print('${total.inHours}:$minutes:$seconds');
}0:09:00Question 10 — Solution
void main() {
var parked = DateTime.utc(2026, 10, 17, 10, 5);
var left = DateTime.utc(2026, 10, 17, 12, 20);
var minutes = left.difference(parked).inMinutes;
var hours = (minutes + 59) ~/ 60;
print('Parked: $minutes minutes');
print('Fee: ${hours * 100}');
}Parked: 135 minutes
Fee: 300inHours would give 2 — truncated. Adding 59 minutes before ~/ 60 counts any started
hour as a full one.
Quick Revision
- What is the difference between a
DateTimeand aDuration? - What does
Duration(minutes: 150).inHoursreturn, and why? - Which operator subtracts two durations? Which method moves a date?
- What does
a.difference(b)return whenais earlier thanb? - Why is
days ~/ 365a poor way to calculate age? - Why can
add(Duration(days: 1))land on the same date? - Which two tools turn
62minutes into the02in1:02:05?
Key Takeaways
- A
Durationis a length of time; build it from namedintparameters. inDays,inHours,inMinutes,inSecondsgive whole units and truncate.- Durations support
+,-,*, comparisons,isNegativeandabs(). addandsubtractmove aDateTime;later.difference(earlier)measures the gap.- Count days with UTC dates at midnight; calculate age from the calendar, not from days.
Duration(days: 1)is 24 hours — useDateTime(y, m, d + 1)for the next calendar day.- Format with
inHours,% 60andpadLeft(2, '0'). Stopwatch.elapsedis aDurationtoo.
What's Next?
Lecture 112 — URI & Core Utilities. Dates and durations are only one part of
dart:core. Apps also handle web addresses, query parameters and encoded text. Next we will
build and take apart URLs with Uri and meet a few more everyday core utilities.