2

I have weird behaviour using new Date(stringFormat) in js

Why is result of this:

 var date = new Date('2020-03-01') 
 console.log(date.toISOString())

different than

 var date = new Date(2020,2,1) 
 console.log(date.toISOString())

And this is what I get

2020-03-01T00:00:00.000Z
2020-02-29T23:00:00.000Z

I want to have always the first result. I want to understand why is there difference between these two, I see that it's something with timezones, but I'm providing same date in both cases but result is different. Is any of these overloading obsolete?

What is the reason for different interpreting of timezones by both methods? Can I assume that in every timezone and every browser from first method I will get first result?

sTrenat
  • 1,029
  • 9
  • 13
  • 1
    The ISO string is considered UTC, the other one is considered local. – VLAZ Jun 17 '20 at 10:00
  • 1
    I know, but you can see that I call toISOString on both and the result is different – sTrenat Jun 17 '20 at 10:03
  • Yes, it would be because your timezone is *not* UTC. The first one means `2020-03-01T00:00:00+00:00`, the second is instead `2020-03-01T00:00:00+01:00` because you're most likely your local timezone is the UK. If not, you're it's still a +1 timezone. So, when you convert the latter *to* a UTC date, it's an hour back which also shifts the date back. – VLAZ Jun 17 '20 at 10:14
  • I'm not asking about difference between utc and local time, I'm asking about new Date(stringFormat) vs new Date(year,month,day) – sTrenat Jun 17 '20 at 10:16
  • Again, I explained it - first one is treated as UTC, the second is local. You said you understood that and yet still asked why the output is different. So, what *is* the question? Two different timestamps are different. If they point at the same datetime but they are in different timezones, that *also* makes them different timestamps. – VLAZ Jun 17 '20 at 10:18
  • I'm asking about why is one threated as UTC and second as local and I think Robby Cornelissen answerd this, but I still want to know if I can safely use it to get UTC time – sTrenat Jun 17 '20 at 10:22
  • "*I'm asking about why is one threated as UTC and second as local*" because that's how the specs have have been defined. "*but I still want to know if I can safely use it to get UTC time*" this is unclear. The `Date` objects do not have a timezone. You can *read* something with a timezone and you can *output* something with a timezone, if you wish but the date is always kept as UTC. Well, as a Unix timestamp but that itself is always UTC. So *regardless of how you construct it*, a date object is "in UTC". The input/output can take the local timezone into consideration and apply an offset. – VLAZ Jun 17 '20 at 10:31

1 Answers1

2

From MDN:

Parsing of date strings with the Date constructor (and Date.parse(), which works the same way) is strongly discouraged due to browser differences and inconsistencies.

And specifically to the point of your question (emphasis mine):

Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local

So that explains the difference in timezone handling that you're witnessing.

Compare the output of the following two statements:

console.log(new Date('2020-03-01').toISOString());
console.log(new Date('2020-03-01T00:00:00').toISOString());
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
  • Ok, does it mean i can always assume it will be treated as UTC, not local? or it may differ between browsers or can change in future ECMA versions? – sTrenat Jun 17 '20 at 10:14
  • @sTrenat To make sure, always include the `Z` in the timestamp. – Bergi Jun 17 '20 at 10:29
  • When it comes to parsing date strings using the `Date` constructor, I think it's best to not make too many assumptions. I expect that in one of the upcoming ECMAScript versions we'll see a new date/time API. I also expect that this will effectively freeze the behavior of the current `Date` class. – Robby Cornelissen Jun 17 '20 at 10:29