/** Bantu perbandingan tanggal trip (hari kalender UTC). */ /** Parse `YYYY-MM-DD` sebagai awal hari UTC (hindari ambiguitas `new Date(string)` di berbagai TZ). */ export function utcDayStartFromYmd(ymd: string): Date { const parts = ymd.split("-").map(Number); const y = parts[0]; const m = parts[1]; const d = parts[2]; if (!y || !m || !d) { return utcStartOfDay(new Date()); } return new Date(Date.UTC(y, m - 1, d, 0, 0, 0, 0)); } /** Akhir hari UTC untuk `YYYY-MM-DD`. */ export function utcDayEndFromYmd(ymd: string): Date { const parts = ymd.split("-").map(Number); const y = parts[0]; const m = parts[1]; const d = parts[2]; if (!y || !m || !d) { return utcStartOfDay(new Date()); } return new Date(Date.UTC(y, m - 1, d, 23, 59, 59, 999)); } export function maxUtcDate(a: Date, b: Date): Date { return a.getTime() >= b.getTime() ? a : b; } /** * Tanggal dari DatePicker = hari kalender **lokal** browser. * Encode `YYYY-MM-DD` dengan `getFullYear/getMonth/getDate` (bukan `toISOString()`) * supaya tidak bergeser ke hari UTC lain (mis. WIB malam → UTC hari sebelumnya). */ export function formatLocalCalendarYmd(d: Date): string { const y = d.getFullYear(); const m = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); return `${y}-${m}-${day}`; } /** * Simpan `trip.date` / `trip.endDate`: string `YYYY-MM-DD` diartikan sebagai * **hari kalender UTC** yang sama (selaras dengan filter Open Trip). */ export function tripStoredInstantFromYmd(ymd: string): Date { return utcDayStartFromYmd(ymd.trim().slice(0, 10)); } export function utcStartOfDay(d: Date): Date { return new Date( Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()) ); } /** true jika hari berangkat trip sudah lewat dibanding hari ini (UTC). */ export function isTripDepartureDayPast(departureDate: Date): boolean { const today = utcStartOfDay(new Date()); const dep = utcStartOfDay(departureDate); return dep.getTime() < today.getTime(); } /** * true jika sudah lewat akhir hari terakhir trip (tanggal pulang atau tanggal berangkat). * Dipakai untuk membuka fitur ulasan. */ export function isPastTripLastDayForReview( tripDate: Date, tripEndDate: Date | null ): boolean { const last = tripEndDate ?? tripDate; const endMs = Date.UTC( last.getUTCFullYear(), last.getUTCMonth(), last.getUTCDate(), 23, 59, 59, 999 ); return Date.now() > endMs; }