24

This is a noob question:

How to parse a date in format "YYYYmmdd" without external libraries ? If the input string is not in this format I would like to get invalid Date (or undefined if it will be easier).

Michael
  • 10,185
  • 12
  • 59
  • 110

6 Answers6

39
function parse(str) {
    if(!/^(\d){8}$/.test(str)) return "invalid date";
    var y = str.substr(0,4),
        m = str.substr(4,2),
        d = str.substr(6,2);
    return new Date(y,m,d);
}

Usage:

parse('20120401');

UPDATE:

As Rocket said, months are 0-based in js...use this if month's aren't 0-based in your string

function parse(str) {
    if(!/^(\d){8}$/.test(str)) return "invalid date";
    var y = str.substr(0,4),
        m = str.substr(4,2) - 1,
        d = str.substr(6,2);
    return new Date(y,m,d);
}

UPDATE:

More rigorous checking for validity of date. Adopted HBP's way to validate date.

function parse(str) {
    var y = str.substr(0,4),
        m = str.substr(4,2) - 1,
        d = str.substr(6,2);
    var D = new Date(y,m,d);
    return (D.getFullYear() == y && D.getMonth() == m && D.getDate() == d) ? D : 'invalid date';
}
Parth Thakkar
  • 5,427
  • 3
  • 25
  • 34
  • 3
    Note: in JavaScript, months are zero-indexed, so you may want to use `new Date(y, m-1, d);`, otherwise `20120401` will be May 1st, not April 1st. – gen_Eric May 17 '12 at 15:25
  • What if the input is `00005050`? It is invalid string but `new Date('0000', '50', 50')` is `Tue Jun 09 1903 00:00:00 GMT+0300 (IDT)` – Michael May 17 '12 at 15:30
  • all right...one more update coming up...if you still have problems, do tell them so that i can improve this answer...actually i did think of this, but thought this might be a trivial case, hence didn't add any code for __detailed__ validation... – Parth Thakkar May 17 '12 at 15:45
  • @ParthThakkar Thanks. However now it gets complicated. I wonder if there is a simpler solution. – Michael May 17 '12 at 16:00
  • All right...another update coming up...this time, I've adopted HBP's way to validate date, much simpler and easier to understand! An upvote to HBP! – Parth Thakkar May 17 '12 at 16:15
  • @ParthThakkar—note that the date can be validated by just checking the month (per HBP's answer). – RobG Oct 22 '15 at 23:13
6

A more robust version validating the numbers :

 function parse (str) {
        // validate year as 4 digits, month as 01-12, and day as 01-31 
        if ((str = str.match (/^(\d{4})(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$/))) {
           // make a date
           str[0] = new Date (+str[1], +str[2] - 1, +str[3]);
           // check if month stayed the same (ie that day number is valid)
           if (str[0].getMonth () === +str[2] - 1)
              return str[0];
        }
        return undefined;
 }

See fiddle at : http://jsfiddle.net/jstoolsmith/zJ7dM/

I recently wrote a much more capable version you can find here : http://jsfiddle.net/jstoolsmith/Db3JM/

HBP
  • 15,685
  • 6
  • 28
  • 34
  • Great, but instead of returning *undefined* where parsing fails, it should return an invalid date, i.e. `new Date(NaN)`. – RobG Jan 31 '17 at 05:03
  • To do this replace the `return undefined` with `return date(NaN)` – HBP Jan 31 '17 at 06:40
4

simplistic answer maybe, without checks, but fast...

var date = parseInt(date);
new Date(date / 10000, date % 10000 / 100, date % 100);

or, if months are not zero based in the source,

new Date(date / 10000, (date % 10000 / 100) - 1, date % 100);
Milimetric
  • 13,411
  • 4
  • 44
  • 56
MrE
  • 19,584
  • 12
  • 87
  • 105
1

Example using only the digits in the string:

function toDate(str) {
  var m = str.split(/\D/);
  return new Date(+m[0], +m[1] - 1, +m[2], +m[3], +m[4], +m[5]);
}
    
console.log(toDate("2020-08-23 23:34:45"));
Italo Borssatto
  • 15,044
  • 7
  • 62
  • 88
1

Using newer language features for destructuring assignment:

// Parse YYYYMMDD to Date
function parseYMD(s) {
  let [C,Y,M,D] = s.match(/\d\d/g);
  return new Date(C+Y, M-1, D);
}

['20211125', // Valid date
 '2021112',  // Invalid input
 '20219999'  // Invalid date components
].forEach(d => 
  console.log(`${d} -> ${parseYMD(d).toDateString()}`)
);

Note that this does not validate the date components, any string with 8 or more digits will produce a valid Date. Anything else will produce an invalid Date. If strict parsing is required, consider:

// Parse YYYYMMDD to Date. If any part is out of
// range, return an invalid Date.
function parseYMD(s) {
  let [C,Y,M,D] = s.match(/\d\d/g);
  let d = new Date(C+Y, M-1, D);
  let [yr,mo,da] = d.toLocaleDateString('en-CA').split(/\D/); 
  if (yr != C+Y || mo != M || da != D) {
    d.setTime(NaN);
  }
  return d;
}

['20211125', // Valid date
 '2021112',  // Invalid input
 '20219999'  // Invalid date components
].forEach(d => 
  console.log(`${d} -> ${parseYMD(d).toDateString()}`)
);
RobG
  • 142,382
  • 31
  • 172
  • 209
0

combining HBP's answer and this answer to get a function that parses YYYYMMDDHHmm and here is a fiddle

var parseTS=function(str){
                // validate year as 4 digits, month as 01-12, and day as 01-31
                if ((str = str.match (/^(\d{4})(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])([0-5]\d)$/))) {
                    // make a date
                    str[0] = new Date (+str[1], +str[2] - 1, +str[3], +str[4], +str[5]);
                    // check if month stayed the same (ie that day number is valid)
                    if (str[0].getMonth () === +str[2] - 1) {
                        return str[0];
                    }
                }
                return undefined;
            };

    console.log(parseTS('201501012645'));
Community
  • 1
  • 1
Or Gal
  • 1,298
  • 3
  • 12
  • 20