1# -*- coding: utf-8 -*-
2
3__author__ = """Nicolas Aimetti"""
4__email__ = 'naimetti@yahoo.com.ar'
5__version__ = '0.1.4'
6
7import re
8import calendar
9import six
10
11RFC3339_REGEX_FLAGS = 0
12if six.PY3:
13 RFC3339_REGEX_FLAGS |= re.ASCII
14
15RFC3339_REGEX = re.compile(r"""
16 ^
17 (\d{4}) # Year
18 -
19 (0[1-9]|1[0-2]) # Month
20 -
21 (\d{2}) # Day
22 T
23 (?:[01]\d|2[0123]) # Hours
24 :
25 (?:[0-5]\d) # Minutes
26 :
27 (?:[0-5]\d) # Seconds
28 (?:\.\d+)? # Secfrac
29 (?: Z # UTC
30 | [+-](?:[01]\d|2[0123]):[0-5]\d # Offset
31 )
32 $
33""", re.VERBOSE | RFC3339_REGEX_FLAGS)
34
35
36def validate_rfc3339(date_string):
37 """
38 Validates dates against RFC3339 datetime format
39 Leap seconds are no supported.
40 """
41 m = RFC3339_REGEX.match(date_string)
42 if m is None:
43 return False
44 year, month, day = map(int, m.groups())
45 if not year:
46 # Year 0 is not valid a valid date
47 return False
48 (_, max_day) = calendar.monthrange(year, month)
49 if not 1 <= day <= max_day:
50 return False
51 return True