Skip to content

Commit

Permalink
fix: numeric timestamp handling, notz case
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmcgrath13 committed Jan 7, 2025
1 parent 1cfaf9f commit 4bd8601
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 46 deletions.
77 changes: 54 additions & 23 deletions containers/ecr-viewer/src/app/services/formatService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,22 @@ export const formatAddress = (
// Return the offset from UTC for a dateTimeString given the original time zone string
// EDT => -04
// Z => +00
// none => +00
// none => local
const getTimeZoneOffset = (dateTimeString: string, tzString: string | null) => {
if (tzString === null) return formatTzOffset(0);

const trueDate = new Date(dateTimeString);

if (tzString === null) return getLocalTimeZoneOffset(trueDate);

const notzDateString = dateTimeString.slice(0, -1 * tzString.length).trim();
const localDate = new Date(notzDateString);
const diffMin = (localDate.valueOf() - trueDate.valueOf()) / 1000 / 60;
const diffHr = (diffMin - trueDate.getTimezoneOffset()) / 60;
return formatTzOffset(diffHr);
};

// TODO: do we need this? or just use undefined and maybe short-generic name
// const getLocalTimeZoneOffset = (date: Date) => {
// return formatTzOffset(date.getTimezoneOffset() / -60);
// };
const getLocalTimeZoneOffset = (date: Date) => {
return formatTzOffset(date.getTimezoneOffset() / -60);
};

// Format numeric offset in parser friendly '+/-dd'
const formatTzOffset = (diffHr: number): string => {
Expand Down Expand Up @@ -145,6 +145,31 @@ const getTimeZoneString = (dateTimeString: string): string | null => {
return null;
};

// yyyymmdd[hhmmss][+-zzzz] to ISO
const reformatNumericTimestampToISO = (dateTimeString) => {
// datetime is 20240101[1234][56][-0400] style
const parts = dateTimeString.match(
/(\d{4})(\d{2})(\d{2})(\d{2})?(\d{2})?(\d{2})?([+-]\d{4})?/,
);
// The regex didn't consume everything
if (!parts) {
return dateTimeString;
}
const dateParts = parts.slice(1, 4);
const timeParts = parts.slice(4, 7).filter(Boolean);
const tzPart = parts.at(-1);

let newDateStr = dateParts.join("-");
if (timeParts.length > 0) {
newDateStr += "T";
newDateStr += timeParts.join(":");
}
if (tzPart) {
newDateStr += tzPart;
}
return newDateStr;
};

/**
* Format a datetime string to "MM/DD/YYYY HH:MM AM/PM Z" where "Z" is the timezone abbreviation.If
* the input string contains a UTC offset then the returned string will be in the format
Expand All @@ -170,10 +195,17 @@ export const formatDateTime = (

const date = new Date(dateTimeString);
if (date.toString() === "Invalid Date") {
// datetime is 20240101[1234][56][-0400] style?
const newDateStr = reformatNumericTimestampToISO(dateTimeString);
if (newDateStr !== dateTimeString) {
return formatDateTime(newDateStr, local);
}

// If we are unable to format the date, return as is
return dateTimeString;
}

// time as 00:00[:000]
const hasTime = dateTimeString?.includes(":");
if (!hasTime) {
return formatDate(dateTimeString) || dateTimeString;
Expand All @@ -199,7 +231,7 @@ export const formatDateTime = (

// Not actually time zoned
if (!local && timezone === null) {
return formatted.slice(0, -4); // lop off " GMT"
return formatted.slice(0, formatted.lastIndexOf(" ")); // lop off " GMT"
}

return formatted;
Expand All @@ -214,22 +246,21 @@ export const formatDate = (dateString?: string): string | undefined => {
if (dateString) {
let date = new Date(dateString);

if (date.toString() == "Invalid Date") {
const formattedDate = `${dateString.substring(
0,
4,
)}-${dateString.substring(4, 6)}-${dateString.substring(6, 8)}`; // yyyy-mm-dd
date = new Date(formattedDate);
}
// double check that the reformat actually worked otherwise return nothing
if (date.toString() != "Invalid Date") {
return date.toLocaleDateString("en-US", {
year: "numeric",
month: "2-digit",
day: "2-digit",
timeZone: "UTC",
}); // UTC, otherwise will have timezone issues
if (date.toString() === "Invalid Date") {
const newDateStr = reformatNumericTimestampToISO(dateString);
if (newDateStr !== dateString) {
return formatDate(newDateStr);
}

return undefined;
}

return date.toLocaleDateString("en-US", {
year: "numeric",
month: "2-digit",
day: "2-digit",
timeZone: "UTC",
}); // UTC, otherwise will have timezone issues
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
formatPhoneNumber,
} from "@/app/services/formatService";
import { ContactPoint, HumanName } from "fhir/r4";
import { splitTimeZone } from "../../services/formatService";

describe("Format Name", () => {
const inputHumanName = {
Expand Down Expand Up @@ -123,28 +122,6 @@ describe("formatDateTime", () => {
});
});

describe("splitTimeZone", () => {
it("given datetime string, returns the thing", () => {
const dates = [
"04 Dec 1995 00:12:00 GMT-5",
"04 Dec 1995 00:12:00",
"200401010924-0400",
"200401010924",
"08/04/2024 10:02 AM EDT",
"08/04/2024 10:02 AM",
"2019-01-16T12:19:10-05:00",
"2019-01-16T12:19:10",
"2019-01-16T12:19:10Z",
];

dates.forEach((date) => {
const res = splitTimeZone(date);
console.log(res);
expect(res).toBeDefined();
});
});
});

describe("Format Date", () => {
it("should return the correct formatted date", () => {
const inputDate = "2023-01-15";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
BuildHeaders,
BuildTable,
} from "@/app/view-data/components/EvaluateTable";
import React from "react";

type AdministeredMedicationProps = {
medicationData: AdministeredMedicationTableData[];
Expand Down

0 comments on commit 4bd8601

Please sign in to comment.