How to avoid/control a timezone offset when deploying next.js app to vercel?

Viewed 20

In a React/Next.js App, is there a way to always make sure, anywhere in the world it shows the local time in CEST. Let’s say; I get the GMT time from my backend, which I want to offset, to display the CEST timezone offset of that time. That same time should be displayed anywhere in the world. Case: Exhibition Opening in Berlin at 6pm local time, shouldn't be displayed as different time in another timezone! Important in my case is also, that it has to work as well if the server and client are in different timezones as the function may be called on either side. This was my attempt:

  const initialDate = new Date("Fri, 07 May 2021 17:00:00 GMT");

  const userTimezoneOffset = initialDate.getTimezoneOffset() * 60000;

  const date = new Date(initialDate.getTime() - userTimezoneOffset);

I am struggling to fix this one for a while now, and I failed to find a solution working for me. When the app is deployed, it is 4pm instead of 6pm. It works correctly in dev mode as well as when building locally, it even works when I change my local time with .env.TZ. But the timezone is always off when deploying to vercel. I assume it has something to do, wether the time is rendered server-side or client-side…

1 Answers

A few things:

  • CEST is UTC+2, and was indeed in effect in Berlin on the date you gave - so 6pm (18:00) is 16:00 UTC, not 17:00 UTC.

  • You should prefer date strings in ISO 8601 / RFC 3339 format, rather than the RFC 822/2822 formatted string you showed. (See the language spec for how dates get parsed.)

  • The approach you show that is subtracting time from the date object and constructing a new one should be avoided. You're not actually changing the time zone, but picking a new point in time completely.

  • Date objects cannot represent time in other time zones, but they can create string representations that have a time zone applied by using toLocaleString and specifying the timeZone option.

Thus, you can do this:

const d = new Date("2021-05-07T16:00:00Z");
const s = d.toLocaleString(undefined, {timeZone: 'Europe/Berlin' });
console.log(s);

Note undefined here means to use the user's default locale (language and region-specific formatting preferences) to produce an appropriate string. You could instead specify a language such as en or full locale such as en-US. There are also many other formatting options available. See the docs for details.

Related