25

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).

1

6 Answers 6

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';
}
Sign up to request clarification or add additional context in comments.

6 Comments

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.
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)
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...
@ParthThakkar Thanks. However now it gets complicated. I wonder if there is a simpler solution.
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!
|
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/

2 Comments

Great, but instead of returning undefined where parsing fails, it should return an invalid date, i.e. new Date(NaN).
To do this replace the return undefined with return date(NaN)
3

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);

Comments

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()}`)
);

Comments

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'));

Comments

0

This worked for me:

    function parse(str) {
      const year = str.substring(0, 4)
      const month = str.substring(4, 6)
      const day = str.substring(6, 8)
      return new Date(`${year}-${month}-${day}`)
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.