I want to create a Date object in javascript, which represents the year 0001, 2014 years ago.
I tried with
d = new Date();
d.setYear(1);
console.log(d);
but it gives the year 1901
with
d = new Date(1,1,1)
console.log(d);
no way.
How can I create this date?
First of all it's not a Y2K issue at all! ( UPDATE: in some cases - it's related to Y2K issues, but it's not the problem here )
The correct answer is that you can't do that reliably. Does Daylight saving time apply to year 1? How many Leap Years were there? Were there any? Etc. But the answer by #Daniel will use it!
UPDATE: not to mention #MattJohnson post about DST. DST in year 1, actually JS (ES5 anyway) will lie and use the current DST rule for all years
So please don't fool yourself with the idea that you can reliably work with dates lower than 1970. (You will have a lot of problems and surprises even in that time range.)
But if you really, really need to you can use new Date('0001-01-01') (ISO 8601 format) or #Daniel's method:
var d = new Date(); d.setFullYear(1);
But before you use it read this...
There are 4 ways to create a Date in JS:
new Date()
new Date(milliseconds)
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)
1) new Date() creates current date ( in your local timezone ) so we are not interested in it for now.
2) new Date(number) creates a new date object as zero time plus the number. Zero time is 01 January 1970 00:00:00 UTC.
So in this case time in JS counting from year 1970.
(new Date(0)).toUTCString()
"Thu, 01 Jan 1970 00:00:00 GMT
If you use negative number you can go "back" it time before 1970
(new Date(-62167219200000)).toUTCString()
"Sat, 01 Jan 0 00:00:00 GMT"
-62167219200000 <- milliseconds
-62167219200000 / 1000
-62167219200 <- seconds
-62167219200 / 60
-1036120320 <- minutes
-1036120320 / 60
-17268672 <- hours
-17268672 / 24
-719528 <- days
-719528 / 365
-1971.309589041096 <- years ( this is roughly calculated value )
The problem is that it's not reliable. How many Leap Years were there? Were there any? Daylight saving time? Etc. And I don't like it because of this magic number -62167219200000
3) new Date(dateString) This is most 'reliable' way. DateString - A string representing an RFC2822 or ISO 8601 date.
RFC2822 / IETF date syntax (RFC2822 Section 3.3), e.g. "Mon, 25 Dec 1995 13:30:00 GMT"
The problem with it is that if you use negative number you will get an incorrect Date with NaN in a result of all methods
(new Date('01 January -1 00:00:00 UTC')).getFullYear()
NaN
If you use year higher or equal 0 and lower then 50 then 2000 will be added automatically.
(new Date('01 January 0 00:00:00 UTC')).getFullYear()
2000
(new Date('01 January 1 00:00:00 UTC')).getFullYear()
2001
(new Date('01 January 10 00:00:00 UTC')).getFullYear()
2010
(new Date('01 January 01 00:00:00 UTC')).getFullYear()
2001
(new Date('01 January 30 00:00:00 UTC')).getFullYear()
2030
(new Date('01 January 49 00:00:00 UTC')).getFullYear()
2049
And if you use year higher or equal 50 and lower then 100 then 1900 will be added.
(new Date('01 January 50 00:00:00 UTC')).getFullYear()
1950
(new Date('01 January 51 00:00:00 UTC')).getFullYear()
1951
(new Date('01 January 90 00:00:00 UTC')).getFullYear()
1990
(new Date('01 January 99 00:00:00 UTC')).getFullYear()
1999
Years equal 100 or higher will get correct year number
(new Date('01 January 100 00:00:00 UTC')).getFullYear()
100
(new Date('01 January 101 00:00:00 UTC')).getFullYear()
101
(new Date('01 January 999 00:00:00 UTC')).getFullYear()
999
(new Date('01 January 9999 00:00:00 UTC')).getFullYear()
9999
So we can't create year 1 using RFC2822 / IETF date syntax
About ISO 8601:
http://www.w3.org/TR/NOTE-datetime
The actual formats are
Year:
YYYY (eg 1997)
Year and month:
YYYY-MM (eg 1997-07)
Complete date:
YYYY-MM-DD (eg 1997-07-16)
Complete date plus hours and minutes:
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
Complete date plus hours, minutes and seconds:
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
Complete date plus hours, minutes, seconds and a decimal fraction of a second
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
We are most interested in 'Complete date'
(new Date('0001-01-01')).toUTCString()
"Mon, 01 Jan 1 00:00:00 GMT"
Yahoo!!! ( or it is better to say Google! :) ), we can use ISO 8601 to create date with year 1
But be careful and do not try to use negative numbers or short year numbers, as parsing of those will may vary on localization or just insanity :)
(new Date('-0001-01-01')).toUTCString()
"Sun, 31 Dec 2000 21:00:00 GMT"
(new Date('01-01-01')).toUTCString()
"Sun, 31 Dec 2000 21:00:00 GMT"
(new Date('02-01-01')).toUTCString()
"Wed, 31 Jan 2001 21:00:00 GMT"
(new Date('02-01-05')).toUTCString()
"Mon, 31 Jan 2005 21:00:00 GMT"
4) new Date(year, month, day, hours, minutes, seconds, milliseconds)
To use this one you have to pass two parameters ( year, and month ), all other will be optional. Be careful because here month will start from 0 to 11, not like everywhere else. WAT? o_O
WARNING! This date will be created in your current time zone!!! So be careful using it!
UPD: clarification by #matt-johnson
...actually the Date object always reflects the local time zone. You can't place it in another time zone, and even if you initialize it with a UTC timestamp, it will still reflect back the local time zone in most of the functions. Internally it tracks UTC by the numeric timestamp, and there are functions that expose UTC values explicitly, but everything else is local.
The negative numbers will be interpreted as negative years
(new Date(-1, 0)).toString()
"Fri Jan 01 -1 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(-234, 0)).toString()
"Wed Jan 01 -234 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
The numbers from 0 to 99 will be incremented by 1900 automatically
(new Date(0, 0)).toString()
"Mon Jan 01 1900 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(1, 0)).toString()
"Tue Jan 01 1901 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(11, 0)).toString()
"Sun Jan 01 1911 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(50, 0)).toString()
"Sun Jan 01 1950 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(99, 0)).toString()
"Fri Jan 01 1999 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
The numbers from 100 to 275760 will be interpreted as year numbers
(new Date(100, 0)).toString()
"Fri Jan 01 100 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(102, 0)).toString()
"Sun Jan 01 102 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(2002, 0)).toString()
"Tue Jan 01 2002 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
And numbers higher then 275760 will be Invalid date
(new Date(275760, 0)).toString()
"Tue Jan 01 275760 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)"
(new Date(275761, 0)).toString()
"Invalid Date"
UPD:
new Date(Date.UTC(1,1,1)) will safer from same symptoms as new Date(year, month, day, hours, minutes, seconds, milliseconds). Because of Date.UTC function.
Use setFullYear - this is the Y2K issue with JavaScript.
var d = new Date(); d.setFullYear(1);
document.write(d);
You can use the string version of the constructor:
console.log(new Date("0001-01-01"));
The (deprecated) Date.setYear method sets the year for a specified date, but note that:
If yearValue is a number between 0 and 99 (inclusive), then the year
for dateObj is set to 1900 + yearValue. Otherwise, the year for
dateObj is set to yearValue.
var theBigDay = new Date();
theBigDay.setYear(96); // sets year to 1996
theBigDay.setYear(1996); // sets year to 1996
theBigDay.setYear(2000); // sets year to 2000
You should use Date.setFullYear method nevertheless. The other method is deprecated.
when handling JavaScript date objects you have to specify the full year for ex, 1950 and not 50. It is mentioned in the doc. So the code should be as Daniel has said also,
d = new Date(); d.setFullYear(1);
console.log(d);
Actually, you can use the Date constructor for years whose absolute value is below 100, by using the negative year instead of the positive one, and then setting it back to positive using the reliable .setFullYear() / .setUTCFullYear() methods. This is because the issue of getting 20th or 21st century years in the case of historical ones manifests itself only for under 100 positive years. While for a basic usage this works without problems, care should be taken when using the new Date(...) constructor to add or subtract time at object creation moment, since you'd want to switch the operation sign accordingly as well. Also, if the desired historical year is negative in the first place and you need to add or subtract from it at construction time, the matter suffers further complications.
Therefore, to avoid any confusion and be clear and consistent about things, using the extended form of .setFullYear() / .setUTCFullYear() and .setHours() / .setUTCHours() to set the entire date and time parts after the object construction should be an optimal alternative and present no drawbacks whatsoever, while also being similar to setting things at construction time.
Below there are examples for each of the two methods mentioned above and both local and UTC dates (an optional 365 day or 31536000000 ms year is "added" in all cases, to illustrate if and how it changes things):
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Historic Dates Problem</h2>
<p>Construct negative dates and switch them to positive (1) or <br>Set the full date and time parts separately (2)</p>
<p id="examples"></p>
<script>
var loc1 = new Date(- 37, 11, 24, 10, 33, 30, - 31536000000); loc1.setFullYear(- loc1.getFullYear());
var utc1 = new Date(Date.UTC(- 37, 11, 24, 10, 33, 30, - 31536000000)); utc1.setUTCFullYear(- utc1.getUTCFullYear());
var loc2 = new Date(); loc2.setFullYear(37, 11, 24); loc2.setHours(10, 33, 30, 31536000000);
var utc2 = new Date(); utc2.setUTCFullYear(37, 11, 24); utc2.setUTCHours(10, 33, 30, 31536000000);
document.getElementById("examples").innerHTML = "LOC1: " + loc1 + "<br>UTC1: " + utc1 + "<br>LOC2: " + loc2 + "<br>UTC2: " + utc2;
</script>
</body>
</html>
Related
I ran into a problem with a 'time' in JS. So basicaly I'm tring to get a time from databace as a string like 11:00 and 20:30.
With the upcoming function code I convert it to js format:
function getDateFromHours(time) {
time = time.split(':');
let now = new Date();
return new Date(now.getFullYear(), now.getMonth(), now.getDate(), ...time);
}
After all I got this: Mon Nov 09 2020 11:00:00 GMT+0300 and this: Mon Nov 09 2020 20:30:00 GMT+0300
So the first question:
How to compare these times to each other?
How to output every 15 minuties between these two times in concole to make it look like:
Mon Nov 09 2020 11:00:00 GMT+0300
Mon Nov 09 2020 11:15:00 GMT+0300
Mon Nov 09 2020 11:30:00 GMT+0300
etc...
For comparing times, and generating times algorithmically, you're best to work in timestamps. It's just a matter of converting between milliseconds and whatever unit of time you care to think in. You can get the timestamp from a Date object with the getTime method.
This question already has answers here:
Incorrect date shown in new Date() in JavaScript
(3 answers)
Closed 5 years ago.
When I convert that date to ISO string I get the 30th of november 2015. Why wouldn't it be first of december? I have googled and I know that month is 0-indexed and that overflows lead to the next day/month/year. But I cannot explain myself that behaviour and when I google it I find unrelated topics.
Thing is if You type:
var date = new Date(2015, 11, 1);
console.log(date);
You will get output based on your timezone, for me it's:
Tue Dec 01 2015 00:00:00 GMT+0100 (Central Europe Standard Time)
Function toISOString will always output time in UTC. So in this case you will get this date minus one hour.
2015-11-30T23:00:00.000Z
If you check the MDN page you'll see that:
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.
Your users have different local timezones.
For me new Date(2015, 11, 1) gives Tue Dec 01 2015 00:00:00 GMT+0100 (Romance Standard Time) (I'm in the timezone Central European Time which is GMT+1).
Hence you can follow the MDN hint and use Date.UTC inside of your date call instead:
var date = new Date(2015, 11, 1);
console.log(date.toString());
// "Tue Dec 01 2015 00:00:00 GMT+0100 (Romance Standard Time)"
// 00:00:00 in GMT+1 but 23:00:00 in GMT+0
console.log(date.toISOString());
// "2015-11-30T23:00:00.000Z"
// ^^ 30th of november - that's a nogo!
var utcDate = new Date(Date.UTC(2015, 11, 1));
console.log(utcDate.toString());
// "Tue Dec 01 2015 01:00:00 GMT+0100 (Romance Standard Time) 15:49:26.146"
// 01:00:00 in GMT+1 but 00:00:00 in GMT+0
console.log(utcDate.toISOString());
// "2015-12-01T00:00:00.000Z"
// ^^ The first! Not the 30th!
var date = new Date(Date.UTC(2015, 11, 1));
console.log(date.toISOString());
Output:
2015-12-01T02:00:00.000Z
I did create a date object out of '31/12/2018':
new Date('2018', '12', '31')
It does however create something completely different that I would expect.
Date {Thu Jan 31 2019 00:00:00 GMT+0100 (Central European Standard Time)}
What's happening?
Months are indexed starting from 0. Use 11 for December, not 12 :
new Date(2018, 11, 31)
(and yes, there should be numbers instead of strings, which makes it a little less confusing)
From the MDN :
month
Integer value representing the month, beginning with 0 for
January to 11 for December.
Months start with 0 in JavaScript. January is 0; December is 11. 12 represents January the following year. You'll want to use 11 instead of 12:
new Date('2018', '11', '31')
-> Mon Dec 31 2018 00:00:00 GMT+0100 (Central European Standard Time)
You've forget that months in JS starts with 0 instead 1.
Please use
new Date('2018', '11', '31')
in your case.
So I have this date returned from an API:
"2014-08-07T00:00Z"
And the results from new Date("2014-08-07T00:00Z") equal Wed Aug 06 2014 20:00:00 GMT-0400 (EDT) and .getDay() on that date gives me 3.
Why is it going from August 7th, to 6th, and the getDay returns 3?
Basically I'm trying to turn the API return date into english.
days[d.getDay()]+", "+months[d.getMonth()]+" "+getOrdinal(d.getDay())+" "+formatAMPM(d)
(aka "Wednesday, August 3rd 8:00 pm")
console.log(d,data[i].startDate, d.getDay());
//yields
// Wed Aug 06 2014 20:00:00 GMT-0400 (EDT) "2014-08-07T00:00Z" 3
days is just an array of text days, as is months, getOrdinal is a function that gives the text st or nd or rd on the day, and formatAMPM is pretty obvious.
.getDay() returns the day of the week. I think you'd expect .getDate()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate
That's why you're seeing that it is a Wednesday.
The result for me of new Date("2014-08-07T00:00Z") is Wed Aug 06 2014 18:00:00 GMT-0600 (MDT). This is because dates are converted to your local timezone when constructed
I don't think that there is any problem here.
Your date is 2014-08-07T00:00Z, with Z meaning Zulu Time Zone (equivalent to UTC), and using new Date() on it will convert to you local time, here GMT-4, that is why you are getting 4 hours difference.
And For the "3", the getDay() method returns the day of the week, wednesday in your case.
I was playing around with JavaScript dates and I'm looking for an explanation pertaining to the last logged array. Why are the numbers 1352589000, 1352589395 different?
Code
var examples = [
"Fri Jan 16 1970 10:43:09 GMT-0500 (EST)",
1352589395
];
var text = [
new Date((examples[0])),
new Date((examples[1])),
];
var unix = [
new Date((examples[0])).getTime(),
new Date((examples[1])).getTime(),
];
console.log(examples);
console.log(text);
console.log(unix);
Output
[
'Fri Jan 16 1970 10:43:09 GMT-0500 (EST)',
1352589395
][
'Fri Jan 16 1970 10:43:09 GMT-0500 (EST)' ,
'Fri Jan 16 1970 10:43:09 GMT-0500 (EST)'
][
1352589000,
1352589395
]
The numbers are in milliseconds. The difference between them is 395, which is less than half a second. The string format you're using only goes down to the second, and so its milliseconds portion is 0, but the number you're parsing includes the milliseconds (all 395 of them).
Because that Unix time stamp is in milliseconds. You didn't specify milliseconds, so it is giving you exactly 10:43:09 on Jan 16, 1970. The other time stamp is giving you 10:43:09.395 on Jan 16, 1970.
EDIT
The Unix timestamp is the number of SECONDS since the Jan 1st, 1970. Javascript's getTime() returns the number of MILLISECONDS since Jan 1st, 1970. So yes it is the Unix timestamp... in milliseconds.
You are giving two different times to Date() and both of them are incorrect. Javascript's Date object accepts no argument for current time or milliseconds or date string or [year, month, day, hours, minutes, seconds, milliseconds].
"Fri Jan 16 1970 10:43:09 GMT-0500 (EST)" is invalid format for Date(). For correct DateString formats check https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/parse