Skip to content

Instantly share code, notes, and snippets.

@znnahiyan
Last active January 5, 2022 10:20
Show Gist options
  • Save znnahiyan/30c8c17d3c6693b373ad434a7b5988fe to your computer and use it in GitHub Desktop.
Save znnahiyan/30c8c17d3c6693b373ad434a7b5988fe to your computer and use it in GitHub Desktop.
ISO-8601 date regex with leap year validation. Diagram: https://www.debuggex.com/r/XzZWlrzeqE2NZQAu
'''ISO-8601 date regex with leap-year validation.'''
import re
date_regex = re.compile(r"^(\d{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|02-(0[1-9]|1[0-9]|2[0-8]))|(\d{2}(0[48]|[2468][048]|[13579][26])|([02468][48]|[13579][26])00)-02-29)$")
# Piece-wise regex by month/leap year:
#
# 31 days: Jan/Mar/May/Jul/Aug/Oct/Dec
# \d{4}-(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])
# yyyyy mmmmmmmmmmmmmmmm dddddddddddddddddddddddd
#
# 30 days: Apr/Jun/Sep/Nov
# \d{4}-(0[469]|11)-(0[1-9]|[12][0-9]|30)
# yyyyy mmmmmmmmmmm ddddddddddddddddddddd
#
# 28 days: Feb (common year)
# \d{4}-02-(0[1-9]|1[0-9]|2[0-8])
# yyyyy mm dddddddddddddddddddddd
#
# 29 days: Feb (leap year: divisible by 4, not divisible by 100, divisible by 400)
# \d{2}(0[48]|[2468][048]|[13579][26])-02-29
# yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy-mm-dd
# ([02468][48]|[13579][26])00-02-29
# yyyyyyyyyyyyyyyyyyyyyyyyyyy-mm-dd
^(\d{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|02-(0[1-9]|1[0-9]|2[0-8]))|(\d{2}(0[48]|[2468][048]|[13579][26])|([02468][48]|[13579][26])00)-02-29)$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment