Why does JavaScript interprete 1/1/0000 as 1/1/2000? - javascript

I encountered some strange behaviour, and while I don't really have an issue with it, I would like to know the reasoning behind it.
I wrote the following statements:
console.log(new Date("0000-1-1"));
console.log(new Date("0000-01-01"));
console.log(new Date("0000-01-01T00:00:00Z"));
console.log(new Date(0, 0, 1));
While all dates "appear" to be similar, and if you use normal days/months/years behave the same, it does not in this case.
The results are the following:
Sat Jan 01 2000 00:00:00 GMT+0100 (CET)
Sat Jan 01 0 01:00:00 GMT+0100 (CET)
Sat Jan 01 0 01:00:00 GMT+0100 (CET)
Mon Jan 01 1900 00:00:00 GMT+0100 (CET)
Which is quite interesting to me. I can agree with the last one, because the JavaScript spec clearly says the following:
year
Integer value representing the year. Values from 0 to 99 map to the years 1900 to 1999. See the example below.
I can also understand the second and third result, since this is depending on the RFC 2822. They do accept 4*DIGITS as a year, so 0000 should be the year 0 by the RFC spec (I didn't read it completely though).
It's only a bit weird that one of the Date constructors can be used for dates above 1900 while the other constructor allows dates from a wider range (RFC).
However, I do not understand the first result. Where does the year 2000 come from? I do understand that the date is not really an appropriate one, but shouldn't it return Invalid Date in stead of this date?

This is browser specific.
This is yet another area where JavaScript and browser inconsistency cause extra programmer pain. Some browsers will interpret all two digit years as 19xx, so new Date('1/1/49') gives January 1st, 1949, and new Date('1/1/50') gives January 1st, 1950. Others use 1950 as the "two digit year cutoff date", so new Date('1/1/49') gives January 1st, 2049, and new Date('1/1/50') gives January 1st, 1950.
— Two Digit Years in JavaScript - Chris Bristol
You have to bear in mind that the RFC document you've referenced was published in April 2001. The 1900s had only just ended. I guess in an attempt to modernise dates away from the 1900s, some browsers now map 0 to 49 as 2000 to 2049. 50, however, still gets mapped as 1950.
The article quoted above also goes on to give some test results:
Here is a brief summary of the results:
IE9: No two digit year cutoff found. Year 00 = 1900.
Chrome 24.0: Two digit years change between 49 and 50. Year 00 = 2000.
Opera: No two digit year cutoff found. Year 00 = 1900.
Firefox: No two digit year cutoff found. Year 00 = 1900.
Safari: Two digit years change between 49 and 50. Year 00 = 2000.
The article is quite dated now though, so I imagine the data for Opera and Firefox above may have changed.

Related

why new Date("Tue Apr 08 2008 00:00:00 GMT+0530").getMonth() is returning 3 [duplicate]

This question already has answers here:
why does javascript getMonth count from 0 and getDate count from 1?
(4 answers)
getMonth in javascript gives previous month
(6 answers)
Closed 5 years ago.
new Date("Tue Apr 08 2008 00:00:00 GMT+0530").getMonth() returns 3?
Why does this datetime format returns -1 month. Also can any one please tell me is this UTC timestamp or GMT or ISO. I am pretty confused. Any help is greatly appreciated.
The month field is 0 indexed :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
month
Integer value representing the month, beginning with 0 for
January to 11 for December.
getMonth() is returning the right date, it's just zero indexed, so Jan = 0, Dec = 11
new Date("Tue Apr 08 2008 00:00:00 GMT+0530").getMonth()
Also, ISO formatted dates look like this:
YYYY-MM-DDTHH:mm:ss.sssZ
If the Z is present, UTC is used, otherwise you can replace the Z with +hh:mm or -hh:mm to specify an offset from UTC.
Possibly because it is returning the month index from base 0.
January=0
Febuary=1
March=2
April =3
etc.
Just a guess though.

D3 time format skips isoWeek

When using d3.time.format(%Y%W) it doesn't give the expected output.
d3.time.format("%Y%W").parse("201553")
outputs
Mon Jan 04 2016
Although the first Monday of week number 53 in 2015 is Mon Dec 28 2015
So it seems like it parses to the next week.
Any ideas how to fix this to get the expected output.
The number of weeks is zero-based. d3.time.format defines a week number that is different from ISO 8601.
Check the documentation: https://github.com/d3/d3/wiki/Time-Formatting
%W - week number of the year (Monday as the first day of the week) as a decimal number [00,53].
It's the same for %U:
%U - week number of the year (Sunday as the first day of the week) as a decimal number [00,53].

Explain why Dec 31 2012 is week 53 and not week 1 (ISO-8601)

I'm trying to write a function in JavaScript that returns the week number for a given date and I'm testing my code against two functions I've found on the web, i.e.
https://web.archive.org/web/20150906081028/http://techblog.procurios.nl/k/n618/news/view/33796/14863/calculate-iso-8601-week-and-year-in-javascript.html
https://web.archive.org/web/20160402050000/http://www.epoch-calendar.com/support/getting_iso_week.html
I've tested 30,000 days starting from Jan 1 1970 and I got a few differences with the second source. The first kind of differences is where that source returns week zero for some cases, which is clearly wrong. Then for some other cases it return week 53, where my function returns week 1. These are the dates
1984, Dec 31
2012, Dec 31
2040, Dec 31
And they all look like this
Dec Jan
29 30 31 01 02 03 04 05 06 07 08 09 10
Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th
^^ ^^
according to ISO-8601
weeks start on Monday
first week of the year is the week with the first Thursday of that year
Jan 3 is the first Thursday of 2013, therefore Jan 3 is a day in week 1 (of 2013). And the start of week 1 (of 2013) is the Monday before that Thursday, which is Dec 31 2012.
Therefore Dec 31 2012 must be week 1.
However...
when I type 'what week is 31 december 2012' in Wolfram Alpha, it returns week 53
when I type '=WEEKNUM("2012-12-31")' in excel, it also returns week 53
Am I missing something? What bothers me is that it occurs on only so few dates (3 dates in 70 years or more)
Not everything uses ISO 8601; there are many differing definitions of "week number". You are correct in your interpretation - 31 Dec 2012 was indeed the start of ISO week 1 of 2013.
Demonstration using GNU's date(1) command on Linux:
$ date +%GW%V -d '2012-12-31'
2013W01
If you want to use the ISO definition in Excel, you have to specify return type 21:
=WEEKNUM("2012-12-31",21)
yields 1.

JavaScript incorrectly converting milliseconds to date?

I've noticed an issue with some data I'm processing (2000+ lines of data).
The problem is very strange: the code works fine! UNTIL a specific date is reached (in this case 01/08/2011) when JavaScript fails to generate the correct date?
So, to explain: I'm taking a string in the format of 'dd/mm/yyyy' and doing (which doesn't work):
var date = '01/08/2011'.split('/');
var milliseconds = new Date(date[2], parseInt(date[1]) - 1, date[0]).getTime(); => 1291161600000
new Date(1291161600000); => Wed Dec 01 2010 00:00:00 GMT+0000 (GMT)
...but yet that exact code works fine with any date before the 1st August 2011?
So try again with 29/07/2011...
var date = '29/07/2011'.split('/');
var milliseconds = new Date(date[2], parseInt(date[1]) - 1, date[0]).getTime(); => 1311894000000
new Date(1311894000000); => Fri Jul 29 2011 00:00:00 GMT+0100 (BST)
The only difference is the (GMT) and (BST) values returned, which suggests a locale issue. But why would that occur, and how can I fix the code to work around that?
Many thanks for any help you can give me.
You are doing octal!
Use a radix!
parseInt(date[1],10)
From the MDN Docs parseInt(string[, radix]):
If radix is undefined or 0, JavaScript assumes the following:
If the input string begins with "0x" or "0X", radix is 16 (hexadecimal).
If the input string begins with "0", radix is eight (octal). This feature is non-standard, and some implementations deliberately do not
support it (instead using the radix 10). For this reason always
specify a radix when using parseInt.
If the input string begins with any other value, the radix is 10 (decimal).

