dayjs() is in the wrong timezone
Asked Answered
S

4

8

Problem

Calling dayjs() results in a date that is correct except it is off by two hours. For some reason, dayjs() seems to be set to the wrong time zone (GMT), when my actual time zone is GMT+2.

Expected

Mon, 09 Aug 2021 17:45:55 GMT+2

Actual

Mon, 09 Aug 2021 15:45:55 GMT

What I've tried

I have tried setting my time zone with the time zone plugin, but that didn't seem to work:

import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs().tz('Europe/Berlin'); // unchanged Mon, 09 Aug 2021 15:45:55 GMT

I'm on Ubuntu 20.04.2 LTS, so I checked:

$ timedatectl 
Local time: Mo 2021-08-09 17:45:55 CEST
Universal time: Mo 2021-08-09 15:45:55 UTC 
RTC time: Mo 2021-08-09 17:45:55     
Time zone: Europe/Berlin (CEST, +0200)
System clock synchronized: yes                        
NTP service: active                     
RTC in local TZ: yes                        

Warning: The system is configured to read the RTC time in the local time zone.
This mode cannot be fully supported. It will create various problems
with time zone changes and daylight saving time adjustments. The RTC
time is never updated, it relies on external facilities to maintain it.
If at all possible, use RTC in UTC by calling
'timedatectl set-local-rtc 0'.

I am coding in TypeScript, so I also checked if creating a Date object would result in the wrong time too, but it did not:

const time = new Date(); // results in correct time

TL;DR

dayjs() is in GMT, but should be in GMT+2. Why?

Stlouis answered 9/8, 2021 at 16:31 Comment(8)
When you do new Date('Mon, 09 Aug 2021 17:45:55 GMT+2') and new Date('Mon, 09 Aug 2021 15:45:55 GMT') what are the resulting date objects? How do they differ?Macron
They result in the same thing: 1: Mon Aug 09 2021 17:45:55 GMT+0200 (Central European Summer Time) 2: Mon Aug 09 2021 17:45:55 GMT+0200 (Central European Summer Time)Stlouis
In your question you said it's "off by two hours". Is it off by 2 hours or is the same exact time? Can you just store your as GMT?Macron
My problem is that dayjs seems to go off a wrong local time. My problem with that is that if i run the same code on a different machine it doesnt work anymore because on that machine the local time works correctly.Stlouis
So you are saying if one machine is in Germany and another machine is in United Kingdom, and you create new dates and store those utc/iso string values, then using those strings on the opposite machine it results in different times? Not local, different UTC/ISO times. The local times can be "different" but if they generated the same iso/utc string then they are the same right?Macron
You are confusing the ever living hell out of me. dayjs() results in a time that is two hours behind what it should be. thats the problem.Stlouis
You've determined that both the dates are the same exact time accounting for offset. As long as you turn the respective date objects back into UTC/ISO time, then you can use that string to create dates effectively across time zones. Can you maybe share how exactly you are using the dates to explain the issue you are seeing?Macron
may be useful: github.com/iamkun/dayjs/issues/1227Mckelvey
E
3
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Europe/Berlin');

You should try this way. However, note, that it affects only dayjs.tz('some date'), dayjs() still will show your local time.

Entire answered 22/8, 2022 at 12:39 Comment(1)
Your last sentence is wrong. It doens't matter your timezone. dayjs() always brings GMT. I'm in GMT-0300, and still prints "Wed, 29 Nov 2023 21:27:43 GMT". Comparing with moment(), it prints "Wed Nov 29 2023 18:25:08 GMT-0300", which is the right time now.Interdictory
G
3

You can create a service like this

// Filename : dayjs.ts

import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";
import "dayjs/locale/fr";

dayjs.extend(utc);
dayjs.extend(timezone);

dayjs.locale("fr");
dayjs.tz.setDefault("Europe/Paris")

const timezonedDayjs = (...args: any[]) => {
    return dayjs(...args).tz();
};

const timezonedUnix = (value: number) => {
    return dayjs.unix(value).tz();
};

timezonedDayjs.unix = timezonedUnix;
timezonedDayjs.duration = dayjs.duration;

export default timezonedDayjs;

And change your imports from import dayjs from "dayjs" to import dayjs from "my-service/dayjs"

With this, typing works even with plugins

Geoponics answered 3/11, 2022 at 10:29 Comment(0)
S
2

Simply using the utc plugin without the timezone plugin somehow had the desired effect.

import utc from 'dayjs/plugin/utc';
day.extend(utc);
dayjs.utc(); // results in date in correct timezone
Stlouis answered 26/8, 2021 at 16:19 Comment(1)
I believe that's supposed to be: dayjs.extend(utc);Mender
P
2

This is what works for me.

dayjs('2021-08-09 15:45:55 UTC').tz("Africa/Lagos")

Response

{
  '$L': 'en',
  '$offset': 60,
  '$d': 2021-08-09T15:45:55.000Z,
  '$x': { '$timezone': 'Africa/Lagos' },
  '$y': 2021,
  '$M': 7,
  '$D': 9,
  '$W': 1,
  '$H': 16,
  '$m': 45,
  '$s': 55,
  '$ms': 0
}
Pommard answered 15/11, 2021 at 15:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.