This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 6 years ago.
I feel like I am missing something here.
The Date.getDay() method is supposed to return a value from 0-6. 0 for Sunday and 6 for Saturday.
Now I have two dates, both are 'Sunday' which should return 0.
new Date('1990-11-11').getDay() // returns 6
new Date('2016-1-3').getDay() // returns 0
What is causing the discrepancy? I dare to question the validity of the .getDay() method, but I can't figure out what is going on.
EDIT
> new Date('1990-11-11')
Sat Nov 10 1990 17:00:00 GMT-0700 (MST)
> new Date('2016-01-03')
Sat Jan 02 2016 17:00:00 GMT-0700 (MST)
> new Date('2016-1-3') // they say this format is wrong, but it returns the right date
Sun Jan 03 2016 00:00:00 GMT-0700 (MST)
I don't understand what is going on. January 3rd is Sunday and November 11th 1990 is Sunday. Why is it saying Saturday?
The one that is wrong is the one that returns Sunday, and that must be because the format is incorrect. 1990-11-11 is interpreted as 00:00:00 on midnight of the 11th, UTC, which is 5pm on Saturday the 10th in your time zone.
If you use getUTCDay(), you should get 0 for both dates.
new Date('1990-11-11').getUTCDay() // returns 0
new Date('2016-01-03').getUTCDay() // returns 0
Certainly, your claim that 1990-11-11 is Sunday is true but you have to understand that JavaScript Date object:
Handles time as well as date
Is time zone aware
Is poorly designed and rather counter-intuitive
Your own tests illustrate this:
new Date('1990-11-11').getDay() // returns 6
> new Date('1990-11-11')
Sat Nov 10 1990 17:00:00 GMT-0700 (MST)
What happens is that constructor assumes local time or UTC depending on the syntax used:
Note: Where Date is called as a constructor with more than one
argument, the specifed arguments represent local time. If UTC is
desired, use new Date(Date.UTC(...)) with the same arguments.
Note: parsing of date strings with the Date constructor (and
Date.parse, they are equivalent) is strongly discouraged due to
browser differences and inconsistencies. Support for RFC 2822 format
strings is by convention only. Support for ISO 8601 formats differs in
that date-only strings (e.g. "1970-01-01") are treated as UTC, not
local.
... and your syntax makes it as UTC. But many others methods assume local time:
The getDay() method returns the day of the week for the specified date
according to local time, where 0 represents Sunday.
getDay returns day index (from 0 to 6), where 0 is Sunday.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay
Return value:
An integer number corresponding to the day of the week for the given date, according to local time: 0 for Sunday, 1 for Monday, 2 for Tuesday, and so on.
Update:
new Date constructor returns different time values for those dates.
new Date('2016-1-3')
==> Sun Jan 03 2016 00:00:00 GMT+0100 (CET)
new Date('1990-11-11')
==> Sun Nov 11 1990 01:00:00 GMT+0100 (CET)
And for some reason, the first one gets interpreted as Saturday on your machine.
Sorry for not being able to help out more
Update2:
Using two digits for month/day should standardize the results.
Example:
(new Date('2016-01-03')).getDay() ==> 0
Related
This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 2 years ago.
Came across this one tonight and thought I would throw it out there to see if anybody had a rational and clear explanation on what's going on.
I've declared two JavaScript date objects and passed in date strings to the constructor (same date).
In the first variable I have been explicit with the time and added 00:00.
In the second variable I have omitted the time (assuming that it would be midnight).
I've wrapped everything in a Self-Invoking Function but this has no bearing on the outcome.
I'm in GMT so I've used a date that is in BST (GMT+1).
(function() {
'use strict';
let a = new Date("2020-06-05 00:00");
let b = new Date("2020-06-05");
console.log(a);
console.log(b);
console.log(JSON.stringify(a));
console.log(JSON.stringify(b));
})();
I would have expected Fri Jun 05 2020 00:00:00 GMT+0100 (British Summer Time) on both cases but the second variable without the explicit 00:00 has been set to Fri Jun 05 2020 01:00:00 GMT+0100.
Any explanations?
It appears that a date inside BST (+1) without a time assumes it's +1.
Scenario doesn't happen with new Date("2020-01-05"); for example. This is outside BST and therefore +0.
Fri Jun 05 2020 00:00:00 GMT+0100 (British Summer Time)
Fri Jun 05 2020 01:00:00 GMT+0100 (British Summer Time)
"2020-06-04T23:00:00.000Z"
"2020-06-05T00:00:00.000Z"
Due to the ECMA specs:
ECMA-262 Date(value) constructor specs
Date.parse
If the String conforms to the Date Time String Format, substitute values take the place of absent format elements. When the MM or DD elements are absent, "01" is used. When the HH, mm, or ss elements are absent, "00" is used. When the sss element is absent, "000" is used. When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
According to ECMA specs:
Date only forms without timezone are interpreted as UTC.
Date-Time without timezone are interpreted as local time.
Generally you are better off just using the full ISO-like form with timezone attached. But since these are spec-compliant, if you always keep it under control it's safe to depend on this behavior, albeit it might get confusing sometimes for both you and others, especially when it comes to server-side code and DB storage.
I'm using method getDay() from Date() to get day of the week, then I notice that the same Date without time returns me a different day of the week
new Date().getDay()
this first one returns me 3
new Date('2017-09-27').getDay()
this one returns me 2
Comparing these results with some friends I notice that almost everyone had different results, even worse, some people really got day 26 when the date 27 was written
I'm almost sure this problem is caused by timezone issues but I can't find how get accurate results
The reason is when you pass the date 2017-09-27 into the date method you have not passed a timezone in. Look at the results below:
> new Date()
Wed Sep 27 2017 12:58:39 GMT-0700 (PDT)
> new Date('2017-09-27')
Tue Sep 26 2017 17:00:00 GMT-0700 (PDT)
You can pass your time zone in for example in PDT (GMT-08:00)
> new Date('2017-09-27 GMT-08:00')
Wed Sep 27 2017 01:00:00 GMT-0700 (PDT)
Or you can use a library like moment.
This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 5 years ago.
These are my two codes:
var date1 = new Date('2017-04-23');
var date2 = new Date('April 23, 2017');
console.log(date1);
console.log(date2);
this is the results:
Sat Apr 22 2017 17:00:00 GMT-0700 (PDT)
Sun Apr 23 2017 00:00:00 GMT-0700 (PDT)
why is date1 showing as the 22nd at 17:00?
JavaScript's Date parsing behavior is somewhat unreliable. It seems that when you give it an ISO 8601 string such as `"2017-04-23" it interprets the date as being in your own timezone, but when you give it an arbitrary string, it will interpret it as a UTC date.
Since you are in the GMT-7 timezone, the 22nd at 17:00 is the 23rd at 00:00 in UTC, and when you print out a date object, it will always print out the UTC date and not the localized date.
So, in summary, both dates are getting set to the 23rd at 00:00, but in different timezones. The first is being set to Apr 23 00:00 UTC-7 and the second one is being set to Apr 23 00:00 UTC.
It might be a good idea to always explicitly set a timezone in order to avoid this ambiguity.
I get dates from the database in this format:
yyyy-mm-dd
When I create a javascript Date object using this string, it builds a day before the date.
You can test this in your console:
var d = new Date("2015-02-01");
d
You will get January 31st! I've tested many theories, but none answer the question.
The day is not zero-based, otherwise it would give Feb 00, not Jan 31
It's not performing a math equation, subtracting the day from the month and/or year
Date(2015-02-01) = Wed Dec 31 1969
Date("2015-01") = Wed Dec 31 2014
It is not confusing the day for the month
Date("2015-08-02") = Sat Aug 01 2015
If this were true the date would be Feb 08 2015
If you create a Date using a different format, it works fine
Date("02/01/2015") = Feb 1st, 2015
My conclusion is that js does this purposefully. I have tried researching 'why' but can't find an explanation. Why does js build dates this way, but only with this format? Is there a way around it, or do I have to build the Date, then set it to the next day?
PS: "How to change the format of the date from the db" is not what I'm asking, and that is why I'm not putting any db info here.
Some browsers parse a partial date string as UTC and some as a local time,
so when you read it the localized time may differ from one browser to another
by the time zone offset.
You can force the Date to be UTC and add the local offset if you
want the time to be guaranteed local:
1. set UTC time:
var D= new Date("2015-02-01"+'T00:00:00Z');
2. adjust for local:
D.setMinutes(D.getMinutes()+D.getTimezoneOffset());
value of D: (local Date)
Sun Feb 01 2015 00:00:00 GMT-0500 (Eastern Standard Time)
Offset will be whatever is local time.
Some differences between browsers when time zone is not specified in a parsed string:
(tested on Eastern Standard Time location)
(new Date("2015-02-01T00:00:00")).toUTCString();
Firefox 35: Sun, 01 Feb 2015 05:00:00 GMT
Chrome 40: Sun, 01 Feb 2015 00:00:00 GMT
Opera 27: Sun, 01 Feb 2015 00:00:00 GMT
IE 11: Sun, 01 Feb 2015 05:00:00 GMT
IE and Firefox set the Date as if it was local, Chrome and Opera as if it was UTC.
In javascript, Date objects are internally represented as the number of milliseconds since Jan 1st 1970 00:00:00 UTC. So instead of thinking of it as a "date" in the normal sense, try thinking of a Date object as a "point in time" represented by an integer number (without timezone).
When constructing your Date object using a string, you are actually just calling the parse function. Most date time formats (including ISO 8601) allow you to reduce the precision of a date string.
For reduced precision, any number of values may be dropped from any
of the date and time representations, but in the order from the least
to the most significant.
e.g. 2015-02-01 would represent the day February 1st 2015.
This causes a dilemma for javascript because a Date object is always accurate to the millisecond. Javascript cannot store a reduced accuracy date since it is just an integer of milliseconds since 1st Jan 1970. So it does the next best thing which is to assume a time of midnight (00:00:00) if not specified, and a timezone of UTC if not specified.
All valid javascript implementations should give the same result for this:
var d = new Date("2015-02-01");
alert(d.getTime());
1422748800000
The out-by-1-day issue comes when outputting the date either to some (often unclear) debugger or using the getter methods because the local timezone is used. In a browser, that will be your operating systems timezone. Anyone "west" of Greenwich Mean Time may see this problem because they have a negative UTC offset. Please note there are UTC equivalent functions too which use the UTC timezone, if you are really just interested in representing a date rather than a point in time.
a = new Date('09-01-2013')
//Sun Sep 01 2013 00:00:00 GMT-0400 (EDT)
b = new Date('2013-09-01')
//Sat Aug 31 2013 20:00:00 GMT-0400 (EDT)
b < a
//true
I did this in the Node.js repl, v0.10.12
Why are the dates different based on the form of the dateString?
I can't see how this is timezone related, since both dates are displayed in local timezone and their values are clearly not equivalent.
The problem is that new Date('09-01-2013') and new Date('2013-09-01') use different formats/standards and as such are parsed differently.
new Date('09-01-2013') is parsed as you would expect and results in a midnight time (in your local time zone). However, new Date('2013-09-01') is parsed as an ISO-8601 date at UTC midnight, UTC midnight is then converted to your local timezone when displayed (in this case EDT which is reflected in the 20:00:00, a 4 hour difference).
Conclusion: use YYYY/MM/DD to avoid headaches.