flutter_relative_time 0.0.1
flutter_relative_time: ^0.0.1 copied to clipboard
Human-friendly past and future DateTime formatting with localized timeago and calendar labels.
flutter_relative_time #
flutter_relative_time formats DateTime values into short, friendly labels
for product interfaces.
It supports past dates, future dates, calendar-style labels, very recent values,
custom messages, custom locales, and DateTime extensions.
What it can format #
Future dates:
in 2h
tomorrow, 05:03
mañana, 05:03
sexta-feira, 14:30
Past dates:
5m ago
hace 5 min
há 2 horas
yesterday, 18:45
Very recent dates:
just now
soon
ahora
pronto
Basic usage #
import 'package:flutter_relative_time/flutter_relative_time.dart';
final now = DateTime(2026, 8, 2, 12);
final tomorrow = DateTime(2026, 8, 3, 5, 3);
final label = tomorrow.toRelativeCalendar(
languageCode: 'en',
options: RelativeTimeFormatOptions.calendar(
now: now,
clockFormat: RelativeTimeClockFormat.twentyFourHour,
),
);
// tomorrow, 05:03
The extension is available on nullable dates too, so UI code can safely format optional backend values:
final DateTime? deliveredAt = order.deliveredAt;
final label = deliveredAt.toRelativeTime(languageCode: 'es');
If the value is null, the formatter returns the localized unknown label.
Example app #
The package includes a Flutter example app with interactive language and clock format controls:
cd example
flutter run
Future examples #
Use toTimeAgo when the UI needs a compact countdown-style value:
final now = DateTime(2026, 8, 2, 12);
final startsAt = DateTime(2026, 8, 2, 14);
final label = startsAt.toTimeAgo(
languageCode: 'en',
options: RelativeTimeFormatOptions.timeAgo(now: now),
);
// in 2h
Use toRelativeCalendar when the UI needs a date that feels natural in a
schedule, map, booking, event, or opening-hours flow:
final now = DateTime(2026, 8, 2, 12);
final opensAt = DateTime(2026, 8, 3, 10);
final label = opensAt.toRelativeCalendar(
languageCode: 'es',
options: RelativeTimeFormatOptions.calendar(now: now),
);
// mañana, 10:00
Past examples #
final now = DateTime(2026, 8, 2, 12);
final createdAt = DateTime(2026, 8, 2, 11, 55);
final label = createdAt.toTimeAgo(
languageCode: 'es',
options: RelativeTimeFormatOptions.timeAgo(now: now),
);
// hace 5 min
For older values, calendar mode produces a readable date:
final now = DateTime(2026, 8, 2, 12);
final paidAt = DateTime(2026, 7, 28, 18, 45);
final label = paidAt.toRelativeCalendar(
languageCode: 'pt',
options: RelativeTimeFormatOptions.calendar(now: now),
);
// terça-feira, 18:45
Very recent examples #
Values inside justNowThreshold are formatted with a short status label.
final now = DateTime(2026, 8, 2, 12);
final sentAt = DateTime(2026, 8, 2, 11, 59, 50);
final label = sentAt.toTimeAgo(
languageCode: 'en',
options: RelativeTimeFormatOptions.timeAgo(
now: now,
justNowThreshold: Duration(seconds: 30),
),
);
// just now
The same rule works for very near future dates:
final now = DateTime(2026, 8, 2, 12);
final retryAt = DateTime(2026, 8, 2, 12, 0, 10);
final label = retryAt.toTimeAgo(
languageCode: 'en',
options: RelativeTimeFormatOptions.timeAgo(
now: now,
justNowThreshold: Duration(seconds: 30),
),
);
// soon
Formatting modes #
RelativeTimeFormatter.format(value, languageCode: 'es');
RelativeTimeFormatter.timeAgo(value, languageCode: 'pt');
RelativeTimeFormatter.calendar(value, languageCode: 'en');
RelativeTimeFormatMode.smart: nearby values use timeago labels, while farther values use calendar labels.RelativeTimeFormatMode.timeAgo: always returns relative labels such ashace 5 min,in 2h, orhá 3 dias.RelativeTimeFormatMode.calendar: returns labels such astoday, 5:03 AM,tomorrow, 05:03,mañana, 05:03, or12 ago, 10:00.
Clock format #
By default, clockFormat is RelativeTimeClockFormat.auto.
const options = RelativeTimeFormatOptions.calendar(
clockFormat: RelativeTimeClockFormat.auto,
);
auto chooses 12h or 24h using the effective languageCode or locale. You can
also force the format per call:
const twentyFourHour = RelativeTimeFormatOptions.calendar(
clockFormat: RelativeTimeClockFormat.twentyFourHour,
);
const twelveHour = RelativeTimeFormatOptions.calendar(
clockFormat: RelativeTimeClockFormat.twelveHour,
);
When 24h is selected, the hour always uses two digits:
tomorrow, 05:03
mañana, 05:03
Keep business text outside the formatter #
The package should format only the temporal part. Product-specific verbs should stay in the app layer.
final date = nextOpeningAt.toRelativeCalendar(
languageCode: context.locale.languageCode,
);
final text = 'Opens $date';
That keeps product copy flexible for phrases such as Opens, Closes,
Starts, Expires, Scheduled, or any custom business wording.
Custom messages #
Override one or more keys for a single call:
final label = value.toTimeAgo(
languageCode: 'es',
options: const RelativeTimeFormatOptions.timeAgo(
overrides: {
RelativeTimeKeys.justNow: 'ahora mismo',
RelativeTimeKeys.soon: 'en breve',
},
),
);
Custom locales #
You can add a locale without changing the package source:
final label = value.toRelativeCalendar(
languageCode: 'nl',
options: RelativeTimeFormatOptions.calendar(
locales: {
'nl': RelativeTimeLocaleMessages(
languageCode: 'nl',
values: {
RelativeTimeKeys.todayAt: 'vandaag, {time}',
RelativeTimeKeys.tomorrowAt: 'morgen, {time}',
RelativeTimeKeys.yesterdayAt: 'gisteren, {time}',
RelativeTimeKeys.weekdayAt: '{weekday}, {time}',
RelativeTimeKeys.dateAt: '{date}, {time}',
RelativeTimeKeys.unknown: 'onbekend',
},
),
},
),
);
Built-in languages #
- Arabic:
ar - German:
de - English:
en - Spanish:
es - French:
fr - Italian:
it - Portuguese:
pt - Russian:
ru - Chinese:
zh
License #
MIT License.