timeAgo static method
- DateTime date, {
- DateTime? now,
- bool assumeUtc = false,
- int justNowSeconds = 10,
- TimeAgoLabels? labels,
A relative "time ago" phrase covering seconds → years.
Robust by design:
• Never emits a negative count — a future or clock-skewed date
(e.g. a just-posted row whose server time is slightly ahead) clamps to
the labels' "just now" instead of -3s ago.
• Full range — seconds, minutes, hours, days, weeks, months, years.
• Localisable — pass labels (TimeAgoLabels.en() / .enShort() /
.ar(), or your own) so plural/dual rules stay out of the framework.
Parameters:
• now — reference instant; inject in tests for determinism (defaults to
DateTime.now()).
• assumeUtc — reinterpret a naive (offset-less) date as UTC before
comparing. Use when the value came from a server/DB that stores UTC;
a value already flagged UTC is left as-is.
• justNowSeconds — anything more recent than this reads as "just now".
Implementation
static String timeAgo(
DateTime date, {
DateTime? now,
bool assumeUtc = false,
int justNowSeconds = 10,
TimeAgoLabels? labels,
}) {
final l = labels ?? TimeAgoLabels.enShort();
var d = date;
if (assumeUtc && !d.isUtc) {
d = DateTime.utc(d.year, d.month, d.day, d.hour, d.minute, d.second,
d.millisecond, d.microsecond);
}
var diff = (now ?? DateTime.now()).difference(d);
if (diff.isNegative) diff = Duration.zero; // clock skew / future → "just now"
final s = diff.inSeconds;
if (s < justNowSeconds) return l.justNow;
if (s < 60) return l.format(s, TimeUnit.second);
final m = diff.inMinutes;
if (m < 60) return l.format(m, TimeUnit.minute);
final h = diff.inHours;
if (h < 24) return l.format(h, TimeUnit.hour);
final days = diff.inDays;
if (days < 7) return l.format(days, TimeUnit.day);
if (days < 30) return l.format(days ~/ 7, TimeUnit.week);
if (days < 365) return l.format(days ~/ 30, TimeUnit.month);
return l.format(days ~/ 365, TimeUnit.year);
}