This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
How to validate a date?
(11 answers)
Closed 2 years ago.
I've seen many articles about this but not quite found what I am looking for yet.
I'm trying to simply check if a string is a date. That string might contains a number such as 2012 though.
var timestamp = Date.parse('foo 2012');
if (isNaN(timestamp) == false) {
var d = new Date(timestamp);
console.log('DATE', d)
}else{
console.log('TEXT');
}
//OUTPUT: DATE Sun Jan 01 2012 00:00:00 GMT+1100 (Australian Eastern Daylight Time)
Why does javascript convert foo 2012 into a date when it's clearly not?
How can I validate that my string is an actual date ?
A string is never a date.
A string can represent a date. There are many ways to represent the same date through different string formats.
This means "validating that a string is a date" is an impossible task. What you can do instead is:
Validate that the format of the string conforms to some well-known format and that its contents are valid.
Try to parse a given string as an expected format and either throw an error or return a "guard" value to indicate that the parsing was not a success.
JavaScript took a third option, which is like option 2, only it returns a value indicating its "best efforts" at working with the garbage input. That's apparently why it saw a year in your string and decided "well, I guess I can make a date with this?" As #Pointy pointed out, it's actually in the spec that if the JavaScript string doesn't match one of the two supported formats, the implementer can decide what the result should be.
I'd highly recommend that if you're dealing with date strings, you should stick with a consistent format. I'm a big fan of ISO 8601 date/time strings because they are time zone aware, easy to sort, and are widely supported (including being easily parsed by JavaScript). If you're requiring the strings are in a standard format, it's easier to do things like finding A RegExp that can validate the input.
Related
This question already has answers here:
Detecting an "invalid date" Date instance in JavaScript
(52 answers)
Closed 3 years ago.
When I pass "test 2" string in new Date(), I am getting an actual date, how?
I am trying to whether it is a date or not.
console.log(new Date("test 2"));
Passing a string to new Date is the same as using Date.parse.
When a non-standard date string is passed, the result is implementation-dependent; the browser can do whatever it wants, including guessing. On Chrome, your input results in a date, but not on Firefox (NaN is returned).
test isn't part of a date string, so it looks like Chrome just parses the 2:
console.log(new Date('2'));
console.log(new Date('1'));
console.log(new Date('0'));
Essentially, this is undefined behavior, so strange results aren't surprising. Unless the passed string conforms to the format defined in the specification - that is, something like "2011-10-10" or "2011-10-10T14:48:00" or "2011-10-10T14:48:00.000+09:00", the results are unpredictable.
Consider instead figuring out what sort of string format you'd be expecting as an input, and then checking if the format is followed with a regular expression. If so, pass to new Date and see if it gives you a meaningful results; otherwise, don't.
As per MDN:
The ECMAScript specification states: If the String does not conform to the standard format the function may fall back to any implementation–specific heuristics or implementation–specific parsing algorithm.
Google Chrome tries to parse your date and picks up the number as a month. Other browsers may reject the passed value or return something totally different.
Hence please consider the following note:
Parsing of date strings with the Date constructor (and Date.parse(), which works the same way) is strongly discouraged due to browser differences and inconsistencies.
MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Parameters
From mdn:
A string representing a simplification of the ISO 8601 calendar date extended format (other formats may be used, but results are implementation-dependent).
You're encountering an implementation-specific attempt to parse your string as a date. It is not recommended to depend on this behaviour.
Because your test text includes a number. See, it's interpreting a number like 1 as January, 2 as February,3 as March, and so on.
new Date( "3")
will give you
Thu Mar 01 2001 00:00:00 GMT+0530 (India Standard Time)
If you use text with no number, e.g. new Date("test") it will throw invalid date.
This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 6 years ago.
I was trying to check what values would return if partial values are sent.
var d = new Date("11/28");
console.log(d.toLocaleDateString())
I was expecting it to be 28th Nov., 2016(current year), but it returns 28th Nov., 2001.
So the question is Why is 2001 considered as default year?
2001 is not consider as default year.
This is a Chrome issue, if you run the same code with Firefox you get Invalid Date.
The language specification only includes rules for parsing ISO 8601 formatted strings. Parsing of any other format is implementation dependent (noting that the Date constructor and Date.parse are equivalent for parsing).
So given "11/28" is not a valid ISO 8601 string, the implementation is free to apply any heuristics it likes. Any result, including an invalid date, should be expected and consistency between implementations should not.
This question already has answers here:
JavaScript's getDate returns wrong date
(12 answers)
Closed 6 years ago.
This is so basic, but it makes no sense to me:
new Date("2010-01-01").getFullYear();
result: 2009
wth? My goal is to reformat the date as mm/dd/yyyy given the format yyyy-mm-dd..
Adding on:
new Date("2010-01-01").getMonth();
result: 11
new Date("2010-01-01").getDate();
result: 31
The date string you're passing into new Date() has no timezone in it. It's being interpreted as UTC. The critical thing to understand here is that a Date is stored as a Unix timestamp (seconds since 1970-01-01 00:00, making 'Date' a misleading name) so if you don't specify the time within the date, it's going to apply a default.
Date.prototype.getFullYear() retrieves the full year for that timestamp in your LOCAL time. (See the docs here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear)
You're somewhere west of UTC, and 2010-01-01 UTC is 2009-12-31 in your local time.
And for your final mystery....getMonth() is 0-based, not 1-based, so '11' is December.
Don't use the Date constructor to parse strings, it's largely implementation dependent and inconsistent.
An ISO 8601 date and time without a timezone like "2016-02-29T12:00:00" should be treated as local (i.e. use the host system timezone offset to create a Date), but a date–only string is treated like "2016-02-29" as UTC. The first behaviour is consistent with ISO 8601, but the second isn't.
Some versions of browsers will treat date–only strings as UTC, and some as invalid dates, so always parse strings manually (a two line function or library can help). That way you know how it will be parsed in all hosts.
Provide Time with date in the new Date() as parameter . Then u will get exact Result.
It seems to me that Date.parse assumes all months have 31 days. Including months with 30 days and including February(which should only ever have 28/29 days).
I checked this question 31 days in February in Date object
But the answer there suggested there was nothing wrong with Date in his issue..Somebody said something to the questioner about zero indexing and he pretty much said "oh ok", and determined that it was his mistake and not a mistake of Date.
Another question Date is considering 31 days of month the guy was doing some subtraction was a number of lines of code and he seemed to not put the error down to Date in the end.
But this example that I have seems to be a bit different and more clear cut. It involves Date.parse and can be demonstrated with one/two lines of code.
Date.parse is aware that there are not 32 days in a month, that's good
Date.parse("2000-01-32");
NaN
But In February it thinks there can be 30 or 31 days
Date.parse("2013-02-30");
1362182400000
Date.parse("2013-02-31");
1362268800000
In fact it looks like it thinks all months have 31 days. That is really strange for a method that is meant to parse a date.
And there's no issue of zero indexing here. As Date.parse("...") doesn't use zero indexing (And even if it did, it wouldn't cause it tot make the error of thinking there are 31 days in February - that is more than one off!
Date.parse("01-00-2000");
NaN
Date.parse("00-01-2000");
NaN
According to the specification for Date.parse() (emphasis mine):
The function first attempts to parse the format of the String according to the rules called out in Date Time String Format. […] Unrecognisable Strings or dates containing illegal element values in the format String shall cause Date.parse to return NaN.
And according to the specification for Date Time String Format (emphasis mine):
ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
Where the fields are as follows: […] DDis the day of the month from 01 to 31.
Therefore, any date with a day of month greater than 31 is illegal and Date.parse() returns NaN.
Please notice that the standard defines a date format, not a date: the static method isn't required to make additional verifications, and everything else is implementation-specific. For instance, Date.parse('2013-02-30') and Date.parse('2013-04-31') both return NaN on Firefox.
The implementation differs between browsers. IE, Edge and Chrome will parse strings that doesn't represent actual dates, but Firefox will return NaN for those strings. The safe thing to do is to consider the result from Date.parse as undefined for date strings where the day falls outside the range of the month.
Browsers that allow parsing of non-existent dates will return a different date. Parsing "2015-04-31" will return the date 2015-05-01. This is the same behaviour as when using new Date(2015, 3, 31), where numbers out of range is allowed and will wrap around into a different month or year. That means that the result is still usable, if you don't mind that some invalid dates turn into other dates in some browsers.
The standard isn't very clear about what values are valid:
Illegal values (out-of-bounds as well as syntax errors) in a format
string means that the format string is not a valid instance of this
format.
The day component is defined as having a range from 1 to 31:
DD is the day of the month from 01 to 31.
However, the format is based on ISO 8601, and that is not a format for parsing strings into dates, that is a format for representing dates as string. Clearly you can't represent a date that doesn't even exist as a string.
Right, so how to check if a date string has a valid value?
with moment is very easy:
export function dateStringIsValid(aDateString){
return (moment(aDateString, "DD/MM/YYYY", true).isValid())
}
This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 4 years ago.
Hi I am trying to construct a javascript date object with a string, but it keeps contructing the wrong day. It always constructs a day that is one day behind. Here is my code
var date = new Date('2006-05-17');
The date i want to get is
Wednesday May 17 2006 00:00:00 GMT-0700 (PDT)
But instead I get
Tue May 16 2006 17:00:00 GMT-0700 (PDT)
When you pass dates as a string, the implementation is browser specific. Most browsers interpret the dashes to mean that the time is in UTC. If you have a negative offset from UTC (which you do), it will appear on the previous local day.
If you want local dates, then try using slashes instead, like this:
var date = new Date('2006/05/17');
Of course, if you don't have to parse from a string, you can pass individual numeric parameters instead, just be aware that months are zero-based when passed numerically.
var date = new Date(2006,4,17);
However, if you have strings, and you want consistency in how those strings are parsed into dates, then use moment.js.
var m = moment('2006-05-17','YYYY-MM-DD');
m.format(); // or any of the other output functions
What actually happens is that the parser is interpreting your dashes as the START of an ISO-8601 string in the format "YYYY-MM-DDTHH:mm:ss.sssZ", which is in UTC time by default (hence the trailing 'Z').
You can produce such dates by using the "toISOString()" date function as well.
http://www.w3schools.com/jsref/jsref_toisostring.asp
In Chrome (doesn't work in IE 10-) if you add " 00:00" or " 00:00:00" to your date (no 'T'), then it wouldn't be UTC anymore, regardless of the dashes. ;)
Remove the prepending zero from "05"