Skip to content

Commit

Permalink
fix(Dates): Set zone for dates coming from the backend as UTC by defa…
Browse files Browse the repository at this point in the history
…ult & load the user tz in the browser
  • Loading branch information
qgerome committed Jan 15, 2025
1 parent e489afb commit f965b5b
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 25 deletions.
27 changes: 11 additions & 16 deletions src/core/components/Time/Time.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,40 @@
import clsx from "clsx";
import useRelativeTime from "core/hooks/useRelativeTime";
import { DateTime, DateTimeOptions } from "luxon";
import { memo, useMemo } from "react";
import { useMemo } from "react";

type Props = {
datetime: string;
zone?: string;
className?: string;
relative?: boolean;
format?: DateTimeOptions;
};

const Time = (props: Props) => {
const datetime = useMemo(
() => DateTime.fromISO(props.datetime),
// By default, all dates from the backend are in UTC
() => DateTime.fromISO(props.datetime).toLocal(),
[props.datetime],
);

const relativeDate = useRelativeTime(datetime);

const value = useMemo(() => {
if (props.relative) {
return relativeDate;
} else {
return datetime.toLocaleString(props.format ?? DateTime.DATETIME_SHORT);
}
// We use the toggle variable to force React to recompute this value
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [datetime, props.format, props.relative, relativeDate]);

if (!datetime?.isValid) return null;

const isoDate = datetime.toISO();
return (
<time
suppressHydrationWarning={true}
title={datetime.toISO() ?? undefined}
dateTime={datetime.toISO() ?? undefined}
title={isoDate ?? undefined}
dateTime={isoDate ?? undefined}
className={clsx("whitespace-nowrap", props.className)}
>
{value}
{props.relative
? relativeDate
: datetime.toLocaleString(props.format ?? DateTime.DATETIME_SHORT)}
</time>
);
};

export default memo(Time);
export default Time;
2 changes: 1 addition & 1 deletion src/core/components/Time/__snapshots__/Time.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ exports[`Time renders relative time 2`] = `
datetime="2022-02-20T10:11:34.000+01:00"
title="2022-02-20T10:11:34.000+01:00"
>
10 minutes ago
2 hours ago
</time>
</div>
`;
Expand Down
4 changes: 3 additions & 1 deletion src/core/hooks/useRelativeTime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ function useRelativeTime(datetime: DateTime | string) {

const value = useMemo(() => {
if (!datetime) return null;
return typeof datetime === "string" ? DateTime.fromISO(datetime) : datetime;
return typeof datetime === "string"
? DateTime.fromISO(datetime, { zone: "utc" })
: datetime;
}, [datetime]);

return value ? value.toRelative() : null;
Expand Down
18 changes: 11 additions & 7 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Head from "next/head";
import { ApolloProvider } from "@apollo/client";
import { useApollo } from "core/helpers/apollo";
import DefaultLayout from "core/layouts/default";
Expand All @@ -9,14 +8,19 @@ import "../styles/globals.css";
import AlertManager from "core/components/AlertManager";
import { useEffect } from "react";
import { setUser } from "@sentry/nextjs";
import ErrorBoundary from "core/components/ErrorBoundary/ErrorBoundary";
import { Settings } from "luxon";
import Head from "next/head";
// Set the default timezone to use on the client
import { MeProvider } from "identity/hooks/useMe";
import ErrorBoundary from "core/components/ErrorBoundary/ErrorBoundary";

// Set the default locale & timezone to be used on server and client.
// This should be changed to use the correct lang and tz of the user when it's available.
// Fixes #OPENHEXA-D7 Hydration error
Settings.defaultZone = "Europe/Brussels";
if (typeof window !== "undefined") {
try {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
Settings.defaultZone = timeZone;
} catch (e) {
console.error(e);
}
}

function App({ Component, pageProps }: AppPropsWithLayout) {
const apolloClient = useApollo(pageProps);
Expand Down

0 comments on commit f965b5b

Please sign in to comment.