How does JavaScript's Date work? - javascript

Can someone explain me the output http://jsfiddle.net/mark69_fnd/NhuLe/ produces?
new Date('2012-07-01') == Sat Jun 30 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-07-09') == Sun Jul 08 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-07-10') == Mon Jul 09 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-07-31') == Mon Jul 30 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-1') == Wed Aug 01 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-9') == Thu Aug 09 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-10') == Thu Aug 09 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-31') == Thu Aug 30 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-09-1') == Sat Sep 01 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-09-9') == Sun Sep 09 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-09-10') == Sun Sep 09 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-12-09') == Sat Dec 08 2012 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2012-12-31') == Sun Dec 30 2012 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-01-01') == Mon Dec 31 2012 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-01-09') == Tue Jan 08 2013 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-02-09') == Fri Feb 08 2013 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-03-09') == Fri Mar 08 2013 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-04-09') == Mon Apr 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-05-09') == Wed May 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-06-09') == Sat Jun 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-07-09') == Mon Jul 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-08-09') == Thu Aug 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-09-09') == Sun Sep 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
I am interested to understand how it decides to compute the day. Please, note the difference between 2012-07-09, 2012-08-9 and 2013-08-09.
I ran it on Chrome.

This is a very interesting, and subtle, question.
The reason is that some of your dates are in the ISO-8601-like format defined in the specification, and so are parsed as GMT, but others are not, and so they fall back on non-standard date parsing, which appears to be (in Chrome) using local time instead.
The date string 2012-07-01 conforms to the format specified in Section 15.9.1.15, and so according to the rules of that section, it is parsed in timezone Z (GMT). Then you output it and it's output in local time, four hours or so earlier, and so the date changes as the original value (having no time part) is at midnight.
The date string 2012-08-1 does not conform to that format (it needs a 0 before the 1). This takes us out of the land of specified behavior. The Date constructor, when given a string, follows the same rules as Date.parse, which are defined in Section 15.9.4.2, which says amongst other things:
The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
(My emphasis)
The moral of this story is: Stick to specified formats. :-)
But a side note on that: The date/time format defined in the spec is relatively new (as of ES5, about three years ago). Prior to that, there was no defined date/time format that the Date constructor (or Date parse) was required to parse. It just had to be able to parse whatever Date#toString spat out, but what that was was implementation-specific. And older browsers will indeed fail to parse 2012-08-01. Although it's not specified, nearly all browsers (every one I've ever tested) will parse 2012/08/01, though. Of course, now I want to go back and see what time zone they use (and check whether they all use the same one)...

new Date('2012-07-01') means that you are providing date in *GMT 000*0 timezone.
But when it displays you the date it does the same in your browser timezone(which is GMT -400 in your case).
Thats is the reason that you see all the timings to be 20:00.

Related

rrule.js - Recurrence series changes time of day in time zone after Daylight Savings

