Easy Date parsing with JavaScript

Posted: November 25th, 2008 | Author: | Filed under: Coding | Tags: , , , | 14 Comments »

Date.fromString()

For the impatient, scroll to the bottom of the page for an interactive example.

Date.fromString() is a method that allows you to easily parse user input into a date. There are currently many implementations of calendar pop-ups that aim to solve a similar problem. However, these calendars are cumbersome to use if the target date is more than a couple months away. The goal of this project is to parse free-form user input into a valid Date object.

Date.fromString() accepts two parameters:

  • input
    string — User input string to parse
  • options optional
    object — An object that can override the default behavior
    { order: 'MDY', strict: false }

Examples

console.log(Date.fromString('Sept 5th, 2006  4:00 pm'));
// Tue Sep 05 2006 16:00:00 GMT-0600 (MDT)
 
console.log(Date.fromString('Sept 5th, 2006  4:23pm'));
// Tue Sep 05 2006 16:23:00 GMT-0600 (MDT)
 
console.log(Date.fromString('Sept 5th, 2006  4pm'));
// Tue Sep 05 2006 16:00:00 GMT-0600 (MDT)
 
console.log(Date.fromString('Sept 5th, 2006  12:34:56 am'));
// Tue Sep 05 2006 00:34:56 GMT-0600 (MDT)
 
console.log(Date.fromString('Sept 5th, 2006  7:30 am'));
// Tue Sep 05 2006 07:30:00 GMT-0600 (MDT)
 
console.log(Date.fromString('2006/09/05  4:23pm'));
// Tue Sep 05 2006 16:23:00 GMT-0600 (MDT)
 
console.log(Date.fromString('2006/09/05'));
// Tue Sep 05 2006 00:00:00 GMT-0600 (MDT)
 
console.log(Date.fromString('9/5/06'));
//Tue Sep 05 2006 00:00:00 GMT-0600 (MDT)
 
console.log(Date.fromString('2/13/78'));
// Mon Feb 13 1978 00:00:00 GMT-0700 (MST)
 
console.log(Date.fromString('Feb 13 09'));
// Fri Feb 13 2009 00:00:00 GMT-0700 (MST)

When part of the date is left off, it fills in the missing parts with today’s details. When these examples were written, it was November 25, 2008.

console.log(Date.fromString('Feb 13th'));
// Wed Feb 13 2008 00:00:00 GMT-0700 (MST)
 
console.log(Date.fromString('2/13'));
// Wed Feb 13 2008 00:00:00 GMT-0700 (MST)
 
console.log(Date.fromString('4pm'))
// Tue Nov 25 2008 16:00:00 GMT-0700 (MST)

If you would rather have the date not fill in those parts, pass the option strict set to true.

console.log(Date.fromString('4pm'))
// Tue Nov 25 2008 16:00:00 GMT-0700 (MST)
 
console.log(Date.fromString('4pm', {strict:true}))
// Invalid Date

Sometimes the date cannot be parsed without ambiguity. In these cases, the default ordering of month/day/year (MDY) is used. To change this behavior, pass the option order set to your preferred ordering; YMD, DMY, etc.

console.log(Date.fromString('09/05/06'));
// Tue Sep 05 2006 00:00:00 GMT-0600 (MDT)
 
console.log(Date.fromString('09/05/06', {order: 'YMD'}));
// Wed May 06 2009 00:00:00 GMT-0600 (MDT)
 
console.log(Date.fromString('09/05/06', {order: 'DMY'}));
// Tue May 09 2006 00:00:00 GMT-0600 (MDT)

Finally, try it for yourself. I have not been able to test this much in browsers other than Firefox on Linux, so if you find any bugs, please let me know.

Options
Input

Output:



The project is hosted at BitBucket and can be found at http://bitbucket.org/mazzarelli/js-date/downloads/.

You can download the source http://bitbucket.org/mazzarelli/js-date/downloads/date.js
or the minified version at http://bitbucket.org/mazzarelli/js-date/downloads/date.min.js.


