All files / src/utils/helpers utcToLocalTime.js

100% Statements 18/18
100% Branches 14/14
100% Functions 3/3
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32          26x 26x     26x 1365x 383x 383x 383x         26x 540x 331x 331x         26x 82x 10x 82x    
import { DateTime } from "luxon";
 
// EI-3109 — Canonical date formats. All dates in the app render as MM/DD/YYYY
// (4-digit year), date+time as "MM/DD/YYYY, hh:mm AM/PM". Keep these tokens as the
// single source of truth so every section stays consistent.
const DATE_FORMAT = "MM/dd/yyyy"; // e.g. 03/15/2024
const DATE_TIME_FORMAT = "MM/dd/yyyy, hh:mm a"; // e.g. 03/15/2024, 02:30 PM
 
// Date + time in the viewer's local zone, from a UTC ISO timestamp.
export const utcToLocalTime = (utcDateString) => {
    if (!utcDateString) return "N/A";
    const systemTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
    const dt = DateTime.fromISO(utcDateString, { zone: "utc" }).setZone(systemTimeZone);
    return dt.isValid ? dt.toFormat(DATE_TIME_FORMAT) : "N/A";
};
 
// Date + time from a timestamp that is already local (no trailing "Z"); used for
// "created at" displays. Standardized to MM/DD/YYYY (was a spelled-out short month).
export const utcToLocalTimeZone = (dateString) => {
    if (!dateString) return "Invalid date";
    const dt = DateTime.fromJSDate(new Date(dateString));
    return dt.isValid ? dt.toFormat(DATE_TIME_FORMAT) : "Invalid date";
};
 
// Date-only, MM/DD/YYYY. Accepts an ISO string, a Date, or anything `new Date()`
// can parse. The single helper for date-only displays across the app.
export const formatDate = (value) => {
    if (!value) return "N/A";
    const dt = value instanceof Date ? DateTime.fromJSDate(value) : DateTime.fromJSDate(new Date(value));
    return dt.isValid ? dt.toFormat(DATE_FORMAT) : "N/A";
};