formatTimeAgo function
This function calculates the time difference between the provided dateTime and the current moment (DateTime.now())
and returns a string in an approximate, user-friendly format.
Behavior for Past Times (ago):
- Less than 1 second: "just now"
- 1-59 seconds: "1 minute ago" (per specified requirement)
- 1-59 minutes: "X minutes ago"
- 1-23 hours: "X hours ago"
- 1-6 days: "X days ago"
- 1-4 weeks (approx): "X weeks ago"
- 1-11 months (approx): "X months ago"
- 1+ years (approx): "X years ago"
Behavior for Future Times (from now):
- Less than 1 second: "just now"
- 1-59 seconds: "in 1 minute"
- 1-59 minutes: "in X minutes"
- 1-23 hours: "in X hours"
- 1-29 days: "in X days"
- 1-11 months (approx): "in X months"
- 1+ years (approx): "in X years"
Handles singular/plural forms for all units. Approximations for weeks, months, and years are based on fixed day counts (7 days/week, 30 days/month, 365 days/year).
@param dateTime The specific point in time to format. @return A string representing the relative time difference.
Implementation
String formatTimeAgo(DateTime dateTime) {
final now = DateTime.now();
final diff = now.difference(dateTime);
/// chopLastCharacter
String chopLast(String text) =>
text.isEmpty ? '' : text.substring(0, text.length - 1);
/// format Future Times
String fmtFutureTimes(int n, TimeUnit unit) => switch (unit) {
TimeUnit.justnow => TimeUnit.justnow.name,
TimeUnit.unknown => TimeUnit.unknown.name,
_ => 'in $n ${(n > 1) ? unit.name : chopLast(unit.name)}'
};
/// format Future Times
String fmtPastTimes(int n, TimeUnit unit) => switch (unit) {
TimeUnit.justnow => TimeUnit.justnow.name,
TimeUnit.unknown => TimeUnit.unknown.name,
_ => '$n ${(n > 1) ? unit.name : chopLast(unit.name)} ago'
};
if (diff.isNegative) {
// Handling future times
final fDiff = dateTime.difference(now);
if (fDiff.inSeconds == 0) {
return fmtFutureTimes(0, TimeUnit.justnow);
} else if (fDiff.inMinutes == 0) {
return fmtFutureTimes(1, TimeUnit.minutes);
} else if (fDiff.inMinutes < 60) {
return fmtFutureTimes(fDiff.inMinutes, TimeUnit.minutes);
} else if (fDiff.inHours < 24) {
return fmtFutureTimes(fDiff.inHours, TimeUnit.hours);
} else if (diff.inDays < 7) {
return fmtFutureTimes(diff.inDays, TimeUnit.days);
} else if (fDiff.inDays < 30) {
int weeks = (diff.inDays / 7).round();
if (weeks == 0) weeks = 1;
return fmtFutureTimes(weeks, TimeUnit.weeks);
} else if (fDiff.inDays < 365) {
int months = (fDiff.inDays / 30).round();
if (months == 0) months = 1;
return fmtFutureTimes(months, TimeUnit.months);
} else {
int years = (fDiff.inDays / 365).round();
if (years == 0) years = 1;
return fmtFutureTimes(years, TimeUnit.years);
}
}
// Handling past times
if (diff.inMinutes == 0) {
return (diff.inSeconds == 0)
? fmtPastTimes(0, TimeUnit.justnow)
: fmtPastTimes(1, TimeUnit.minutes);
} else if (diff.inMinutes < 60) {
return fmtPastTimes(diff.inMinutes, TimeUnit.minutes);
} else if (diff.inHours < 24) {
return fmtPastTimes(diff.inHours, TimeUnit.hours);
} else if (diff.inDays < 7) {
return fmtPastTimes(diff.inDays, TimeUnit.days);
} else if (diff.inDays < 30) {
int weeks = (diff.inDays / 7).round();
if (weeks == 0) weeks = 1;
return fmtPastTimes(weeks, TimeUnit.weeks);
} else if (diff.inDays < 365) {
int months = (diff.inDays / 30).round();
if (months == 0) months = 1;
return fmtPastTimes(months, TimeUnit.months);
} else {
int years = (diff.inDays / 365).round();
if (years == 0) years = 1;
return fmtPastTimes(years, TimeUnit.years);
}
}