0

Javascript Dates work with timezones. If I create a date, it sets the timezone. When I update the year of that date, I don't expect the timezone to change. It does, however. The worst thing is that it changes the timezone but not the time, causing the actual time to shift by one hour!

This causes the issue that if I have the person's birth date, and want to know his birthday this year, I cannot simply set the year to the current year using birthdate.setFullYear(2018), because it will return the birthday minus one hour. That means that it occurs one day before the actual birthday, at eleven 'o clock.

let test = new Date('1990-10-20');
console.log(test);
console.log(test.toISOString().substring(0, 10));

// 1990-10-20 ( Sat Oct 20 1990 01:00:00 GMT+0100 (Central European Standard Time) )

test.setFullYear(2000);
console.log(test);
console.log(test.toISOString().substring(0, 10));

// 2000-10-19 ( Fri Oct 20 2000 01:00:00 GMT+0200 (Central European Summer Time) === one hour too soon!! )

It might be that your timezone does not reproduce, here is my output:

"1990-10-20T00:00:00.000Z"

1990-10-20

"2000-10-19T23:00:00.000Z"

2000-10-19

The only workaround I found is substring the date and replace it as string values. How can I do it better using the Date object?

Community
  • 1
  • 1
Randy
  • 9,419
  • 5
  • 39
  • 56
  • is the timezone really the issue here? i test your code and it's fine. – david Sep 20 '18 at 06:44
  • I think this is more of an issue of Daylight Savings. as UTC, the time is the same, right ? – Pac0 Sep 20 '18 at 06:45
  • 1
    ahh I understand, it's the other way round : in local time, the time actually stays the same. See Ramiz' answer. I'ts just that you try to show the datetime in UTC. Because of saylight saving issues, it is not the same. – Pac0 Sep 20 '18 at 06:46
  • This seems to be browser specific - I see issue in Chrome, but Firefox, Edge and IE display "2000-10-20T00:00:00.000Z" – barbsan Sep 20 '18 at 09:53

2 Answers2

3

Hm, maybe it would be better to use setUTCFullYear(...) (MDN Docs) instead? At least in that case, it won't mess up the time.

let test = new Date('1990-10-20');
console.log(test);
console.log(test.toISOString().substring(0, 10));

// "1990-10-20T00:00:00.000Z")

test.setUTCFullYear(2000);
console.log(test);
console.log(test.toISOString().substring(0, 10));

// "2000-10-20T00:00:00.000Z"
Ramiz Wachtler
  • 5,623
  • 2
  • 28
  • 33
  • 1
    That indeed fixes my issue. Reading the specs, it seems the browser should actually set the TimeClip to UTC which causes this, I never thought of Daylight Savings being different back then. Thx! – Randy Sep 20 '18 at 06:49
0

BEWARE THE TIMEZONE If you want to work with just-a-date using the date object (and you more or less have to) your date objects should represent UTC midnight at the start of the date in question. In your case, to indicate a year, use UTC midnight at the start of the 1st January. This is a common and necessary convention, but it requires a lot of attention to make sure that the timezone doesn't creep back in, as you've discovered.

When you say "javascript dates work with timezones", a javascript date is a moment in time (ticks since the epoch) with handy static functions for converting that moment into a meaningful string in the local timezone (or a specified timezone). The date object itself does not have a timezone property.

So, you can create your UTC midnight year with something like...

var myDate = new Date(Date.UTC(2018,0,1)); // months are zero-indexed !

Then serialize it specifying UTC...

myDate.toISOString();
myDate.toLocaleDateString("en",{timezone:"UTC"});
bbsimonbb
  • 27,056
  • 15
  • 80
  • 110