Home > OS >  RegEx: date/time (sub)string
RegEx: date/time (sub)string

Time:01-30

I am trying to validate, with a RegEx, a user input to a date/time field in the following format: yyyy-mm-dd HH:mm. Since a user would type this one character at a time, the RegEx also needs to allow for all the substrings (e.g., yyyy-mm, yyyy-mm-dd H, etc.).

For example, the following date 2022-01-29 11:59 or any substring of it, such as (empty string), 202, 2022-01-, 2022-01-29, etc. should match. Strings like 2022-13, 222- or 2024-01-01 23:111 should not match.

I am trying something like,

[0-9]{4}?-?(0[1-9]|1[0-2])-?(0[1-9]|[1-2][0-9]|3[0-1])? ?(2[0-3]|[01][0-9])?:?[0-5]?[0-9]?$

making every character optional, but it does not work since it can just skip parts of the string, e.g. 2022-29 returns match...

CodePudding user response:

It becomes a bit convoluted if you want to match number ranges properly as you type. Here is a regex solution with test cases that has many nested groups (to allow partial input) and validates the ranges of month, day, hours, and minutes:

const regex = /^([0-9]{0,3}|[0-9]{4}(-([01]|(0[1-9]|1[0-2])(-([0-3]|(0[1-9]|[12][0-9]|3[01])( ([0-2]|([0-1][0-9]|2[0-3])(:([0-5]|([0-4][0-9]|5[0-9]))?)?)?)?)?)?)?)?)$/;

[
  '',
  '2',
  '20',
  '202',
  '2022',
  '2022-',
  '2022-0',
  '2022-01',
  '2022-01-',
  '2022-01-2',
  '2022-01-29',
  '2022-01-29 ',
  '2022-01-29 1',
  '2022-01-29 11',
  '2022-01-29 11:',
  '2022-01-29 11:5',
  '2022-01-29 11:59',
  '202-01',
  '2022-1-1',
  '2022-13',
  '2022-01-32',
  '2024-01-01 24',
  '2024-01-01 01:60',
  '2024-01-01 23:111'
].forEach(str => console.log(str, '=>', regex.test(str)));

Output:

 => true
2 => true
20 => true
202 => true
2022 => true
2022- => true
2022-0 => true
2022-01 => true
2022-01- => true
2022-01-2 => true
2022-01-29 => true
2022-01-29  => true
2022-01-29 1 => true
2022-01-29 11 => true
2022-01-29 11: => true
2022-01-29 11:5 => true
2022-01-29 11:59 => true
202-01 => false
2022-1-1 => false
2022-13 => false
2022-01-32 => false
2024-01-01 24 => false
2024-01-01 01:60 => false
2024-01-01 23:111 => false

Hierarchy of regex:

  • ^( -- start of string & group
    • [0-9]{0,3} -- 0 to 3 digits for partial year
  • | -- logical or
    • [0-9]{4} --
    • ( --
      • - -- dash
      • ( --
        • [01] -- one digit of month
      • | -- logical or
        • (0[1-9]|1[0-2]) -- two digits of month
        • ( --
          • - -- dash
          • ( --
            • [0-3] -- one digit of day
          • | -- logical or
            • (0[1-9]|[12][0-9]|3[01]) -- two digits of day
            • ( --
              • -- space
              • ( --
                • [0-2] -- one digit of hours
              • | -- logical or
                • ([0-1][0-9]|2[0-3]) -- two digits of hours
                • ( --
                  • : -- colon
                  • ( --
                    • [0-5] -- one digit of minutes
                  • | -- logical or
                    • ([0-4][0-9]|5[0-9]) -- two digits of minutes
                  • )? --
                • )? --
              • )? --
            • )? --
          • )? --
        • )? --
      • )? --
    • )? --
  • )$ -- end of string and group

Learn more about regex: https://twiki.org/cgi-bin/view/Codev/TWikiPresentation2018x10x14Regex

  • Related