0

Why does javaScript allow creation of dates such as

invalidDate = new Date(2015,3,31);

Here I am trying to create a date with April 31st. Instead JavaScript creates a date as Fri May 01 2015 00:00:00. Should we validate the date before creating it?

There are scenarios when we try to parse invalid dates and it does the same thing. How should one parse the date correctly when the given date may not be valid?

var invalidDate = new Date(2015, 3, 31);
alert(invalidDate);
Prashant Bhanarkar
  • 930
  • 3
  • 14
  • 32

4 Answers4

2

You can use the Date API to create the date and check the result:

function makeDate(year, month, day) {
  var d = new Date(year, month, day);
  if (d.getFullYear() !== year || d.getMonth() !== month)
    throw new Error("Invalid date");
  return d;
}

If the day is not a valid day for the given month, then the month will be adjusted; that's a feature of the Date API that allows easy "date math". If the above code notices that the input values have been corrected, it throws an exception.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Does it make sense to compare Day also, like giving 29 Feb in which month has only 28 days? – Gaurav P Sep 09 '16 at 13:47
  • @GauravP well if the Date is "corrected", the month will change. It would not hurt to compare the day, but I don't think it is necessary. – Pointy Sep 09 '16 at 13:52
  • @Rajesh well the month value might be off too - if month is 15 and day is 1 for example – Pointy Sep 09 '16 at 14:27
1

Because there is no 31st April, so it's giving you the nearest valid date...

For clarity, as below, any integer above a valid date will roll over to the following month.

i.e. Date(2016,0,1) is 1st Jan 2016.

Date(2016,0,61) adds 60 days on to that date, which rolls past the 29th Feb 2016 and into March, thus..

Date(2016,0,61) = 1st March 2016

As a result, Date(2015,3,31) = 30th April 2015 plus one day = 1st May 2015

Chris J
  • 1,441
  • 9
  • 19
  • Define "nearest valid date". For example, `new Date(2015,3,50)` gives you "May 20 2015". – Tomalak Sep 09 '16 at 13:27
  • That's 30th April plus 20 days (giving you the 50). – Chris J Sep 09 '16 at 13:29
  • 2
    I know. Don't explain it to me, explain it in your answer. Saying "nearest valid date" is hand-wavy and explains nothing. Make your answer so that it helps predict the outcome of a call to `Date()`. – Tomalak Sep 09 '16 at 13:33
  • That's better. Now only the other half of the explanation (what about negative numbers) is missing. – Tomalak Sep 09 '16 at 14:24
1

You can validate the date with a function like this:

function isValidDate(year, month, day) {
  var m = month - 1; // Note: the month is 0-based
  var d = new Date(year, m, day);
  /*
  For invalid dates, either the day or month gets changed:
    2015-04-31 -> 2015-05-01
    2015-02-29 -> 2015-03-01
    2015-13-10 -> 2016-01-10
    2016-00-10 -> 2015-12-10
  */
  return d.getDate() == day && d.getMonth() == m;
}
LWChris
  • 3,320
  • 1
  • 22
  • 39
-1

In general, you should never trust user input. As a result, you should try to put them in a situation where they can not enter bad data. This can be done through validation or thought a User interface that only enables them to select valid dates.

You can look around SO for some examples on validating dates: Detecting an "invalid date" Date instance in JavaScript. If you are using a javascript framework they might already have something built into it as well.

As for why it works and "lets you do it", I would suspect that is because javascript's parse function calculates the "milliseconds elapsed since January 1, 1970, 00:00:00 UTC". The resulting milliseconds is then used and javascript represents that as the correct date.

Community
  • 1
  • 1
Nexeh
  • 213
  • 3
  • 18