I have what seems like a very common use case: I want to have a recurring event that occurs at the same time each day in a specific time zone (in the example below, 6:00 AM in the America/Denver time zone). I want this to recur at the same time of day after a change in Daylight Savings as before. Right now, it is changing by one hour after Daylight Savings, which seems to indicate that Daylight Savings is not being accounted for when the recurring datetimes are generated.
I have tried various configurations for the rrule as indicated in the documentation here and here. It says the time of day should be the same across Daylight Savings, but that is not what I am seeing.
Code sample
const rrule = new RRule({
freq: RRule.DAILY,
dtstart: new Date(Date.UTC(2022, 7, 18, 12, 0, 0)),
// tzid: 'America/Denver', // output is the same whether this is included or not
})
const datetimes = rrule.between(
new Date('2022-10-31'),
new Date('2022-11-10')
)
Try out the CodeSandbox. Should get similar results as long as you are in a time zone that has Daylight Savings and the between range includes a change in Daylight Savings.
Expected output
The time of day in America/Denver time zone should not change after Daylight Savings (i.e. recurrence should account for Daylight Savings):
Mon Oct 31 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Tue Nov 01 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Wed Nov 02 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Thu Nov 03 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Fri Nov 04 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Sat Nov 05 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Sun Nov 06 2022 06:00:00 GMT-0700 (Mountain Standard Time) <-- Daylight savings change
Mon Nov 07 2022 06:00:00 GMT-0700 (Mountain Standard Time)
Tue Nov 08 2022 06:00:00 GMT-0700 (Mountain Standard Time)
Wed Nov 09 2022 06:00:00 GMT-0700 (Mountain Standard Time)
^^
Actual output
The time of day in America/Denver time zone is changing from 6:00 to 5:00:
Mon Oct 31 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Tue Nov 01 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Wed Nov 02 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Thu Nov 03 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Fri Nov 04 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Sat Nov 05 2022 06:00:00 GMT-0600 (Mountain Daylight Time)
Sun Nov 06 2022 05:00:00 GMT-0700 (Mountain Standard Time) <-- Daylight savings change
Mon Nov 07 2022 05:00:00 GMT-0700 (Mountain Standard Time)
Tue Nov 08 2022 05:00:00 GMT-0700 (Mountain Standard Time)
Wed Nov 09 2022 05:00:00 GMT-0700 (Mountain Standard Time)
^^
I've opened an issue for this on GitHub, but I'm wondering if I'm just missing something. It seems like a common use case, so I would think I'd be able to find something out there about it. I did find a couple of SO questions about it here and here, but I'm already applying the solutions suggested.
Is this an actual bug in rrule or am I just missing something?
I had to dig very deep and surprisingly it seems like there is no bug. If you change your CodeSandbox to the following then it should work:
import { RRule } from "rrule";
import "./styles.css";
const rrule = new RRule({
freq: RRule.DAILY,
dtstart: new Date(Date.UTC(2022, 7 - 1, 18, 12, 0)), // See note 1
tzid: 'America/Denver',
})
const datetimes = rrule.between(
new Date('2022-10-31'),
new Date('2022-11-10')
)
const output = datetimes.map((d) => new Date( // See note 2
d.getUTCFullYear(),
d.getUTCMonth(),
d.getUTCDate(),
d.getUTCHours(),
d.getUTCMinutes(),
)).join('<br/>')
document.getElementById("app").innerHTML = output;
Notes:
The docs at https://github.com/jakubroztocil/rrule#timezone-support state that using new Date(2022, 7, ...) will produce unexpected timezone offsets. Instead use rrule's datetime function. Since this function currently is not working (see https://github.com/jakubroztocil/rrule/issues/551) we have to use new Date(Date.UTC(2022, 7 - 1, ...)) (which is excatly what the datetime function is doing).
The result will be a date in UTC which you have to interpret as a date in the timezone you specified in tzid. It seems very weird but it is stated in the docs at https://github.com/jakubroztocil/rrule#important-use-utc-dates that: Even though the given offset is Z (UTC), these are local times, not UTC times. Just to emphasize this my code example transforms the UTC dates to America/Denver dates by creating a new instance of Date using the UTC values (only works if your operating's system timezone is America/Denver).

Convert date in Javascript (luxon)

I am using luxon to convert the date:
console.log(DateTime.now('Sun Jan 23 2003 00:00:00 GMT+0200 (Eastern European Standard Time)').toISODate())
Now i get: 2022-04-07. But this is today's day, but i need to get this format from this: Sun Jan 23 2003 00:00:00 GMT+0200 (Eastern European Standard Time). How to get this using luxon library?
Try using console.log(DateTime.local('Sun Jan 23 2003 00:00:00 GMT+0200 (Eastern European Standard Time)').toISODate()).
By using DateTime.now(etc...), it automatically returns the current date.

JavaScript Date Manipulation (Insert Current Time in old Date)

I want to ask a question. Can we insert current Time in old Date?
Like this is a old date "Fri Nov 19 2021 00:00:00 GMT+0500 (Pakistan Standard Time)" and I want to convert it to something like this "Fri Nov 19 2021 (current Time right now) GMT+0500 (Pakistan Standard Time)".
Thanks in advance.
You can try using the setHours method, as in the following example:
const saveTime = new Date();
console.log(saveTime);
Tue Nov 23 2021 06:24:29 GMT-0500 (Cuba Standard Time)
saveTime.setHours(20,35,43)
console.log(saveTime);
Tue Nov 23 2021 20:35:43 GMT-0500 (Cuba Standard Time)

Wrong minutes and seconds in a JavaScript date before year 1925 [duplicate]

