53 lines
1.9 KiB
TypeScript
53 lines
1.9 KiB
TypeScript
/**
|
|
* Hitung Ayam 0-based day index for the Dashboard daily report.
|
|
* Day 0 = cycle start (DOC in). Feed/weight pages are 1-based and must be
|
|
* converted before joining. Local calendar dates only — never toISOString().
|
|
*/
|
|
|
|
export function parseLocalDateString(value: string): Date {
|
|
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
const year = Number(value.slice(0, 4));
|
|
const month = Number(value.slice(5, 7));
|
|
const day = Number(value.slice(8, 10));
|
|
return new Date(year, month - 1, day);
|
|
}
|
|
const parsed = new Date(value);
|
|
parsed.setHours(0, 0, 0, 0);
|
|
return parsed;
|
|
}
|
|
|
|
const toLocalMidnight = (value: Date | string): Date => {
|
|
if (typeof value === 'string') return parseLocalDateString(value);
|
|
const date = new Date(value);
|
|
date.setHours(0, 0, 0, 0);
|
|
return date;
|
|
};
|
|
|
|
/** YYYY-MM-DD from local parts. Do not use toISOString() (WIB off-by-one). */
|
|
export function formatLocalDate(date: Date): string {
|
|
const year = date.getFullYear();
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
return `${year}-${month}-${day}`;
|
|
}
|
|
|
|
/** Calendar date of a Hitung Ayam day. Day 0 is the cycle start. */
|
|
export function reportDayToDate(cycleStart: Date | string, day: number): Date {
|
|
const start = toLocalMidnight(cycleStart);
|
|
start.setDate(start.getDate() + day);
|
|
return start;
|
|
}
|
|
|
|
/** Hitung Ayam day index for a calendar date. Cycle start → 0. */
|
|
export function dateToReportDay(cycleStart: Date | string, date: Date | string): number {
|
|
const start = toLocalMidnight(cycleStart);
|
|
const target = toLocalMidnight(date);
|
|
const diffMs = target.getTime() - start.getTime();
|
|
return Math.round(diffMs / (1000 * 60 * 60 * 24));
|
|
}
|
|
|
|
/** Feed/weight pages label cycle start as day 1; report labels it day 0. */
|
|
export function feedOrWeightDayToReportDay(oneBasedDay: number): number {
|
|
return oneBasedDay - 1;
|
|
}
|