Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

day.js default timezone problem #1227

Open
ruffryder opened this issue Nov 16, 2020 · 33 comments
Open

day.js default timezone problem #1227

ruffryder opened this issue Nov 16, 2020 · 33 comments

Comments

@ruffryder
Copy link

ruffryder commented Nov 16, 2020

Hi there. I am having trouble in the following scenario:
When I set the default timezone, using dayjs.tz.setDefault("America/New_York") and then create new object using
the dayjs() constructor, the newly created object does not have the timezone set. The only way to have timezone on the object is
by using the dayjs.tz() constructor, but in this case the expected arguments are completely different.
So, is there a way to set default timezone and be able to create objects with the standart constructor with the default timezone
set?
Code example:
dayjs.tz.setDefault("America/New_York");

dayjs("20/11/2020","DD/MM/YYYY"); // This object does not have the default timezone set

dayjs.tz(); //Here, we have the default timezone set to America/New_York

@iamkun
Copy link
Owner

iamkun commented Nov 19, 2020

dayjs.tz.setDefault only affect dayjs.tz at present

@ruffryder
Copy link
Author

So, does that mean that there's no way to create an object with the default timezone in the standard way (with dayjs() constructor)?

@iamkun
Copy link
Owner

iamkun commented Nov 20, 2020

Well, as for now, NO. We can only set default tz in dayjs.tz.

Feel free to open a PR if you need this.

@Pixelatex
Copy link

Can we atleast add this to the docs to clarify this? Spent quite searching for a weak bug that turns out to be caused by this.

@bene-we
Copy link

bene-we commented Jan 28, 2021

Also went looking for this, found the doc entry after quite a while under https://day.js.org/docs/en/timezone/set-default-timezone. Still +1 for this.

@Kotoriii
Copy link

Would love to have this as well

@hisuwh
Copy link

hisuwh commented May 18, 2021

The notice here is really unclear: Notice: dayjs.tz.setDefault will not affect existing dayjs objects.
This sounds to me like:

const value1 = dayjs("2021-05-18T14:44:00.000Z");

dayjs.tz.setDefault("Etc/UCT"); 

const value2 = dayjs("2021-05-18T14:44:00.000Z");

// value1 is an "existing dayjs object" so I would not expect it have the timezone.
const result = value1.format("DD/MM/YYYY HH:mm") === value2.format("DD/MM/YYYY HH:mm");
// would expect result to be false but actually true

@aagamdoshi
Copy link

@hisuwh Even I found this notice very unclear. Hoping for a cleaner description

@mrdulin
Copy link

mrdulin commented Jun 10, 2021

+1, What does Notice: dayjs.tz.setDefault will not affect existing dayjs objects. exactly mean? Please add an example for the documentation.

@jemink
Copy link

jemink commented Aug 17, 2021

facing the same issue with dayjs. In my current project I want to display all the date as per the login user time zone. So for that I am passing the user timezone in backend with header value and inside the backend I am setting default time zone with user time zone. Then after inside my code I used dayjs() and it was not use the setDefault timezone it use local timezone.

@iamkun
Copy link
Owner

iamkun commented Aug 18, 2021

At preset, setDefaultTimezone will only affect dayjs.tz() not dayjs()

e.g.

dayjs.tz.setDefault("America/New_York")

dayjs.tz("2014-06-01 12:00")  // The same behavior with dayjs.tz("2014-06-01 12:00", "America/New_York")

dayjs("2014-06-01 12:00")  // Still local timezone

But I'm thinking, seems it's better to make setDefaultTimezone a global default timezone. That is to say, dayjs() will also use the updated default timezone.

Just wondering if anyone is interested to make a PR to fix this?

@ycjcl868
Copy link

ycjcl868 commented Sep 1, 2021

Is there any progress?

@cmcnamara87
Copy link

I ended up doing this

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Australia/Sydney');

export default dayjs.tz;

and replacing all my imports import dayjs from './dayjs'

@madhurgarg71
Copy link

I ended up doing this

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Australia/Sydney');

export default dayjs.tz;

and replacing all my imports import dayjs from './dayjs'

@cmcnamara87 This works, but after doing this I am unable to see the autosuggestion for dayjs apis like .add(), ..subtract() etc. possibly because of the missing type definitions on dayjs.tz. Are you also facing the same or were you able to do something about it?

@KonstantinZhukovskij
Copy link

Any news here?

@ven
Copy link

ven commented Mar 22, 2022

any updates on this?

@Alex-Pqn
Copy link

Update or still nothing ?

@marnixhoh
Copy link

For what it's worth:
I just migrated a code base from moment to day.js and I too ran into this issue. The behavior of the two libraries differs here.

moment applies the default timezone to all instances --> applies to both moment() & moment.tz()
day.js applies the default timezone to only dayjs.tz()

@joelstein
Copy link

joelstein commented Sep 13, 2022

I also encountered this.

Switching to day.js from moment.js, I expected that dayjs.tz.setDefault() would affect all dayjs() instances.

As others mentioned, the documentation doesn't clearly explain the difference.

