Files
fanuzu/app/lib/core/ui/relative_time.dart

40 lines
1.8 KiB
Dart

/// 상대 시각 표기.
///
/// 명세 `523:18399`(캠페인 카드)가 규칙 전부를 정했다 —
/// *~1분 : 방금 전 · ~1시간 : n분 전 · ~24시간 : n시간 전 · ~7일 : n일 전 ·*
/// *이후 : 날짜(2026.01.01)*
///
/// 같은 규칙이 `548:19137`(게시글 카드) · `554:22611` 에도 사본 주석으로 있다. 사본 표본의
/// 「1달 전」은 이 규칙과 어긋나는 표본 문구라 따르지 않는다.
///
/// 화면마다 따로 만들면 「3일 전」과 「2026.01.01」이 같은 목록에서 섞인다.
/// 한 곳에 두고 전 화면이 쓴다.
library;
import '../i18n/app_locale.dart';
String relativeTime(DateTime at, {DateTime? now}) {
final d = (now ?? DateTime.now()).difference(at);
if (d.inMinutes < 1) return appL10n.timeJustNow;
if (d.inMinutes < 60) return appL10n.timeMinutesAgo('${d.inMinutes}');
if (d.inHours < 24) return appL10n.timeHoursAgo('${d.inHours}');
if (d.inDays < 7) return appL10n.timeDaysAgo('${d.inDays}');
// 일주일이 넘으면 「37일 전」보다 날짜가 읽기 쉽다.
final y = at.year.toString().padLeft(4, '0');
final m = at.month.toString().padLeft(2, '0');
final day = at.day.toString().padLeft(2, '0');
return '$y.$m.$day';
}
/// 반응 수치 표기. 명세 — *반응 수치는 K 단위 활용*.
///
/// POP 은 천 단위 구분자를 쓰므로([formatPop]) 다른 함수다. 좋아요 1,200 은
/// 「1.2K」로 줄이는 편이 카드 안에서 읽히지만, POP 잔액을 줄이면 금액이 흐려진다.
String formatReaction(int value) {
if (value < 1000) return '$value';
final k = value / 1000;
// 시안은 「3K」 「1K」 처럼 소수 0 을 떼어 쓴다.
final text = k >= 10 ? '${k.round()}' : k.toStringAsFixed(1);
return '${text.endsWith('.0') ? text.substring(0, text.length - 2) : text}K';
}