Why does Date accept negative values?
As per MDN
"Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC."
Then why does it accept negative values ?
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
new Date('0000', '00', '-1'); // "1899-12-30T05:00:00.000Z"
new Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
new Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
What is happening ?
Update
For some positive values , the year begins from 1900
new Date(100); // "1970-01-01T00:00:00.100Z" // it says 100Z
new Date(0100); // "1970-01-01T00:00:00.064Z" // it says 64Z
new Date("0006","06","06"); // "1906-07-06T04:00:00.000Z"
Also note that, in the last one, the date is shown as 4 which is wrong.
I suspect this is some sort of Y2K bug ?!!
javascript
add a comment |
As per MDN
"Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC."
Then why does it accept negative values ?
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
new Date('0000', '00', '-1'); // "1899-12-30T05:00:00.000Z"
new Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
new Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
What is happening ?
Update
For some positive values , the year begins from 1900
new Date(100); // "1970-01-01T00:00:00.100Z" // it says 100Z
new Date(0100); // "1970-01-01T00:00:00.064Z" // it says 64Z
new Date("0006","06","06"); // "1906-07-06T04:00:00.000Z"
Also note that, in the last one, the date is shown as 4 which is wrong.
I suspect this is some sort of Y2K bug ?!!
javascript
1
@mplungjan note the word since
– TrojanByAccident
Dec 27 '16 at 7:28
Note that new Date(0) is 1970 (with relevant TZ)
– mplungjan
Dec 27 '16 at 7:34
@mplungjan does this mean there is a way to represent a time in BC ?
– Flying Gambit
Dec 27 '16 at 7:35
@FlyingGambit Gregorian calendar can be "reverse extended" to BC dates, but it will cease to be historically accurate long before that. Jesus did not invent the Gregorian calendar.
– Sheepy
Dec 27 '16 at 10:44
@TrojanByAccident, this is the number of milliseconds that is calculated since the epoch. Here the term since give a direction in time. So positive will be after, negative will be before. (this is how I understand it)
– AxelH
Dec 27 '16 at 12:56
add a comment |
As per MDN
"Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC."
Then why does it accept negative values ?
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
new Date('0000', '00', '-1'); // "1899-12-30T05:00:00.000Z"
new Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
new Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
What is happening ?
Update
For some positive values , the year begins from 1900
new Date(100); // "1970-01-01T00:00:00.100Z" // it says 100Z
new Date(0100); // "1970-01-01T00:00:00.064Z" // it says 64Z
new Date("0006","06","06"); // "1906-07-06T04:00:00.000Z"
Also note that, in the last one, the date is shown as 4 which is wrong.
I suspect this is some sort of Y2K bug ?!!
javascript
As per MDN
"Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC."
Then why does it accept negative values ?
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
new Date('0000', '00', '-1'); // "1899-12-30T05:00:00.000Z"
new Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
new Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
What is happening ?
Update
For some positive values , the year begins from 1900
new Date(100); // "1970-01-01T00:00:00.100Z" // it says 100Z
new Date(0100); // "1970-01-01T00:00:00.064Z" // it says 64Z
new Date("0006","06","06"); // "1906-07-06T04:00:00.000Z"
Also note that, in the last one, the date is shown as 4 which is wrong.
I suspect this is some sort of Y2K bug ?!!
javascript
javascript
edited Dec 27 '16 at 8:02
Flying Gambit
asked Dec 27 '16 at 7:24
Flying GambitFlying Gambit
738724
738724
1
@mplungjan note the word since
– TrojanByAccident
Dec 27 '16 at 7:28
Note that new Date(0) is 1970 (with relevant TZ)
– mplungjan
Dec 27 '16 at 7:34
@mplungjan does this mean there is a way to represent a time in BC ?
– Flying Gambit
Dec 27 '16 at 7:35
@FlyingGambit Gregorian calendar can be "reverse extended" to BC dates, but it will cease to be historically accurate long before that. Jesus did not invent the Gregorian calendar.
– Sheepy
Dec 27 '16 at 10:44
@TrojanByAccident, this is the number of milliseconds that is calculated since the epoch. Here the term since give a direction in time. So positive will be after, negative will be before. (this is how I understand it)
– AxelH
Dec 27 '16 at 12:56
add a comment |
1
@mplungjan note the word since
– TrojanByAccident
Dec 27 '16 at 7:28
Note that new Date(0) is 1970 (with relevant TZ)
– mplungjan
Dec 27 '16 at 7:34
@mplungjan does this mean there is a way to represent a time in BC ?
– Flying Gambit
Dec 27 '16 at 7:35
@FlyingGambit Gregorian calendar can be "reverse extended" to BC dates, but it will cease to be historically accurate long before that. Jesus did not invent the Gregorian calendar.
– Sheepy
Dec 27 '16 at 10:44
@TrojanByAccident, this is the number of milliseconds that is calculated since the epoch. Here the term since give a direction in time. So positive will be after, negative will be before. (this is how I understand it)
– AxelH
Dec 27 '16 at 12:56
1
1
@mplungjan note the word since
– TrojanByAccident
Dec 27 '16 at 7:28
@mplungjan note the word since
– TrojanByAccident
Dec 27 '16 at 7:28
Note that new Date(0) is 1970 (with relevant TZ)
– mplungjan
Dec 27 '16 at 7:34
Note that new Date(0) is 1970 (with relevant TZ)
– mplungjan
Dec 27 '16 at 7:34
@mplungjan does this mean there is a way to represent a time in BC ?
– Flying Gambit
Dec 27 '16 at 7:35
@mplungjan does this mean there is a way to represent a time in BC ?
– Flying Gambit
Dec 27 '16 at 7:35
@FlyingGambit Gregorian calendar can be "reverse extended" to BC dates, but it will cease to be historically accurate long before that. Jesus did not invent the Gregorian calendar.
– Sheepy
Dec 27 '16 at 10:44
@FlyingGambit Gregorian calendar can be "reverse extended" to BC dates, but it will cease to be historically accurate long before that. Jesus did not invent the Gregorian calendar.
– Sheepy
Dec 27 '16 at 10:44
@TrojanByAccident, this is the number of milliseconds that is calculated since the epoch. Here the term since give a direction in time. So positive will be after, negative will be before. (this is how I understand it)
– AxelH
Dec 27 '16 at 12:56
@TrojanByAccident, this is the number of milliseconds that is calculated since the epoch. Here the term since give a direction in time. So positive will be after, negative will be before. (this is how I understand it)
– AxelH
Dec 27 '16 at 12:56
add a comment |
4 Answers
4
active
oldest
votes
This is hard and inconsistent, yes. The JavaScript Date object was based on the one in Java 1.0, which is so bad that Java redesigned a whole new package.
JavaScript is not so lucky.
- Date is "based on" unix eopch because of how it is defined. It's internal details.
1st Jan 1970
is the actual time of this baseline.since
is the direction of the timestamp value: forward for +ve, backward for -ve.
Externally, the Date constructor has several different usages, based on parameters:
Zero parameters = current time
new Date() // Current datetime. Every tutorial should teach this.
The time is absolute, but 'displayed' timezone may be UTC or local.
For simplicity, this answer will use only UTC. Keep timezone in mind when you test.
One numeric parameter = timestamp @ 1970
new Date(0) // 0ms from 1970-01-01T00:00:00Z.
new Date(100) // 100ms from 1970 baseline.
new Date(-10) // -10ms from 1970 baseline.
One string parameter = iso date string
new Date('000') // Short years are invalid, need at least four digits.
new Date('0000') // 0000-01-01. Valid because there are four digits.
new Date('1900') // 1900-01-01.
new Date('1900-01-01') // Same as above.
new Date('1900-01-01T00:00:00') // Same as above.
new Date('-000001') // 2 BC, see below. Yes you need all those zeros.
Two or more parameters = year, month, and so on @ 1900 or 0000
new Date(0,0) // 1900-01-01T00:00:00Z.
new Date(0,0,1) // Same as above. Date is 1 based.
new Date(0,0,0) // 1 day before 1900 = 1899-12-31.
new Date(0,-1) // 1 month before 1900 = 1899-12-01.
new Date(0,-1,0) // 1 month and 1 day before 1900 = 1899-11-30.
new Date(0,-1,-1) // 1 month and *2* days before 1900 = 1899-11-29.
new Date('0','1') // 1900-02-01. Two+ params always cast to year and month.
new Date(100,0) // 0100-01-01. Year > 99 use year 0 not 1900.
new Date(1900,0) // 1900-01-01. Same as new Date(0,0). So intuitive!
Negative year = BC
new Date(-1,0) // 1 year before 0000-01-01 = 1 year before 1 BC = 2 BC.
new Date(-1,0,-1) // 2 days before 2 BC. Fun, yes? I'll leave this as an exercise.
There is no 0 AC. There is 1 AC and the year before it is 1 BC. Year 0 is 1 BC by convention.
2 BC is displayed as year
"-000001"
.
The extra zeros are required because it is outside normal range (0000 to 9999).
If younew Date(12345,0)
you will get"+012345-01-01"
, too.
Of course, the Gregorian calendar, adopted as late as 1923 in Europe, will cease to be meaningful long before we reach BC.
In fact, scholars accept that Jesus wasn't born in 1 BC.
But with the stars and the Earth moving at this scale, calendar is the least of your worries.
The remaining given code are just variations of these cases. For example:
new Date(0100) // One number = epoch. 0100 (octal) = 64ms since 1970
new Date('0100') // One string = iso = 0100-01-01.
new Date(-9999, 99, 99) // 9999 years before BC 1 and then add 99 months and 98 days
Hope you had some fun time. Please don't forget to vote up. :)
To stay sane, keep all dates in ISO 8601 and use the string constructor.
And if you need to handle timezone, keep all datetimes in UTC.
Just a question - why doesnew Date('00000100')
report the same asnew Date(0100)
?
– TrojanByAccident
Dec 27 '16 at 22:57
@TrojanByAccident I tested in Firefox 50 and Edge 38, both reports "Invalid Date" fornew Date("00000100")
, so don't do that. Chrome 55 parse it asnew Date("0100")
notnew Date(0100)
(type matters).
– Sheepy
Dec 28 '16 at 5:05
Interesting. Testing in Chrome 55,new Date('00000100')
reports as Fri Jan 01 100, andnew Date(00000100)
reports as Wed Dec 31 1969
– TrojanByAccident
Dec 28 '16 at 5:29
add a comment |
Well, firstly, you're passing in string instead of an integer, so that might have something to do with your issues here.
Check this out, it explains negative dates quite nicely, and there is an explanation for your exact example.
I am unable to open that link due to web security issues, however , can you explain it in brief so that even if the link breaks in future, we still have some concrete answer
– Flying Gambit
Dec 27 '16 at 7:37
I really don't think we're allowed to just copy paste someone elses blog post on the topic
– darryn.ten
Dec 27 '16 at 7:39
2
You could always quote it. I say this because I can't open that link either (just infinite loading icon)
– Jhecht
Dec 27 '16 at 7:41
3
@darryn.ten you can sumarise the ideas or copy small pieces that are relevant. As long as you link to the source it is usually considered OK. As it stands your post could be flagged as a link only answer
– K Scandrett
Dec 27 '16 at 7:43
@darryn.ten That explains hownew Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
works but not the rest, especiallynew Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
– Flying Gambit
Dec 27 '16 at 8:28
|
show 3 more comments
Then why does it accept negative values ?
You are confusing the description of how the data is stored internally with the arguments that the constructor function takes.
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
No, for the above reason. Nothing stops the year, month or day from being negative. You just end up adding a negative number to something.
Also note that, in the last one, the date is shown as 4 which is wrong.
Numbers which start with a 0
are expressed in octal, not decimal. 0100 === 64
.
add a comment |
Please have a look at the documentation
Year: Values from 0 to 99 map to the years 1900 to 1999
- 1970 with appropriate timezone: new Date(0); // int MS since 1970
- 1900 (or 1899 with applied timezone): new Date(0,0) or new Date(0,0,1) - date is 1 based, month and year are 0 based
- 1899: new Date(0,0,-1)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f41340836%2fwhy-does-date-accept-negative-values%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is hard and inconsistent, yes. The JavaScript Date object was based on the one in Java 1.0, which is so bad that Java redesigned a whole new package.
JavaScript is not so lucky.
- Date is "based on" unix eopch because of how it is defined. It's internal details.
1st Jan 1970
is the actual time of this baseline.since
is the direction of the timestamp value: forward for +ve, backward for -ve.
Externally, the Date constructor has several different usages, based on parameters:
Zero parameters = current time
new Date() // Current datetime. Every tutorial should teach this.
The time is absolute, but 'displayed' timezone may be UTC or local.
For simplicity, this answer will use only UTC. Keep timezone in mind when you test.
One numeric parameter = timestamp @ 1970
new Date(0) // 0ms from 1970-01-01T00:00:00Z.
new Date(100) // 100ms from 1970 baseline.
new Date(-10) // -10ms from 1970 baseline.
One string parameter = iso date string
new Date('000') // Short years are invalid, need at least four digits.
new Date('0000') // 0000-01-01. Valid because there are four digits.
new Date('1900') // 1900-01-01.
new Date('1900-01-01') // Same as above.
new Date('1900-01-01T00:00:00') // Same as above.
new Date('-000001') // 2 BC, see below. Yes you need all those zeros.
Two or more parameters = year, month, and so on @ 1900 or 0000
new Date(0,0) // 1900-01-01T00:00:00Z.
new Date(0,0,1) // Same as above. Date is 1 based.
new Date(0,0,0) // 1 day before 1900 = 1899-12-31.
new Date(0,-1) // 1 month before 1900 = 1899-12-01.
new Date(0,-1,0) // 1 month and 1 day before 1900 = 1899-11-30.
new Date(0,-1,-1) // 1 month and *2* days before 1900 = 1899-11-29.
new Date('0','1') // 1900-02-01. Two+ params always cast to year and month.
new Date(100,0) // 0100-01-01. Year > 99 use year 0 not 1900.
new Date(1900,0) // 1900-01-01. Same as new Date(0,0). So intuitive!
Negative year = BC
new Date(-1,0) // 1 year before 0000-01-01 = 1 year before 1 BC = 2 BC.
new Date(-1,0,-1) // 2 days before 2 BC. Fun, yes? I'll leave this as an exercise.
There is no 0 AC. There is 1 AC and the year before it is 1 BC. Year 0 is 1 BC by convention.
2 BC is displayed as year
"-000001"
.
The extra zeros are required because it is outside normal range (0000 to 9999).
If younew Date(12345,0)
you will get"+012345-01-01"
, too.
Of course, the Gregorian calendar, adopted as late as 1923 in Europe, will cease to be meaningful long before we reach BC.
In fact, scholars accept that Jesus wasn't born in 1 BC.
But with the stars and the Earth moving at this scale, calendar is the least of your worries.
The remaining given code are just variations of these cases. For example:
new Date(0100) // One number = epoch. 0100 (octal) = 64ms since 1970
new Date('0100') // One string = iso = 0100-01-01.
new Date(-9999, 99, 99) // 9999 years before BC 1 and then add 99 months and 98 days
Hope you had some fun time. Please don't forget to vote up. :)
To stay sane, keep all dates in ISO 8601 and use the string constructor.
And if you need to handle timezone, keep all datetimes in UTC.
Just a question - why doesnew Date('00000100')
report the same asnew Date(0100)
?
– TrojanByAccident
Dec 27 '16 at 22:57
@TrojanByAccident I tested in Firefox 50 and Edge 38, both reports "Invalid Date" fornew Date("00000100")
, so don't do that. Chrome 55 parse it asnew Date("0100")
notnew Date(0100)
(type matters).
– Sheepy
Dec 28 '16 at 5:05
Interesting. Testing in Chrome 55,new Date('00000100')
reports as Fri Jan 01 100, andnew Date(00000100)
reports as Wed Dec 31 1969
– TrojanByAccident
Dec 28 '16 at 5:29
add a comment |
This is hard and inconsistent, yes. The JavaScript Date object was based on the one in Java 1.0, which is so bad that Java redesigned a whole new package.
JavaScript is not so lucky.
- Date is "based on" unix eopch because of how it is defined. It's internal details.
1st Jan 1970
is the actual time of this baseline.since
is the direction of the timestamp value: forward for +ve, backward for -ve.
Externally, the Date constructor has several different usages, based on parameters:
Zero parameters = current time
new Date() // Current datetime. Every tutorial should teach this.
The time is absolute, but 'displayed' timezone may be UTC or local.
For simplicity, this answer will use only UTC. Keep timezone in mind when you test.
One numeric parameter = timestamp @ 1970
new Date(0) // 0ms from 1970-01-01T00:00:00Z.
new Date(100) // 100ms from 1970 baseline.
new Date(-10) // -10ms from 1970 baseline.
One string parameter = iso date string
new Date('000') // Short years are invalid, need at least four digits.
new Date('0000') // 0000-01-01. Valid because there are four digits.
new Date('1900') // 1900-01-01.
new Date('1900-01-01') // Same as above.
new Date('1900-01-01T00:00:00') // Same as above.
new Date('-000001') // 2 BC, see below. Yes you need all those zeros.
Two or more parameters = year, month, and so on @ 1900 or 0000
new Date(0,0) // 1900-01-01T00:00:00Z.
new Date(0,0,1) // Same as above. Date is 1 based.
new Date(0,0,0) // 1 day before 1900 = 1899-12-31.
new Date(0,-1) // 1 month before 1900 = 1899-12-01.
new Date(0,-1,0) // 1 month and 1 day before 1900 = 1899-11-30.
new Date(0,-1,-1) // 1 month and *2* days before 1900 = 1899-11-29.
new Date('0','1') // 1900-02-01. Two+ params always cast to year and month.
new Date(100,0) // 0100-01-01. Year > 99 use year 0 not 1900.
new Date(1900,0) // 1900-01-01. Same as new Date(0,0). So intuitive!
Negative year = BC
new Date(-1,0) // 1 year before 0000-01-01 = 1 year before 1 BC = 2 BC.
new Date(-1,0,-1) // 2 days before 2 BC. Fun, yes? I'll leave this as an exercise.
There is no 0 AC. There is 1 AC and the year before it is 1 BC. Year 0 is 1 BC by convention.
2 BC is displayed as year
"-000001"
.
The extra zeros are required because it is outside normal range (0000 to 9999).
If younew Date(12345,0)
you will get"+012345-01-01"
, too.
Of course, the Gregorian calendar, adopted as late as 1923 in Europe, will cease to be meaningful long before we reach BC.
In fact, scholars accept that Jesus wasn't born in 1 BC.
But with the stars and the Earth moving at this scale, calendar is the least of your worries.
The remaining given code are just variations of these cases. For example:
new Date(0100) // One number = epoch. 0100 (octal) = 64ms since 1970
new Date('0100') // One string = iso = 0100-01-01.
new Date(-9999, 99, 99) // 9999 years before BC 1 and then add 99 months and 98 days
Hope you had some fun time. Please don't forget to vote up. :)
To stay sane, keep all dates in ISO 8601 and use the string constructor.
And if you need to handle timezone, keep all datetimes in UTC.
Just a question - why doesnew Date('00000100')
report the same asnew Date(0100)
?
– TrojanByAccident
Dec 27 '16 at 22:57
@TrojanByAccident I tested in Firefox 50 and Edge 38, both reports "Invalid Date" fornew Date("00000100")
, so don't do that. Chrome 55 parse it asnew Date("0100")
notnew Date(0100)
(type matters).
– Sheepy
Dec 28 '16 at 5:05
Interesting. Testing in Chrome 55,new Date('00000100')
reports as Fri Jan 01 100, andnew Date(00000100)
reports as Wed Dec 31 1969
– TrojanByAccident
Dec 28 '16 at 5:29
add a comment |
This is hard and inconsistent, yes. The JavaScript Date object was based on the one in Java 1.0, which is so bad that Java redesigned a whole new package.
JavaScript is not so lucky.
- Date is "based on" unix eopch because of how it is defined. It's internal details.
1st Jan 1970
is the actual time of this baseline.since
is the direction of the timestamp value: forward for +ve, backward for -ve.
Externally, the Date constructor has several different usages, based on parameters:
Zero parameters = current time
new Date() // Current datetime. Every tutorial should teach this.
The time is absolute, but 'displayed' timezone may be UTC or local.
For simplicity, this answer will use only UTC. Keep timezone in mind when you test.
One numeric parameter = timestamp @ 1970
new Date(0) // 0ms from 1970-01-01T00:00:00Z.
new Date(100) // 100ms from 1970 baseline.
new Date(-10) // -10ms from 1970 baseline.
One string parameter = iso date string
new Date('000') // Short years are invalid, need at least four digits.
new Date('0000') // 0000-01-01. Valid because there are four digits.
new Date('1900') // 1900-01-01.
new Date('1900-01-01') // Same as above.
new Date('1900-01-01T00:00:00') // Same as above.
new Date('-000001') // 2 BC, see below. Yes you need all those zeros.
Two or more parameters = year, month, and so on @ 1900 or 0000
new Date(0,0) // 1900-01-01T00:00:00Z.
new Date(0,0,1) // Same as above. Date is 1 based.
new Date(0,0,0) // 1 day before 1900 = 1899-12-31.
new Date(0,-1) // 1 month before 1900 = 1899-12-01.
new Date(0,-1,0) // 1 month and 1 day before 1900 = 1899-11-30.
new Date(0,-1,-1) // 1 month and *2* days before 1900 = 1899-11-29.
new Date('0','1') // 1900-02-01. Two+ params always cast to year and month.
new Date(100,0) // 0100-01-01. Year > 99 use year 0 not 1900.
new Date(1900,0) // 1900-01-01. Same as new Date(0,0). So intuitive!
Negative year = BC
new Date(-1,0) // 1 year before 0000-01-01 = 1 year before 1 BC = 2 BC.
new Date(-1,0,-1) // 2 days before 2 BC. Fun, yes? I'll leave this as an exercise.
There is no 0 AC. There is 1 AC and the year before it is 1 BC. Year 0 is 1 BC by convention.
2 BC is displayed as year
"-000001"
.
The extra zeros are required because it is outside normal range (0000 to 9999).
If younew Date(12345,0)
you will get"+012345-01-01"
, too.
Of course, the Gregorian calendar, adopted as late as 1923 in Europe, will cease to be meaningful long before we reach BC.
In fact, scholars accept that Jesus wasn't born in 1 BC.
But with the stars and the Earth moving at this scale, calendar is the least of your worries.
The remaining given code are just variations of these cases. For example:
new Date(0100) // One number = epoch. 0100 (octal) = 64ms since 1970
new Date('0100') // One string = iso = 0100-01-01.
new Date(-9999, 99, 99) // 9999 years before BC 1 and then add 99 months and 98 days
Hope you had some fun time. Please don't forget to vote up. :)
To stay sane, keep all dates in ISO 8601 and use the string constructor.
And if you need to handle timezone, keep all datetimes in UTC.
This is hard and inconsistent, yes. The JavaScript Date object was based on the one in Java 1.0, which is so bad that Java redesigned a whole new package.
JavaScript is not so lucky.
- Date is "based on" unix eopch because of how it is defined. It's internal details.
1st Jan 1970
is the actual time of this baseline.since
is the direction of the timestamp value: forward for +ve, backward for -ve.
Externally, the Date constructor has several different usages, based on parameters:
Zero parameters = current time
new Date() // Current datetime. Every tutorial should teach this.
The time is absolute, but 'displayed' timezone may be UTC or local.
For simplicity, this answer will use only UTC. Keep timezone in mind when you test.
One numeric parameter = timestamp @ 1970
new Date(0) // 0ms from 1970-01-01T00:00:00Z.
new Date(100) // 100ms from 1970 baseline.
new Date(-10) // -10ms from 1970 baseline.
One string parameter = iso date string
new Date('000') // Short years are invalid, need at least four digits.
new Date('0000') // 0000-01-01. Valid because there are four digits.
new Date('1900') // 1900-01-01.
new Date('1900-01-01') // Same as above.
new Date('1900-01-01T00:00:00') // Same as above.
new Date('-000001') // 2 BC, see below. Yes you need all those zeros.
Two or more parameters = year, month, and so on @ 1900 or 0000
new Date(0,0) // 1900-01-01T00:00:00Z.
new Date(0,0,1) // Same as above. Date is 1 based.
new Date(0,0,0) // 1 day before 1900 = 1899-12-31.
new Date(0,-1) // 1 month before 1900 = 1899-12-01.
new Date(0,-1,0) // 1 month and 1 day before 1900 = 1899-11-30.
new Date(0,-1,-1) // 1 month and *2* days before 1900 = 1899-11-29.
new Date('0','1') // 1900-02-01. Two+ params always cast to year and month.
new Date(100,0) // 0100-01-01. Year > 99 use year 0 not 1900.
new Date(1900,0) // 1900-01-01. Same as new Date(0,0). So intuitive!
Negative year = BC
new Date(-1,0) // 1 year before 0000-01-01 = 1 year before 1 BC = 2 BC.
new Date(-1,0,-1) // 2 days before 2 BC. Fun, yes? I'll leave this as an exercise.
There is no 0 AC. There is 1 AC and the year before it is 1 BC. Year 0 is 1 BC by convention.
2 BC is displayed as year
"-000001"
.
The extra zeros are required because it is outside normal range (0000 to 9999).
If younew Date(12345,0)
you will get"+012345-01-01"
, too.
Of course, the Gregorian calendar, adopted as late as 1923 in Europe, will cease to be meaningful long before we reach BC.
In fact, scholars accept that Jesus wasn't born in 1 BC.
But with the stars and the Earth moving at this scale, calendar is the least of your worries.
The remaining given code are just variations of these cases. For example:
new Date(0100) // One number = epoch. 0100 (octal) = 64ms since 1970
new Date('0100') // One string = iso = 0100-01-01.
new Date(-9999, 99, 99) // 9999 years before BC 1 and then add 99 months and 98 days
Hope you had some fun time. Please don't forget to vote up. :)
To stay sane, keep all dates in ISO 8601 and use the string constructor.
And if you need to handle timezone, keep all datetimes in UTC.
edited Jan 11 '18 at 3:19
answered Dec 27 '16 at 12:19
SheepySheepy
11.6k33158
11.6k33158
Just a question - why doesnew Date('00000100')
report the same asnew Date(0100)
?
– TrojanByAccident
Dec 27 '16 at 22:57
@TrojanByAccident I tested in Firefox 50 and Edge 38, both reports "Invalid Date" fornew Date("00000100")
, so don't do that. Chrome 55 parse it asnew Date("0100")
notnew Date(0100)
(type matters).
– Sheepy
Dec 28 '16 at 5:05
Interesting. Testing in Chrome 55,new Date('00000100')
reports as Fri Jan 01 100, andnew Date(00000100)
reports as Wed Dec 31 1969
– TrojanByAccident
Dec 28 '16 at 5:29
add a comment |
Just a question - why doesnew Date('00000100')
report the same asnew Date(0100)
?
– TrojanByAccident
Dec 27 '16 at 22:57
@TrojanByAccident I tested in Firefox 50 and Edge 38, both reports "Invalid Date" fornew Date("00000100")
, so don't do that. Chrome 55 parse it asnew Date("0100")
notnew Date(0100)
(type matters).
– Sheepy
Dec 28 '16 at 5:05
Interesting. Testing in Chrome 55,new Date('00000100')
reports as Fri Jan 01 100, andnew Date(00000100)
reports as Wed Dec 31 1969
– TrojanByAccident
Dec 28 '16 at 5:29
Just a question - why does
new Date('00000100')
report the same as new Date(0100)
?– TrojanByAccident
Dec 27 '16 at 22:57
Just a question - why does
new Date('00000100')
report the same as new Date(0100)
?– TrojanByAccident
Dec 27 '16 at 22:57
@TrojanByAccident I tested in Firefox 50 and Edge 38, both reports "Invalid Date" for
new Date("00000100")
, so don't do that. Chrome 55 parse it as new Date("0100")
not new Date(0100)
(type matters).– Sheepy
Dec 28 '16 at 5:05
@TrojanByAccident I tested in Firefox 50 and Edge 38, both reports "Invalid Date" for
new Date("00000100")
, so don't do that. Chrome 55 parse it as new Date("0100")
not new Date(0100)
(type matters).– Sheepy
Dec 28 '16 at 5:05
Interesting. Testing in Chrome 55,
new Date('00000100')
reports as Fri Jan 01 100, and new Date(00000100)
reports as Wed Dec 31 1969– TrojanByAccident
Dec 28 '16 at 5:29
Interesting. Testing in Chrome 55,
new Date('00000100')
reports as Fri Jan 01 100, and new Date(00000100)
reports as Wed Dec 31 1969– TrojanByAccident
Dec 28 '16 at 5:29
add a comment |
Well, firstly, you're passing in string instead of an integer, so that might have something to do with your issues here.
Check this out, it explains negative dates quite nicely, and there is an explanation for your exact example.
I am unable to open that link due to web security issues, however , can you explain it in brief so that even if the link breaks in future, we still have some concrete answer
– Flying Gambit
Dec 27 '16 at 7:37
I really don't think we're allowed to just copy paste someone elses blog post on the topic
– darryn.ten
Dec 27 '16 at 7:39
2
You could always quote it. I say this because I can't open that link either (just infinite loading icon)
– Jhecht
Dec 27 '16 at 7:41
3
@darryn.ten you can sumarise the ideas or copy small pieces that are relevant. As long as you link to the source it is usually considered OK. As it stands your post could be flagged as a link only answer
– K Scandrett
Dec 27 '16 at 7:43
@darryn.ten That explains hownew Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
works but not the rest, especiallynew Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
– Flying Gambit
Dec 27 '16 at 8:28
|
show 3 more comments
Well, firstly, you're passing in string instead of an integer, so that might have something to do with your issues here.
Check this out, it explains negative dates quite nicely, and there is an explanation for your exact example.
I am unable to open that link due to web security issues, however , can you explain it in brief so that even if the link breaks in future, we still have some concrete answer
– Flying Gambit
Dec 27 '16 at 7:37
I really don't think we're allowed to just copy paste someone elses blog post on the topic
– darryn.ten
Dec 27 '16 at 7:39
2
You could always quote it. I say this because I can't open that link either (just infinite loading icon)
– Jhecht
Dec 27 '16 at 7:41
3
@darryn.ten you can sumarise the ideas or copy small pieces that are relevant. As long as you link to the source it is usually considered OK. As it stands your post could be flagged as a link only answer
– K Scandrett
Dec 27 '16 at 7:43
@darryn.ten That explains hownew Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
works but not the rest, especiallynew Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
– Flying Gambit
Dec 27 '16 at 8:28
|
show 3 more comments
Well, firstly, you're passing in string instead of an integer, so that might have something to do with your issues here.
Check this out, it explains negative dates quite nicely, and there is an explanation for your exact example.
Well, firstly, you're passing in string instead of an integer, so that might have something to do with your issues here.
Check this out, it explains negative dates quite nicely, and there is an explanation for your exact example.
answered Dec 27 '16 at 7:31
darryn.tendarryn.ten
4,83923362
4,83923362
I am unable to open that link due to web security issues, however , can you explain it in brief so that even if the link breaks in future, we still have some concrete answer
– Flying Gambit
Dec 27 '16 at 7:37
I really don't think we're allowed to just copy paste someone elses blog post on the topic
– darryn.ten
Dec 27 '16 at 7:39
2
You could always quote it. I say this because I can't open that link either (just infinite loading icon)
– Jhecht
Dec 27 '16 at 7:41
3
@darryn.ten you can sumarise the ideas or copy small pieces that are relevant. As long as you link to the source it is usually considered OK. As it stands your post could be flagged as a link only answer
– K Scandrett
Dec 27 '16 at 7:43
@darryn.ten That explains hownew Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
works but not the rest, especiallynew Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
– Flying Gambit
Dec 27 '16 at 8:28
|
show 3 more comments
I am unable to open that link due to web security issues, however , can you explain it in brief so that even if the link breaks in future, we still have some concrete answer
– Flying Gambit
Dec 27 '16 at 7:37
I really don't think we're allowed to just copy paste someone elses blog post on the topic
– darryn.ten
Dec 27 '16 at 7:39
2
You could always quote it. I say this because I can't open that link either (just infinite loading icon)
– Jhecht
Dec 27 '16 at 7:41
3
@darryn.ten you can sumarise the ideas or copy small pieces that are relevant. As long as you link to the source it is usually considered OK. As it stands your post could be flagged as a link only answer
– K Scandrett
Dec 27 '16 at 7:43
@darryn.ten That explains hownew Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
works but not the rest, especiallynew Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
– Flying Gambit
Dec 27 '16 at 8:28
I am unable to open that link due to web security issues, however , can you explain it in brief so that even if the link breaks in future, we still have some concrete answer
– Flying Gambit
Dec 27 '16 at 7:37
I am unable to open that link due to web security issues, however , can you explain it in brief so that even if the link breaks in future, we still have some concrete answer
– Flying Gambit
Dec 27 '16 at 7:37
I really don't think we're allowed to just copy paste someone elses blog post on the topic
– darryn.ten
Dec 27 '16 at 7:39
I really don't think we're allowed to just copy paste someone elses blog post on the topic
– darryn.ten
Dec 27 '16 at 7:39
2
2
You could always quote it. I say this because I can't open that link either (just infinite loading icon)
– Jhecht
Dec 27 '16 at 7:41
You could always quote it. I say this because I can't open that link either (just infinite loading icon)
– Jhecht
Dec 27 '16 at 7:41
3
3
@darryn.ten you can sumarise the ideas or copy small pieces that are relevant. As long as you link to the source it is usually considered OK. As it stands your post could be flagged as a link only answer
– K Scandrett
Dec 27 '16 at 7:43
@darryn.ten you can sumarise the ideas or copy small pieces that are relevant. As long as you link to the source it is usually considered OK. As it stands your post could be flagged as a link only answer
– K Scandrett
Dec 27 '16 at 7:43
@darryn.ten That explains how
new Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
works but not the rest, especially new Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
– Flying Gambit
Dec 27 '16 at 8:28
@darryn.ten That explains how
new Date('-9999', '99', '99'); // "-009991-07-08T04:00:00.000Z"
works but not the rest, especially new Date('0000', '00', '00'); // "1899-12-31T05:00:00.000Z"
– Flying Gambit
Dec 27 '16 at 8:28
|
show 3 more comments
Then why does it accept negative values ?
You are confusing the description of how the data is stored internally with the arguments that the constructor function takes.
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
No, for the above reason. Nothing stops the year, month or day from being negative. You just end up adding a negative number to something.
Also note that, in the last one, the date is shown as 4 which is wrong.
Numbers which start with a 0
are expressed in octal, not decimal. 0100 === 64
.
add a comment |
Then why does it accept negative values ?
You are confusing the description of how the data is stored internally with the arguments that the constructor function takes.
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
No, for the above reason. Nothing stops the year, month or day from being negative. You just end up adding a negative number to something.
Also note that, in the last one, the date is shown as 4 which is wrong.
Numbers which start with a 0
are expressed in octal, not decimal. 0100 === 64
.
add a comment |
Then why does it accept negative values ?
You are confusing the description of how the data is stored internally with the arguments that the constructor function takes.
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
No, for the above reason. Nothing stops the year, month or day from being negative. You just end up adding a negative number to something.
Also note that, in the last one, the date is shown as 4 which is wrong.
Numbers which start with a 0
are expressed in octal, not decimal. 0100 === 64
.
Then why does it accept negative values ?
You are confusing the description of how the data is stored internally with the arguments that the constructor function takes.
Even if it did shouldn't negative value mean values before Jan 1, 1970 ?
No, for the above reason. Nothing stops the year, month or day from being negative. You just end up adding a negative number to something.
Also note that, in the last one, the date is shown as 4 which is wrong.
Numbers which start with a 0
are expressed in octal, not decimal. 0100 === 64
.
answered Dec 27 '16 at 11:51
QuentinQuentin
641k718651035
641k718651035
add a comment |
add a comment |
Please have a look at the documentation
Year: Values from 0 to 99 map to the years 1900 to 1999
- 1970 with appropriate timezone: new Date(0); // int MS since 1970
- 1900 (or 1899 with applied timezone): new Date(0,0) or new Date(0,0,1) - date is 1 based, month and year are 0 based
- 1899: new Date(0,0,-1)
add a comment |
Please have a look at the documentation
Year: Values from 0 to 99 map to the years 1900 to 1999
- 1970 with appropriate timezone: new Date(0); // int MS since 1970
- 1900 (or 1899 with applied timezone): new Date(0,0) or new Date(0,0,1) - date is 1 based, month and year are 0 based
- 1899: new Date(0,0,-1)
add a comment |
Please have a look at the documentation
Year: Values from 0 to 99 map to the years 1900 to 1999
- 1970 with appropriate timezone: new Date(0); // int MS since 1970
- 1900 (or 1899 with applied timezone): new Date(0,0) or new Date(0,0,1) - date is 1 based, month and year are 0 based
- 1899: new Date(0,0,-1)
Please have a look at the documentation
Year: Values from 0 to 99 map to the years 1900 to 1999
- 1970 with appropriate timezone: new Date(0); // int MS since 1970
- 1900 (or 1899 with applied timezone): new Date(0,0) or new Date(0,0,1) - date is 1 based, month and year are 0 based
- 1899: new Date(0,0,-1)
edited Dec 27 '16 at 13:43
answered Dec 27 '16 at 11:42
mplungjanmplungjan
87.3k21122181
87.3k21122181
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f41340836%2fwhy-does-date-accept-negative-values%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
@mplungjan note the word since
– TrojanByAccident
Dec 27 '16 at 7:28
Note that new Date(0) is 1970 (with relevant TZ)
– mplungjan
Dec 27 '16 at 7:34
@mplungjan does this mean there is a way to represent a time in BC ?
– Flying Gambit
Dec 27 '16 at 7:35
@FlyingGambit Gregorian calendar can be "reverse extended" to BC dates, but it will cease to be historically accurate long before that. Jesus did not invent the Gregorian calendar.
– Sheepy
Dec 27 '16 at 10:44
@TrojanByAccident, this is the number of milliseconds that is calculated since the epoch. Here the term since give a direction in time. So positive will be after, negative will be before. (this is how I understand it)
– AxelH
Dec 27 '16 at 12:56