Time to find all dayjs( and replace with dayjs.tz(.

@merajseraji
Copy link

I ended up doing this

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Australia/Sydney');

export default dayjs.tz;

and replacing all my imports import dayjs from './dayjs'

@cmcnamara87 This works, but after doing this I am unable to see the autosuggestion for dayjs apis like .add(), ..subtract() etc. possibly because of the missing type definitions on dayjs.tz. Are you also facing the same or were you able to do something about it?

this works for me. with this code also you can use autoseffestion for daujs apis :
dayjs.extend(utc); dayjs.extend(timezone); dayjs.tz.setDefault("Asia/Tehran");
static dayjs(): Dayjs { return dayjs.tz(dayjs()) as Dayjs; }

and then use this.dayjs() anywhere.

@hisuwh
Copy link

hisuwh commented Oct 12, 2022

globals...🤢

@crobinson42
Copy link

I like how axios lib allows creating an instance via const authApi = axios.create({ ... }); const publicApi = axios.create({ ... });.

dayjs should do something similar:

const asiaTehranDayjs = dayjs.instance().tz.setDefault('Asia/Tehran')

Also, another really great convenience that others have pointed out (@marnixhoh comment) would be to also automatically apply the default timezone so it's not necessary to call dayjs().tz().format() etc..

@CaM2091
Copy link

CaM2091 commented Nov 3, 2022

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 import from import dayjs from "dayjs" to import dayjs from "my-service/dayjs"
With this, typing works even with plugins

@mishanianod
Copy link

Hi, default timezone is needed on the dayjs

@andrew-atwood-infinitusai
Copy link
Contributor

The underlying problem here is that there's no way for the plug-in to update the constructor called by the main dayjs factory function, so it's impossible for the timezone plug-in to work that way.

If plug-ins could each initialize functions that the constructor would iterate through and call, it would make the desired behavior possible.

@maordaniel
Copy link

maordaniel commented Apr 24, 2023

Another issue with Day.js's timezone functionality is that when a date without a timestamp is passed, Day.js will calculate a default timestamp and then apply the timezone to it, which can cause the date to advance by a day if the timezone is positive.

dayjs.tz.setDefault("Africa/Addis_Ababa")
moment.tz.setDefault("Africa/Addis_Ababa")

const aDate = "2023-02-06"

const dayjsDate = dayjs(aDate).tz().format("MMM DD, YYYY")
const momentDate = moment(aDate).format("MMM DD, YYYY")

dayjsDate eq to "Feb 27, 2023"
momentDate eq to "Feb 26, 2023"

@Anubarak
Copy link

Anubarak commented Jul 19, 2023

Could you at least make a setting that somehow makes it unable to create dayjs objects? or a setting that requires the local for all dayjs objects?

I was about to switch to dayjs but I know me - even if there is a service and I do always use my custom dayjs service - there will be the day in a few years where I or others in my team will most certainly forget it and import the normal dayjs function and no-one will notice it - since everything works for us.

using dayjs.tz() over dayjs() is just so inconvinient in my opinion - most people with several projects that use dayjs() 95% of the time will forget it, when they hop into the one project that requires dayjs.tz()

@EgorKluch
Copy link

Could you at least make a setting that somehow makes it unable to create dayjs objects? or a setting that requires the local for all dayjs objects?

I was about to switch to dayjs but I know me - even if there is a service and I do always use my custom dayjs service - there will be the day in a few years where I or others in my team will most certainly forget it and import the normal dayjs function and no-one will notice it - since everything works for us.

using dayjs.tz() over dayjs() is just so inconvinient in my opinion - most people with several projects that use dayjs() 95% of the time will forget it, when they hop into the one project that requires dayjs.tz()

And daysjs.tz doesn't have strict flag.

@justingolden21
Copy link

I'm running into an issue where only GMT+0 (London) doesn't work, but every other timezone works fine... I think it's related to this issue in dayjs as I have no specific code for that case.

@justingolden21
Copy link

dayjs($now).tz('Etc/GMT').locale( 'en').format('h:mm A')

INCORRECT time: 1:36pm

dayjs($now).tz('Etc/GMT').format('h:mm A') (without locale)

CORRECT time: 5:36pm

This bug is only present if the timezone is 'Etc/GMT' (or 'Europe/London') and works fine in 'Etc/GMT+1' and 'Etc/GMT-1' with locale set.

@h0gar
Copy link

h0gar commented Feb 22, 2024

My solution:

const dayjstz = (...args) => dayjs(...args).tz("Europe/Paris", true);
for(let k of Object.getOwnPropertyNames(dayjs)) {
  if(k === 'unix')
    dayjstz.unix = (...args) => dayjs.unix(...args).tz();
  else
    dayjstz[k] = (...args) => dayjs[k](...args);
}
dayjstz.dayjs = dayjs;

module.exports = dayjstz

@dominikbrazdil
Copy link

dayjs($now).tz('Etc/GMT').locale( 'en').format('h:mm A')

INCORRECT time: 1:36pm

dayjs($now).tz('Etc/GMT').format('h:mm A') (without locale)

CORRECT time: 5:36pm

This bug is only present if the timezone is 'Etc/GMT' (or 'Europe/London') and works fine in 'Etc/GMT+1' and 'Etc/GMT-1' with locale set.

I experience the same issue

@bmg-will
Copy link

bmg-will commented Apr 3, 2024

We ran into this issue recently due to not spotting the warning in the docs and assumed it would default the tz for all new dayjs objects.

We fixed it by doing the below in case it helps anyone with this issue -

import dayjsImport from 'dayjs';

// various .extend method calls to dayJsImport here

const dayjs = (date?: dayjsImport.ConfigType, format?: dayjsImport.OptionType) => {
  const instance = dayjsImport(date, format);
  instance.tz('Europe/London');
  return instance;
};

dayjs.isDayjs = dayjsImport.isDayjs;
// make sure to add any other methods you use directly on dayjs. here

export default dayjs;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.