Twitter: raymondcamden


Address: Lafayette, LA, USA

Date Fields, JavaScript, and the things that make me go crazy...

06-10-2014 2,872 views JavaScript, HTML5 4 Comments

Just a quick note to detail some interesting issues I ran into last night. I was writing a very simple report tool for a client. He has a process that runs a large set of MLS queries and does a lot of - well - stuff. It is a slow process so I've set it up so that it runs one day at a time based on a simple URL parameter. While this works well enough he asked if I could build a simple front end to it so he could select two dates and have it process each day one by one. Simple, right?

I decided to use two text fields using type="date". This gives me nice date controls in modern browsers and since I have an user base of one, I'm pretty confident I can be sure that it will be supported on his browser. Just in case you haven't seen this in action, this is how it renders in Chrome.

Clicking the field gives an automatic calendar control.

In case you're wondering, in Firefox, and any other browser that decided it was more important to support canvas for HTML gaming than form fields that most people use (sorry, I'm not bitter, honest), you get a plain text field. I can skip downloading a library just to add a control and it "breaks" perfectly - the user can still type in a date. A win-win.

So, the first issue I ran into was validation. Now, I know I said earlier that I have a small user base, so I could have just told him not to screw up, but I wanted to do some validation at least. Can't hurt, right? Turns out checking to see if a value is a proper date is a bit more difficult than you would imagine. So for example, if you make a new Date object and pass 99/99/99, you get a Date object back. It recognizes that the value is bad, but you still have a date object.

A bit of Googling turned up this answer, which I'm duplicating here:

function isDate(d) {
	if ( Object.prototype.toString.call(d) === "[object Date]" ) {
	  // it is a date
	  if ( isNaN( d.getTime() ) ) {  // d.valueOf() could also work
		// date is not valid
		return false;
	  }
	  else {
		// date is valid
		return true;
	  }
	}
	else {
	  // not a date
		return false;
	}
}

Essentially, his solution checks to see if the value is a Date object and then sees if the time value is a valid number. If it isn't a date object, then it fails as well. Note - his solution on the Stack Overflow page didn't have return statements in it. Don't do what I did and just cut and paste as is and wrap in a function. That was kinda lame, Ray.

Ok, so far so good. But then came the thing that really threw me for a loop. Last night I was testing and picking today (June 9th) as the date. I got the value from the form field, made a new date out of it, and sent it to console.log, just to be sure. (I do that a lot - use the console just to ensure that the values I think I'm working with are the values I actually have.) So again - I picked the current date. It showed 6/9/2014. In the console I got: Sun Jun 08 2014 19:00:00 GMT-0500 (CDT).

Yeah, let that sink in a bit.

Ok, so what the heck? Luckily I was able to quickly find a solution here: HTML5 Date Pickers and JavaScript Date Objects. To quote Dave Leeds:

According to the specifications, date picker controls will have a value in RFC 3339 format, which is a profile of ISO 8601. When you new up a JavaScript Date in that format, you'll get a date that accounts for your timezone.

As he goes on to say, the values are GMT, not the user's time zone. Because... I don't freaking know. I mean, in what universe would a typical user pick a date on a calendar and think, "Oh my god I hope this is GMT because I do EVERYTHING IN GMT!"

*sigh* These are the things that drive me crazy about web development. Luckily Dave has a simple fix. It feels like a hack, but it seems to work fine for me: var dateString = somedate.replace(/-/g, "/"). Basically changing 6-9-2014 to 6/9/2014.

So um... yeah. Keep this in mind.

4 Comments

  • Commented on 06-11-2014 at 10:19 AM
    Here's the demo: http://jsfiddle.net/simevidas/PLttb/
  • Commented on 06-11-2014 at 10:41 AM
    For folks confused by Sime's comment, he means a demo of what is talked about above.

    Sorry if that was obvious Sime but when I first saw your comment, I thought I missed an earlier one. Thanks for adding this!
  • PhistucK #
    Commented on 06-14-2014 at 4:54 AM
    You can shorten (or not use it at all) that isDate("99/99/9999), to -
    isNaN(Date.parse("99/99/99"))

    For supporting browsers, just use input.valueAsDate (maybe null check it first).
  • Commented on 06-14-2014 at 9:50 AM
    See the SO link. They discuss why using that isn't enough.

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead. Text wrapped in asterisks (*) will be bold and text wrapped in underscores (_) will be italicized.

Leave this field empty