111 lines
3.2 KiB
TypeScript
111 lines
3.2 KiB
TypeScript
/** 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;
|
|
}
|
|
|
|
/**
|
|
* Tampilkan tanggal trip untuk UI: pakai **kalender UTC** (sama dengan
|
|
* `tripStoredInstantFromYmd` & filter Open Trip), supaya tidak bergeser
|
|
* karena timezone runtime (server vs browser).
|
|
*/
|
|
export function formatTripCalendarDateLong(
|
|
d: Date | string,
|
|
locale = "id-ID"
|
|
): string {
|
|
const date = typeof d === "string" ? new Date(d) : d;
|
|
return new Intl.DateTimeFormat(locale, {
|
|
dateStyle: "long",
|
|
timeZone: "UTC",
|
|
}).format(date);
|
|
}
|
|
|
|
export function formatTripCalendarDateRangeLong(
|
|
start: Date | string,
|
|
end?: Date | string | null,
|
|
locale = "id-ID"
|
|
): string {
|
|
const startStr = formatTripCalendarDateLong(start, locale);
|
|
if (!end) return startStr;
|
|
const endStr = formatTripCalendarDateLong(end, locale);
|
|
return `${startStr} — ${endStr}`;
|
|
}
|