This function checks a string s to see if
it is a valid date string as described in the specification.
Although the ISO standard requires left zeroes on all
three units, we'll be a little lax about the month and
year. However, to prevent a repetition of that ugly Y2K
business, we'll absolutely require four digits for the
year. The compiled regular expression DATE_PAT implements these rules. YEAR_FIELD, MONTH_FIELD, and
DAY_FIELD are the group names used to
retrieve the values of the year, month, and day once the
pattern has matched.
# - - - p a r s e D a t e
YEAR_FIELD = "Y"
MONTH_FIELD = "M"
DAY_FIELD = "D"
dateRe = (
r'(' # Begin YEAR_FIELD
r'?P<%s>' # Name this group YEAR_FIELD
r'\d{4}' # Match exactly four digits
r')' # End YEAR_FIELD
r'\-' # Matches one hyphen
r'(' # Begin MONTH_FIELD
r'?P<%s>' # Name this group MONTH_FIELD
r'\d{1,2}' # Matches one or two digits
r')' # End MONTH_FIELD
r'\-' # Matches "-"
r'(' # Begin DAY_FIELD
r'?P<%s>' # Name this group DAY_FIELD
r'\d{1,2}' # Matches one or two digits
r')' # End DAY_FIELD
r'$' # Make sure all characters match
) % (YEAR_FIELD, MONTH_FIELD, DAY_FIELD)
DATE_PAT = re.compile ( dateRe )
def parseDate ( s ):
"""Validate and convert a date in external form.
[ s is a string ->
if s is a valid external date string ->
return that date as a datetime.date instance
else -> raise SyntaxError ]
"""
If DATE_PAT matches s,
we'll get back a match instance; otherwise
we get back None.
#-- 1 --
# [ if DATE_PAT matches s ->
# m := a match instance describing the match
# else -> raise SyntaxError ]
m = DATE_PAT.match ( s )
if m is None:
raise SyntaxError, ( "Date does not have pattern YYYY-DD-MM: "
"'%s'" % s )
We retrieve the contents of the three fields using the
match instance's .group()
method, then construct and return a datetime.date instance.
#-- 2 --
year = int ( m.group ( YEAR_FIELD ) )
month = int ( m.group ( MONTH_FIELD ) )
day = int ( m.group ( DAY_FIELD ) )
#-- 3 --
return datetime.date ( year, month, day )