1

I'm trying to write a method that checks whether a date is valid. It is passed in three Strings: month, day, and year, in order. Month should be from 0-11 instead of 1-12. I have tested the logic of the code in Java and it works. is_int is another method that tests if a String is composed solely of numerical characters. Unfortunately, I am running into problems which I can't figure out.

function is_int(value) {
   for (i = 0 ; i < value.length ; i++) {
      if ((value.charAt(i) < '0') || (value.charAt(i) > '9')) return false
    }
   return true;
}

function isValidDate(value1:String, value2:String, value3:String)
{
  if (!is_int(value3)) return false;
  if (!is_int(value2)) return false;
  if (!is_int(value1)) return false;
  var v1 = parseInt(value1) + 1;
  var v2 = parseInt(value2);
  var v3 = parseInt(value3);
  if (v1 > 12 || v1 < 1) return false;
  if (v2 > 31 || v2 < 1) return false;
  if (v2 == 31) if (v1 == 2 || v1 == 4 || v1 == 6 || v1 == 9 || v1 == 11) return false;
  if (v1 != 2) return true;
  if (v2 < 29) return true;
  if (v2 == 30) return false;
  if (v3 % 400 == 0)
        return true;
  else if (v3 % 100 == 0)
        return false;
  else if (v3 % 4 == 0)
        return true;
  else
        return false; 
}

My first tester is something that asks for three text inputs and, if the isValidDate function returns false, displays an alert. If not, it forwards to a blank html page. However, I tried this:

function validate() {
  if (!isValidDate("a", "a", "a")) {
  alert("wrong");
  return false;
  }
}

and the alert never displayed and it forwarded every time. Strangely enough, this still happened when I removed the exclamation point in front of isValidDate. I also tried swapping the double quotation marks for single, but that didn't fix the problem either. The same thing happens with my tester for is_int. I have no idea where I'm going wrong.

joseph
  • 767
  • 3
  • 8
  • 16
  • You can use the built-in function [`isNaN`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/isNaN) to check whether strings are valid numbers. See http://stackoverflow.com/questions/175739/is-there-a-built-in-way-in-javascript-to-check-if-a-string-is-a-valid-number/175787#175787 – Jon Gauthier Aug 05 '11 at 00:54
  • isNaN is a little different from my function. For example, isNaN("") returns false because "" is equal to 0 according to that function. I don't want "" to be a number so I used mine instead. – joseph Aug 05 '11 at 01:06
  • How about `parseInt(some_string, 10) == some_string`? – Jon Gauthier Aug 05 '11 at 01:08

5 Answers5

2

I know you didn't ask for it, but here's a much more valid way to check for dates, and it handles odd dates more consistently:

function isValidDate(year, month, day) {
    var d = new Date(parseInt(year,10), parseInt(month, 10)-1, parseInt(day, 10), 0, 0, 0);
    return d.getFullYear() == year &&
           (d.getMonth()+1) == month &&
           d.getDate() == day;
}

isValidDate("2011", "08", "04"); // true
isValidDate("bob", "08", "04"); // false
isValidDate("1979", "1", "1"); // true

Fiddle with it: http://jsfiddle.net/2WJCv/

Alternate HTML-only link: http://pastehtml.com/view/b2se2lk9k.html

OverZealous
  • 39,252
  • 15
  • 98
  • 100
  • jsfiddle isn't working for me (weird proxy problem in my connection) so I can't try your example out (and am too lazy to try it locally), but does it handle non-numeric values? What does `parseInt(month,10)-1` do if month is "test"? – nnnnnn Aug 05 '11 at 01:19
  • parseInt(val,10) attempts to convert a string to a number. If that string is invalid, it returns `NaN`. The `-1` is because the `Date` constructor requires 0-based months. Hang on, I'll get you another link to try. (Edit, oops, meant NaN.) – OverZealous Aug 05 '11 at 01:22
  • +1 as this is a good method—only need to test 2 out of 3 conditions at the end though. The extra one doesn't hurt, it's just redundant. Also no need to set the hours, minutes and seconds, but again, doesn't hurt. – RobG Aug 05 '11 at 01:27
  • @OverZealous - yeah, I know `parseInt` can return `NaN`, and I know about the 0-based months (I don't understand _why_ they're 0-based, but I know about it). What I was really asking is what is the value of `NaN - 1`, and what happens when you pass that value to the `Date` constructor? Thanks for taking the trouble with the other link. – nnnnnn Aug 05 '11 at 02:05
  • `NaN +/- anything` is still `NaN` It's a bizarro special construct in JS. Luckily, passing NaN to the Date constructor just returns an "invalid date", where each date part is `NaN`. Also luckily, `NaN` does not equal anything, so the test still works. – OverZealous Aug 05 '11 at 02:07
  • @nnnnnn - zero based months because javascript copied Java's date object (and defects, e.g. getYear returning two digit year) so that's what it has. – RobG Aug 07 '11 at 04:03
0

I think your problem is in the isValidDate() function: Should be function isValidDate(value1, value2, value3) I got an alert using that. Hope that helps! :)

bozdoz
  • 12,550
  • 7
  • 67
  • 96
0

If you take the illegal javascript out, it seems to work for me in this jsFiddle: http://jsfiddle.net/jfriend00/ae9aC/.

In your code, I changed this:

function isValidDate(value1:String, value2:String, value3:String)

to this:

function isValidDate(value1, value2, value3)

And, the jsFiddle alerts false when passed isValidDate("a", "a", "a").

FYI, there are a lot of ways this function could be improved. To start with, I would suggest that you change value1, value2 and value3 to month, day, year and similarly v1, v2 and v3 so the function is a lot more self describing.

Also, parseInt() should always be passed the radix parseInt(str, 10) otherwise it will "guess" the radix based on the contents of the string.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

Your function declaration is invalid:

function isValidDate(value1:String, value2:String, value3:String) {
  // your code here
}

JavaScript function parameters and variable declarations don't have types, so you need to say:

function isValidDate(value1, value2, value3) {
  // your code here
}

(An unrelated suggestion: name your parameters and variables more meaningfully. If you expect month, day, year, why not call them that? Especially when dealing with dates where a lot of countries normally say day, month, year rather than month, day, year.

Another unrelated suggestion: look into regular expressions.)

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • Thanks this was a good answer too. I inserted the :String after the variables after doing a cursory Google search to figure out why my method didn't work before. I must have changed something else in between so when my method body finally was correct it still wouldn't run, but I didn't remember changing anything else so I got really confused. – joseph Aug 07 '11 at 01:09
0

If you like doing it long hand and without using the Date constructor, try:

function validDate(y, m, d) {
  // Days in month
  var days = [,31,28,31,30,31,30,31,31,30,31,30,31];
  // Adjust February it's a leap year
  if (m == 2 && (!(y%4) && y%100) || !(y%400)) {
    days[2] = 29;
  }
  // Check date in month
  return d <= days[+m];
}

It may be faster, or not. :-)

RobG
  • 142,382
  • 31
  • 172
  • 209