60 lines
1.7 KiB
Dart
60 lines
1.7 KiB
Dart
/// Universal time formatting helper to format relative timestamps cleanly for UI displays.
|
|
class TimeUtils {
|
|
/// Converts ISO-8601 or DateTime inputs to localized, readable relative time strings.
|
|
///
|
|
/// Examples:
|
|
/// - Under 60 minutes: "Vor 15 Min.", "Vor 42 Min."
|
|
/// - 1 hour or more: "Vor 1 Std.", "Vor 1 Std. 15 Min.", "Vor 3 Std. 45 Min."
|
|
/// - Yesterday: "Gestern"
|
|
/// - Older: "22.07.2026"
|
|
static String formatRelativeTime(dynamic rawDate) {
|
|
if (rawDate == null) return '';
|
|
final str = rawDate.toString().trim();
|
|
if (str.isEmpty) return '';
|
|
|
|
DateTime dt;
|
|
try {
|
|
dt = DateTime.parse(str).toLocal();
|
|
} catch (_) {
|
|
// Return raw string if already formatted or non-date string
|
|
return str;
|
|
}
|
|
|
|
final now = DateTime.now();
|
|
final rawDiff = now.difference(dt);
|
|
|
|
// If the timestamp is in the future (e.g. slight clock skew or scraper timezone issues), cap it to 0
|
|
final duration = rawDiff.isNegative ? Duration.zero : rawDiff;
|
|
final totalMinutes = duration.inMinutes;
|
|
|
|
if (totalMinutes < 1) {
|
|
return 'Vor 1 Min.';
|
|
}
|
|
|
|
if (totalMinutes < 60) {
|
|
return 'Vor $totalMinutes Min.';
|
|
}
|
|
|
|
final hours = duration.inHours;
|
|
if (hours < 24) {
|
|
final remainingMinutes = totalMinutes % 60;
|
|
if (remainingMinutes == 0) {
|
|
return 'Vor $hours Std.';
|
|
} else {
|
|
return 'Vor $hours Std. $remainingMinutes Min.';
|
|
}
|
|
}
|
|
|
|
final days = duration.inDays;
|
|
if (days == 1) {
|
|
return 'Gestern';
|
|
} else if (days < 7) {
|
|
return 'Vor $days Tagen';
|
|
}
|
|
|
|
final dayStr = dt.day.toString().padLeft(2, '0');
|
|
final monthStr = dt.month.toString().padLeft(2, '0');
|
|
return '$dayStr.$monthStr.${dt.year}';
|
|
}
|
|
}
|