Files
doormilxpress_astryx/src/lib/doormileTimestamp.js

34 lines
1.5 KiB
JavaScript

import dayjs from 'dayjs';
/**
* Doormile timestamps are IST (Asia/Kolkata) wall-clock stored in Postgres
* `timestamp without time zone` columns. Some responses come back with a
* trailing Z/offset anyway — a known Go+pgx footgun where a naive DB timestamp
* loads into `time.Time` under the UTC location and gets marshalled with a
* false "Z" suffix. dayjs reads a Z-suffixed string as a real UTC instant and
* converts it to the browser's local time, adding a spurious +5:30 on top of
* digits that were already correct IST.
*
* Stripping any trailing zone marker before parsing makes both cases — truly
* naive, or naive-with-false-Z — render and bucket identically as the raw
* wall-clock digits. Every page that displays or buckets a Doormile timestamp
* must go through here, or two pages will disagree about which day a row is on.
*/
export const parseDoormileTimestamp = (raw) => {
if (!raw) return dayjs(null);
const stripped = String(raw).replace(/(Z|[+-]\d{2}:?\d{2})$/, '');
return dayjs(stripped);
};
/** `raw` rendered in `format`, or `fallback` when the timestamp is unusable. */
export const formatDoormileTimestamp = (raw, format = 'DD MMM YYYY, hh:mm A', fallback = '—') => {
const parsed = parseDoormileTimestamp(raw);
return parsed.isValid() ? parsed.format(format) : fallback;
};
/** The calendar day (`YYYY-MM-DD`) a Doormile timestamp falls on. */
export const doormileDay = (raw) => {
const parsed = parseDoormileTimestamp(raw);
return parsed.isValid() ? parsed.format('YYYY-MM-DD') : undefined;
};