Next.js Discord

Discord Forum

Get client current date ?

Unanswered
California pilchard posted this in #help-forum
Open in Discord
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

@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)
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]);