This question already has answers here:
Browsers, time zones, Chrome 67 Error (historic timezone changes)
(2 answers)
Closed 4 years ago.
I have an application which allows users to pick some time slots. By default the timeslots are empty, and my .NET back-end has default generated values of type DateTimeOffset, which by default are set to "0001-01-01T00:00:00+00:00".
Now, when I populate a date on the front-end with this value, it generates a date in the local time zone, but with wrong minutes and seconds. This happens only in Chrome. I'm not seeing this under Edge or Firefox.
console.log(new Date("2001-01-01T00:00:00+00:00").toString())
// Mon Jan 01 2001 02:00:00 GMT+0200 (Eastern European Standard Time)
console.log(new Date("1001-01-01T00:00:00+00:00").toString())
//Thu Jan 01 1001 02:02:04 GMT+0202 (Eastern European Standard Time)
console.log(new Date("1801-01-01T00:00:00+00:00").toString())
//Thu Jan 01 1801 02:02:04 GMT+0202 (Eastern European Standard Time)
console.log(new Date("1901-01-01T00:00:00+00:00").toString())
//Tue Jan 01 1901 02:02:04 GMT+0202 (Eastern European Standard Time)
console.log(new Date("1961-01-01T00:00:00+00:00").toString())
//Sun Jan 01 1961 03:00:00 GMT+0300 (Eastern European Standard Time)
console.log(new Date("1921-01-01T00:00:00+00:00").toString())
//Sat Jan 01 1921 02:02:04 GMT+0202 (Eastern European Standard Time)
console.log(new Date("1931-01-01T00:00:00+00:00").toString())
//Thu Jan 01 1931 03:00:00 GMT+0300 (Eastern European Standard Time)
console.log(new Date("1922-01-01T00:00:00+00:00").toString())
//Sun Jan 01 1922 02:02:04 GMT+0202 (Eastern European Standard Time)
console.log(new Date("1923-01-01T00:00:00+00:00").toString())
//Mon Jan 01 1923 02:02:04 GMT+0202 (Eastern European Standard Time)
console.log(new Date("1924-01-01T00:00:00+00:00").toString())
//Tue Jan 01 1924 02:02:04 GMT+0202 (Eastern European Standard Time)
console.log(new Date("1925-01-01T00:00:00+00:00").toString())
//Thu Jan 01 1925 02:00:00 GMT+0200 (Eastern European Standard Time)
As you can see, I played around with the date, to see before which date this happens, but the problem may not be the year 1925, just certain time before the current date. Does anyone know why this is happening?
Screenshot as requested
Prior to 1883 Time Zones were not standardized. If you check every year you'll notice that 1883 is "broken" with the additional minutes and 1884 is "fine". Chrome handles this transition very well - you'll notice the "problem" doesn't exist in Firefox.
new Date("1883-01-01T00:00:00+00:00")
Sun Dec 31 1882 16:07:02 GMT-0752 (Pacific Standard Time)
new Date("1884-01-01T00:00:00+00:00")
Mon Dec 31 1883 16:00:00 GMT-0800 (Pacific Standard Time)
In fact, you can track this down to November 18th, 1883.
new Date("1883-11-18T00:00:00+00:00")
Sat Nov 17 1883 16:07:02 GMT-0752 (Pacific Standard Time)
new Date("1883-11-19T00:00:00+00:00")
Sun Nov 18 1883 16:00:00 GMT-0800 (Pacific Standard Time)
Chrome tries very hard to match time, even going so far as to calculate the suspended DST of Ramadan in Egypt in 2010.
Read more here: https://www.huffingtonpost.com/quora/how-when-and-why-were-tim_b_5838042.html

Understanding UTC vs GMT Standard Time in JavaScript / node.js

I have some unit tests failing with errors like:
- "dateModified": "Fri Mar 06 2015 00:00:00 GMT+0000 (UTC)"
- "datePublished": "Fri Mar 06 2015 00:00:00 GMT+0000 (UTC)"
+ "dateModified": "Fri Mar 06 2015 00:00:00 GMT+0000 (GMT Standard Time)"
+ "datePublished": "Fri Mar 06 2015 00:00:00 GMT+0000 (GMT Standard Time)"
One set of results in from node 6.5.0 on Unix, the other node 6.5.0 on Windows.
This is odd, as I was under the impression that UTC was GMT.
Is UTC the same thing as GMT?
If not, what is the difference?
Is one preferable to the other?
Some further tests setting the TZ environment variable:
Before changing the timezone:
$ node
> new Date().toString()
'Fri Sep 02 2016 17:14:36 GMT+0100 (GMT Daylight Time)'
After changing the timezone:
$ $env:TZ='UTC'
$ node
> new Date().toString()
'Fri Sep 02 2016 16:15:34 GMT+0000 (GMT Standard Time)'

Categories