Get client current date ?
Unanswered
California pilchard posted this in #help-forum
California pilchardOP
Hey guys, in NextJS how do we get the current time of the client (not of the server), because when I do
new Data()
in use client;
component, in production (server Hetzner) the date is timezoned from the server not the client. Im having a component which give the ended time of the movie so I really need to have the datetime from client :"use client";
import { addMinutes } from 'date-fns';
import { useFormatter, useNow } from 'next-intl';
import { ConvertHoursMinutes, cn } from '@/lib/utils';
import { TooltipBox } from '../Box/TooltipBox';
export function RuntimeTooltip({
runtime,
className,
}: {
runtime: number;
className?: string;
}) {
const format = useFormatter();
const now = useNow({ updateInterval: 1000 * 60 });
if (!runtime) return;
const endTime = addMinutes(now, runtime);
const formattedEndTime = format.dateTime(endTime, {
hour: 'numeric',
minute: '2-digit',
});
return (
<TooltipBox tooltip={runtime ? `Se termine à ${formattedEndTime}` : 'Unknown'}>
<span className={cn('w-fit cursor-pointer', className)}>{ConvertHoursMinutes(runtime ?? 0)}</span>
</TooltipBox>
)
}
11 Replies
@California pilchard Hey guys, in NextJS how do we get the current time of the client (not of the server), because when I do `new Data()` in `use client;` component, in production (server Hetzner) the date is timezoned from the server not the client. Im having a component which give the ended time of the movie so I really need to have the datetime from client :
tsx
"use client";
import { addMinutes } from 'date-fns';
import { useFormatter, useNow } from 'next-intl';
import { ConvertHoursMinutes, cn } from '@/lib/utils';
import { TooltipBox } from '../Box/TooltipBox';
export function RuntimeTooltip({
runtime,
className,
}: {
runtime: number;
className?: string;
}) {
const format = useFormatter();
const now = useNow({ updateInterval: 1000 * 60 });
if (!runtime) return;
const endTime = addMinutes(now, runtime);
const formattedEndTime = format.dateTime(endTime, {
hour: 'numeric',
minute: '2-digit',
});
return (
<TooltipBox tooltip={runtime ? `Se termine à ${formattedEndTime}` : 'Unknown'}>
<span className={cn('w-fit cursor-pointer', className)}>{ConvertHoursMinutes(runtime ?? 0)}</span>
</TooltipBox>
)
}
you need to do it in useEffect or use next/dynamic ssr: false
because what happens here is that the component is prerendered on the server so the value follows server-side timezone. disabling ssr with ssr: false, or running the time-related code in useEffect, will ensure it is not run on the server, fixing the issue
because what happens here is that the component is prerendered on the server so the value follows server-side timezone. disabling ssr with ssr: false, or running the time-related code in useEffect, will ensure it is not run on the server, fixing the issue
@joulev you need to do it in useEffect or use next/dynamic ssr: false
because what happens here is that the component is prerendered on the server so the value follows server-side timezone. disabling ssr with ssr: false, or running the time-related code in useEffect, will ensure it is not run on the server, fixing the issue
California pilchardOP
Thx for ur help ! Like this ?
"use client";
...
export function RuntimeTooltip({
runtime,
className,
}: {
runtime: number;
className?: string;
}) {
const format = useFormatter();
const [endTime, setEndTime] = useState<Date | null>(null);
const formattedEndTime = useMemo(() => {
if (!endTime) return null;
return format.dateTime(endTime, {
hour: 'numeric',
minute: '2-digit',
});
}, [endTime]);
useEffect(() => {
const now = new Date();
setEndTime(addMinutes(now, runtime));
}, [runtime]);
if (!runtime || !endTime) return null;
return (
<TooltipBox tooltip={`Se termine à ${formattedEndTime}`}>
<span className={cn('w-fit cursor-pointer', className)}>
{ConvertHoursMinutes(runtime)}
</span>
</TooltipBox>
);
}
@joulev yeah. if `endTime` is `null` you can render a loading state for example
California pilchardOP
Okay Im gonna try this (to check I have to push and wait build time to see if its working 😂)
@joulev yeah. if `endTime` is `null` you can render a loading state for example
California pilchardOP
Well even with the previous example I have the same problem (expected result :
7:27 PM
because my current time is 5:44 PM
)@California pilchard Well even with the previous example I have the same problem (expected result : `7:27 PM` because my current time is `5:44 PM`)
i will need a minimal reproduction repo then
by the way you can enforce a timezone for the server by setting the
TZ
environment variable TZ=UTC pnpm start
then you can test things locally
@joulev by the way you can enforce a timezone for the server by setting the `TZ` environment variable `TZ=UTC pnpm start`
California pilchardOP
Ohh didn’t know that it’s gonna help me a lot !
Thx !
California pilchardOP
Okay the issue seems to be with
useFormatter
, I have to specify the timezone in the format like this : const format = useFormatter();
const userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; // <= GET TIMEZONE
const now = useNow({ updateInterval: 1000 * 60 });
const endTime = useMemo(() => {
if (!runtime) return null;
return addMinutes(now, runtime);
}, [runtime, now]);
const formattedEndTime = useMemo(() => {
if (!endTime) return null;
return format.dateTime(endTime, {
hour: 'numeric',
minute: '2-digit',
timeZone: userTimeZone, // <= SPECIFY HERE
});
}, [endTime]);