formatRelativeTime function

String formatRelativeTime(
  1. DateTime date, {
  2. RelativeTimeStyle style = RelativeTimeStyle.narrow,
  3. DateTime? now,
})

Format a date as a relative time string.

Implementation

String formatRelativeTime(
  DateTime date, {
  RelativeTimeStyle style = RelativeTimeStyle.narrow,
  DateTime? now,
}) {
  final reference = now ?? DateTime.now();
  final diffInMs =
      date.millisecondsSinceEpoch - reference.millisecondsSinceEpoch;
  final diffInSeconds = diffInMs ~/ 1000; // truncate toward zero

  final intervals = <({String unit, int seconds, String shortUnit})>[
    (unit: 'year', seconds: 31536000, shortUnit: 'y'),
    (unit: 'month', seconds: 2592000, shortUnit: 'mo'),
    (unit: 'week', seconds: 604800, shortUnit: 'w'),
    (unit: 'day', seconds: 86400, shortUnit: 'd'),
    (unit: 'hour', seconds: 3600, shortUnit: 'h'),
    (unit: 'minute', seconds: 60, shortUnit: 'm'),
    (unit: 'second', seconds: 1, shortUnit: 's'),
  ];

  for (final interval in intervals) {
    if (diffInSeconds.abs() >= interval.seconds) {
      final value = diffInSeconds ~/ interval.seconds;
      if (style == RelativeTimeStyle.narrow) {
        return diffInSeconds < 0
            ? '${value.abs()}${interval.shortUnit} ago'
            : 'in $value${interval.shortUnit}';
      }
      // Long/short style
      final absValue = value.abs();
      final unitLabel = absValue == 1 ? interval.unit : '${interval.unit}s';
      return diffInSeconds < 0
          ? '$absValue $unitLabel ago'
          : 'in $absValue $unitLabel';
    }
  }

  if (style == RelativeTimeStyle.narrow) {
    return diffInSeconds <= 0 ? '0s ago' : 'in 0s';
  }
  return diffInSeconds <= 0 ? '0 seconds ago' : 'in 0 seconds';
}