views:

731

answers:

5

I am trying to compare two textbox values on an aspx form. Both the values represent dates. They are formatted like "dd/MMM/yyyy". How can I compare them in JavaScript to see if they are not equal and which one is greater etc.?

Does JavaScript have a date constructor for strings like this? Any tips would be appreciated.

A: 

Convert the dates to a UNIX timestamp, then just compare the values.

if (date1.getTime() > date2.getTime()) alert("bla");

To be a bit more precise, the getTime function returns the number of milliseconds since 1970/01/01: http://www.w3schools.com/jsref/jsref_getTime.asp

And a bit of explanation about UNIX time : http://en.wikipedia.org/wiki/Unix_time

rnaud
Nice idea, how he can do that? yes code helps :)
Byron Whitlock
I think that's exactly what he's having problems with. That is, converting the string representation into a value that can be processed further.
Matti Virkkunen
any example? I've never heard of UNIX timestamp. Thanks!
Hcabnettek
A: 

Read about the Date object.

scaryzet
+2  A: 

You want to use Date.parse() So to convert to a Unix timestamp in milliseconds:

var d = Date.parse("Jul 8, 2005");
> 1120773600000 

You can now manipulate the date as an integral value.

Byron Whitlock
yes this is better, date objects are already comparable, so if you have a string, there you go.
rnaud
`Date.parse()` is really useful. It saves you the trouble of having to do all of that input parsing yourself. This works the way you'd hope it does: `new Date(Date.parse("21/May/2010"))`
Christopher Parker
hmm, .parse doesn't seem to like the date in that format. I get a NAN when I try. Am I missing something?
Hcabnettek
Date parse can't really be relied upon. What it is (said to be) guaranteed to do, is parse *strings returned by the implementation's `toString()` and `toUTCString()` methods*. And guess what? The format of the output from those is implementations dependent :( It would be nice if they would return some defined format of course.
npup
A: 

Sadly, the Date.parse way isn't reliable, not even for ISO format.

Here below is a quick one-off-ish function for parsing dates of the very format you currently use. If you like you can add some sanity checking to see if the day is within each month's bounds (don't forget about leapyear then :)), but if one has reasonable control over the strings one sends in, this works.

function parseThisYourVeryKnownFormatToDate(dateString /* '12/Jun/2010' */) {
  function getMonthIdx(monthName) {
    var months = {
      'Jan':0, 'Feb':1, 'Mar':2, 'Apr':3, 'May':4, 'Jun':5
      , 'Jul':6, 'Aug':7, 'Sep':8, 'Oct':9, 'Nov':10, 'Dec':11
    };
    return months[monthName];
  }
  var format = /^(\d+)\/(\w{3})\/(\d{4})$/;
  var match = format.exec(dateString);
  if (!match) {return undefined;}
  var day = match[1], monthIdx = getMonthIdx(match[2]), year = match[3];
  return new Date(year, monthIdx, day);
}

var testDates = ['10/Jan/2008', '15/Jun/1971', '31/Dec/1999', 'bogus/date/foo'];
for (var idx=0, len=testDates.length; idx<len; ++idx) {
  console.log(parseThisYourVeryKnownFormatToDate(testDates[idx])); // real date objects, except for the last
}

var d0 = (parseThisYourVeryKnownFormatToDate('15/Apr/2009'));
var d1 = (parseThisYourVeryKnownFormatToDate('12/Apr/2009'));
console.log(d0+' is after '+d1+': '+(d0.getTime()>d1.getTime())); // says true
console.log(d1+' is after '+d0+': '+(d1.getTime()>d0.getTime())); // says false
console.log(d0+' is after '+d0+': '+(d0.getTime()>d0.getTime())); // says false
npup
A: 

If all you want to do a comparison, then you can just do:

compareDates(d1, d2) {
  d1 = d1.split("/").reverse().join("/");
  d2 = d2.split("/").reverse().join("/");
  return d1 == d2 ? 0 : d1 < d2 ? : -1 : 1;
}

Assuming the arguments are in the format "dd/mm/yyyy", this function will return 0 if d1 == d2, -1 if d1 < d2 and 1 if d1 > d2.

PS: if your Arrays don't know how to reverse, teach them how:

Array.prototype.reverse = function() {
 var a = [];
 for(var i=this.length; i; i--) a.push(this[i-1]);
 return a;
}

EDIT: ok I didn't notice the "MMM" format. I guess I would use a hash of month names, then.

function compareDates(date1,date2) {
 var d1 = date1.split("/").reverse();
 var d2 = date2.split("/").reverse();

 var months = { 'Jan':'01', 'Feb':'02' }; // ...

 d1[1] = months[d1[1]] || '00';
 d2[1] = months[d2[1]] || '00';

 date1 = d1.join("/");
 date2 = d2.join("/");

 return date1 == date2 ? 0 : date1 < date2 ? : -1 : 1;
}
Alsciende