glp-companion/lib/core/utils/date_time_utils.dart

38 lines
1.4 KiB
Dart

// Shared, framework-free date helpers.
//
// The project intentionally avoids `intl` to keep core utilities usable from
// pure Dart domain code and tests; these formatters cover the app's display
// needs with explicit, stable output.
const List<String> _monthNames = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
];
/// Formats [time] as e.g. `Oct 16, 2026 · 2:05 PM`.
String formatDateTime(DateTime time) {
final local = time.toLocal();
final hour12 = local.hour % 12 == 0 ? 12 : local.hour % 12;
final minute = local.minute.toString().padLeft(2, '0');
final period = local.hour < 12 ? 'AM' : 'PM';
return '${_monthNames[local.month - 1]} ${local.day}, ${local.year}'
' · $hour12:$minute $period';
}
/// Formats a coarse elapsed time relative to [now], e.g. `never`, `3 hours
/// ago`, `5 days ago`.
String formatRelativeTime(DateTime time, {DateTime? now}) {
final reference = now ?? DateTime.now();
final elapsed = reference.difference(time);
if (elapsed.isNegative) {
final ahead = time.difference(reference);
if (ahead.inDays >= 1) return 'in ${ahead.inDays} day(s)';
if (ahead.inHours >= 1) return 'in ${ahead.inHours} hour(s)';
return 'in a moment';
}
if (elapsed.inMinutes < 1) return 'just now';
if (elapsed.inHours < 1) return '${elapsed.inMinutes} minute(s) ago';
if (elapsed.inDays < 1) return '${elapsed.inHours} hour(s) ago';
return '${elapsed.inDays} day(s) ago';
}