Possible return values for (new Date()).toDateString() in JavaScript?

The return value for (new Date()).toDateString() is "Mon Oct 08 2012". However I can't find ANY documentation anywhere for what the abbreviations for the rest of the days of the week and months are. Are they all just 3 character abbreviations? I'm trying to write a regex.
+1million points for someone who can find the documentation, or even the source code?
Three letter abbreviations with the first letter upper case.
Months: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
Days: Sun, Mon, Tue, Wed, Thu, Fri, Sat
However, you may want to look into Date.Parse() instead of using a regular expression to parse the date string, depending on what you're doing anyway.
EDIT: Beware that that Date.Parse() is fairly browser dependent. Check out Why does Date.parse give incorrect results?
It's just the standard English language abbreviation for days and months. Just the first 3 letters and the first one capitalized.
From the MDN:
Date instances refer to a specific point in time. Calling toString
will return the date formatted in a human readable form in American
English
It's not hard to find:
W3Schools: http://www.w3schools.com/jsref/jsref_todatestring.asp
Mozilla Developer Network: link
Microsoft Developer Network: link
As you can see, all of them converge, its the week day, the month name, both with 3 characters, day of month and full year.
The specification does not define the output of the string:
The contents of the String are implementation-dependent, but are intended to represent the "date" portion of the Date in the current time zone in a convenient, human-readable form.
This might change in the future, but for now, each browser/environment can produce a different output.

Categories