Parsing short dates

Parsing short dates

Validating and parsing short dates can be a problem when you're not sure if they'll come in D/M/Y or M/D/Y order. I made a basic utility to verify either without adding date library dependency.

/** Validate parts of a separated string to test for a short date's day, month, year. */
const validateDateParts = (d: string, m: string, y: string) => (
  parseInt(m) <= 12 &&
  parseInt(d) <= 31 &&
  d.length <= 2 &&
  m.length <= 2 &&
  (y.length === 2 || y.length === 4) &&
  (y.length === 4
    ? parseInt(y, 10) >= 1000
    : !isNaN(parseInt(y, 10))
  )
)

/** Check if date is valid as DD/MM/YYYY | DD/MM/YY | DD-MM-YY | DD-MM-YYYY */
const isShortDateDmy = (value: string) => {
  const [d, m, y] = value.split(/[/-]/)
  const date = new Date(parseInt(y, 10), parseInt(m, 10) - 1, parseInt(d, 10))
  return (validateDateParts(d, m, y) && !isNaN(date.getTime()))
}

/** Check if date is valid as MM/DD/YYYY | MM/DD/YY | MM-DD-YY | MM-DD-YYYY */
const isShortDateMdy = (value: string) => {
  const [m, d, y] = value.split(/[/-]/)
  const date = new Date(parseInt(y, 10), parseInt(m, 10) - 1, parseInt(d, 10))
  return (validateDateParts(d, m, y) && !isNaN(date.getTime()))
}

E.g.

isShortDateDmy('13/01/2001') // => true
isShortDateDmy('01/13/2002') // => false
isShortDateDmy('2003/01/01') // => false

isShortDateMdy('13/01/2001') // => false
isShortDateMdy('01/13/2002') // => true
isShortDateMdy('2003/01/01') // => false

There's no way to test the format on dates early in a month, like 01/01/20. But you can use these functions to test a whole data set with reasonable confidence.

['01/01/20', '20/01/20'].every(isShortDateDmy) // => true
['01/01/20', '20/01/20'].every(isShortDateMdy) // => false