14 Comments on “Easy Date parsing with JavaScript”

  1. 1 Bill said at 9:08 am on November 26th, 2008:

    Here is a failure case that might be considered valid:

    OPTIONS: MDY
    INPUT: 02091972

    If I put any kind of delimiter between 09 and 1972 (space, -, /) it parses (though not always correctly)

    If I put in a delimiter betwen 09 and 1972 (0209-1972) even with OPTIONS: MDY it parses as Nov 9, 1972 – the day part is ignored.

    i figure if the string can be parsed and contains more than6 characters then all three portions to be parsed have been provided and should be parsed according to the OPTIONS value

    In all of these examples “strict” is turned off

  2. 2 Joey said at 9:14 am on November 26th, 2008:

    Bill,
    Thanks, those are a couple more cases I can add to it.

  3. 3 John Lateral said at 7:42 am on December 17th, 2008:

    Why is:

    MDY
    12/50/2004

    accepted as a valid date? The 50. december does not – as far as I know – exist in any normal calendar. Is it possible to have the function only accept VALID dates?

  4. 4 Thor said at 5:11 am on February 1st, 2009:

    you could run the date through this code to have a check against real date

    http://snipplr.com/view/7875/javascript-validate-date/

  5. 5 esoseRirl said at 12:15 pm on February 24th, 2009:

    Thank you!

  6. 6 Peter Snyder said at 2:32 pm on March 20th, 2009:

    Thanks for this code. I’ve made a couple of additions to make the code with SQL date type 109, ie something like Dec 30 2006 12:38:54:840AM.

    The difference is just a couple of lines. Heres the patch, if you’re interested (i’d also be happy to email it, if you prefer)

    — date.js 2009-03-20 16:57:29.000000000 -0500
    +++ date_new.js 2009-03-20 16:44:47.000000000 -0500
    @@ -36,7 +36,7 @@

    var find_time = function (norm) {
    var obj = {date:norm, time:”};
    - obj.time = norm.replace(/^.*-(\d\d?(:\d\d){1,2}(-(AM|PM))?)-.*$/, ‘$1′);
    + obj.time = norm.replace(/^.*-(\d\d?(:\d\d){1,2}(:\d\d\d)?(-(AM|PM))?)-.*$/, ‘$1′);
    if (obj.time == obj.date)
    obj.time = norm.replace(/^.*-(\d\d?-(AM|PM))-.*$/, ‘$1′);
    if (obj.time == obj.date) obj.time = ”;
    @@ -97,19 +97,20 @@
    };

    var create_absolute = function (obj) {
    -
    var time = obj.time.replace(/[-APM]/g, ”);
    var parts = time.split(‘:’);
    parts[1] = parts[1] || 0;
    - parts[2] = parts[2] || 0;
    + parts[2] = parts[2] || 0;
    + parts[3] = parts[3] || 0;
    var ihr = parseInt(parts[0], 10);
    if (obj.time.match(/-AM-/) && ihr == 12) parts[0] = 0;
    else if (obj.time.match(/-PM-/) && ihr < 12) parts[0] = ihr + 12;
    parts[0] = (“0″ + parts[0]).substring((“0″ + parts[0]).length – 2);
    parts[1] = (“0″ + parts[1]).substring((“0″ + parts[1]).length – 2);
    parts[2] = (“0″ + parts[2]).substring((“0″ + parts[2]).length – 2);
    - time = parts.join(‘:’);
    -
    + time = parts[0]+”:”+parts[1]+”:”+parts[2];
    + var millisecs = parts[3];
    +
    var strict = defaults.opts.strict;
    if (!obj.year && !strict) obj.year = (new Date()).getFullYear();
    var year = parseInt(obj.year, 10);
    @@ -129,6 +130,7 @@

    var date = new Date();
    date.setTime(Date.parse(year + ‘/’ + month + ‘/’ + day + ‘ ‘ + time));
    + date.setMilliseconds(millisecs);
    return date;
    };

  7. 7 Nathan said at 4:07 am on March 31st, 2009:

    Hi, found a problem. If you put in 31/02/2009 (DMY) it changes it to the 3rd of March, which is essentially correct. But it should fail rather than seeming to make up a date. This will happen if you put more days than within a month for any rubbish date.

  8. 8 Joey said at 7:59 am on March 31st, 2009:

    Nathan:

    This is actually something I like. It allows me to do “math” on dates easily.

    I have enough comments here that I need to get around to implementing/fixing, and maybe when I finally do, I’ll include that as an option to reject “rubbish dates”.

    Thanks.

  9. 9 une6 said at 5:45 am on December 6th, 2009:

    best function ever… i’ve been looking for this ever since. good job :)

  10. 10 Qrilka said at 1:32 am on February 10th, 2010:

    console.log(Date.fromString(’01/12/10′, {order: ‘DMY’, strict:true}));
    //Thu Dec 13 2001 00:00:00 GMT+0300 (MSK)

    FAIL :(

  11. 11 Joey said at 8:42 am on February 10th, 2010:

    I’ll have to look into that. I still have some changes from Peter that I need to put into it to. Thanks.

  12. 12 Joey said at 11:15 pm on February 10th, 2010:

    I have implemented Peter’s fix, and fixed another bug in the parsing.

    Qrilka, I got a bad date in that example, but it was a different bad date. Maybe this fix will fix it for you too.

    Anyway, I have moved the code to BitBucket.org, and you can find it at:

    http://bitbucket.org/mazzarelli/js-date/downloads/

  13. 13 prashantchalise said at 11:45 pm on June 13th, 2011:

    Thanks for the issue and thanks for the reply. @Thor

  14. 14 Ajman said at 12:33 am on August 24th, 2012:

    console.log(Date.fromString(‘Sept 5th, 2006 12:34:56 am’));
    // Tue Sep 05 2006 00:34:56 GMT-0600 (MDT)

    The above don’t work.
    My Input : ‘Aug 5, 212 12:34:56 am’
    Output which i get : 24-Aug-2012 00:00:00 PM

    Time is not reading from it. i need even second


Don't be shy...