1

What is the correct way to initialize Date in EcmaScript5.

Here is what I am trying to do:

//18.02.09 12:00 - 18.02.11 24:00
 var StartTime = new Date("2018-02-09T12:00:00.000Z").getTime();
 var EndTime = new Date("2018-02-11T23:59:00.000Z").getTime();

What am I doing wrong here?

I am changing the time on my laptop to 18.02.09 12:01 PM. Then I am calling new Date().now(). What I expect is to get a number which would be between StartTime and EndTime. But I am getting something less on two hours than StartTime.

trafalgarLaww
  • 505
  • 6
  • 15
  • What result did you expect? – Pedro A Jan 27 '18 at 19:49
  • @Hamsterrific, I am expecting to get respective dates. Will I get them? – trafalgarLaww Jan 27 '18 at 19:50
  • I've updated my answer, let me know if you need more help :) – Pedro A Jan 27 '18 at 20:08
  • There is no "EcmaScript5". There is a language called "ECMAScript" that is controlled by the standards body ECMA through [*TC39*](https://www.ecma-international.org/memento/TC39.htm). The language specification has a number of editions, the latest being edition 8, which has a short name of [*ECMAScript 2018*](http://ecma-international.org/ecma-262/8.0/). There was also "HTML5" which has split to become the WHATWG's [*HTML Living Standard*](https://html.spec.whatwg.org/multipage/) and W3C's HTML standard, the current version is [*5.2*](https://www.w3.org/TR/2017/REC-html52-20171214/). – RobG Jan 28 '18 at 06:03
  • If your host is set for a timezone offset of UTC+0200, then "18.02.09 12:01 PM" (which might also be written in ISO 8601 extended format as `2018-02-09T12:01:00+0200`) is equivalent to `2018-02-09T10:01:00Z`, which is not within the interval you've specified. – RobG Jan 29 '18 at 07:18
  • @RobG, how should I haver written then? – trafalgarLaww Jan 29 '18 at 07:19
  • @RobG, or how could I get time taking into account that the host may have UTC set to something different from +0000 ? – trafalgarLaww Jan 29 '18 at 07:20
  • If the TC39 had followed common sense they would have conformed to ISO 8601 and specified that date-only strings be parsed as local, but in their wisdom (and at the persuasion of vested interests) determined they should be parsed as UTC. So the only reliable way is to use the Date constructor with arguments for year, month and day. You could also write your own function to parse Y-M-D format as local (2 lines of code). An alternative is to use an ISO 8601 date and time string without at timezone, e.g. "2018-02-09T00:00:00", but that is not reliable, even in current browsers. – RobG Jan 29 '18 at 08:35

2 Answers2

1

Strings such as "2018-02-09T12:00:00.000Z" are a standardized way to define dates, given by ISO 8601.

There are various ways to construct a Date object in JavaScript. From the Date MDN docs, we can see that one of the ways of doing that is by providing a string to be parsed. There is even an example:

var date2 = new Date("1995-12-17T03:24:00");

But you should not do that. That same page warns that creating a Date by parsing a string is not recommended since it is implementation-dependant (i.e. it might work differently depending on the browser).

Regardless, it is important to mention that in ISO 8601, ending a timestamp with the letter "Z" has a special meaning - it says that instead of considering local time, the date should be interpreted as being in UTC. So, regardless of how you decide do construct your Date object, don't forget to decide whether you want your timestamps to be localized or referring to the UTC standard time.

A safe way to construct your Date object is by providing the arguments separately:

new Date(year, month);
new Date(year, month, day);
new Date(year, month, day, hours);
new Date(year, month, day, hours, minutes);
new Date(year, month, day, hours, minutes, seconds);
new Date(year, month, day, hours, minutes, seconds, milliseconds);

You can also consider using an awesome library called MomentJS, whose size is 16.3 kB at the time of this writing (definitely worth considering), which is very famous and widely used, with over 12 million downloads per month (at the time of this writing).

Pedro A
  • 3,989
  • 3
  • 32
  • 56
  • Please note that normative documentation is [*ECMA-262*](http://ecma-international.org/ecma-262/8.0/), not MDN which is a public wiki that anyone can contribute to. The MDN article warns against using the built-in parser, so you should not recommend doing that. – RobG Jan 28 '18 at 01:18
  • How could I get `now` so that it would correspond to the `Date` created with the help of `ISO 8601`? I mean my problem is that I have to use `00.000Z` at the end, but then I am getting `now` with the help of `new Date().getTime()` which as far as I can notice does not care about local time. So what is an alternative way to get local `now`? – trafalgarLaww Jan 28 '18 at 10:16
  • Could you help me to tackle the problem in the chat, please? – trafalgarLaww Jan 28 '18 at 10:32
  • @trafalgarLaww I made a major edit in my answer. I apologize, I put wrong information in it before. Please disregard the old answer and re-read this one. Let me know if you need further help. I could, yes, help you in chat, but please consider simply editing your answer in a more clear way, specifying your exact problem, and this way not only I can help you more easily but perhaps others could help you faster. – Pedro A Jan 28 '18 at 15:53
1

There are many ways to create a Date, either passing a single string, single integer or multiple arguments. The best way depends on your particular circumstance.

By far the most robust way is to use the Date constructor with discrete values. If you wish to create a date for 18.02.09 12:00 then assuming it is YY.MM.DD HH:mm use:

var d = new Date(2018, 1, 9, 12);

Which will create a date for 9 February, 2018 at 12 noon local time, where "local" is determined from the host system timezone offset.

Passing strings to the Date constructor is strongly recommended against for the reasons expressed in answers to Why does Date.parse give incorrect results?, so don't use the built-in parser, it's unreliable and you can get unexpected results.

The string "2018-02-09T12:00:00.000Z" will be treated as UTC, so the Date created from it will be offset by the host local offset. Using UTC time differences will be different to local time differences where the host timezone offset changes for the two dates, e.g. where a daylight saving boundary is crossed.

So the "correct" or "best" way depends greatly on what you are trying to do, the input values and the outcome you wish to achieve. The bottom line is never use the built-in parser, always manually parse strings either with a bespoke function or use library.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • How could I get `now` so that it would correspond to the `Date` created with the help of `ISO 8601`? I mean my problem is that I have to use `00.000Z` at the end, but then I am getting `now` with the help of `new Date().getTime()` which as far as I can notice does not care about local time. So what is an alternative way to get local `now`? – trafalgarLaww Jan 28 '18 at 10:14
  • Could you help me to tackle the problem in the chat, please? – trafalgarLaww Jan 28 '18 at 10:30
  • @trafalgarLaww—Javascript Dates are always UTC, it calculates local dates using the host system timezone offset. If you want to format the local date as ISO 8601, then see [*Where can I find documentation on formatting a date in JavaScript?*](https://stackoverflow.com/questions/1056728/where-can-i-find-documentation-on-formatting-a-date-in-javascript) – RobG Jan 28 '18 at 11:27
  • @trafalgarLaww—I've added a comment to your OP. – RobG Jan 29 '18 at 07:19