import re


def rfc3339_datetime_re(anchor=True):
    """
    Returns a regular expression for syntactic validation of ISO date-times, RFC-3339 date-times
    to be precise.


    >>> bool( rfc3339_datetime_re().match('2013-11-06T15:56:39Z') )
    True

    >>> bool( rfc3339_datetime_re().match('2013-11-06T15:56:39.123Z') )
    True

    >>> bool( rfc3339_datetime_re().match('2013-11-06T15:56:39-08:00') )
    True

    >>> bool( rfc3339_datetime_re().match('2013-11-06T15:56:39.123+11:00') )
    True

    It anchors the matching to the beginning and end of a string by default ...

    >>> bool( rfc3339_datetime_re().search('bla 2013-11-06T15:56:39Z bla') )
    False

    ... but that can be changed:

    >>> bool( rfc3339_datetime_re( anchor=False ).search('bla 2013-11-06T15:56:39Z bla') )
    True

    >>> bool( rfc3339_datetime_re( anchor=False ).match('2013-11-06T15:56:39Z bla') )
    True

    Keep in mind that re.match() always anchors at the beginning:

    >>> bool( rfc3339_datetime_re( anchor=False ).match('bla 2013-11-06T15:56:39Z') )
    False

    It does not check whether the actual value is a semantically valid datetime:

    >>> bool( rfc3339_datetime_re().match('9999-99-99T99:99:99.9-99:99') )
    True

    If the regular expression matches, each component of the matching value will be exposed as a
    captured group in the match object.

    >>> rfc3339_datetime_re().match('2013-11-06T15:56:39Z').groups()
    ('2013', '11', '06', '15', '56', '39', None, 'Z')
    >>> rfc3339_datetime_re().match('2013-11-06T15:56:39.123Z').groups()
    ('2013', '11', '06', '15', '56', '39', '123', 'Z')
    >>> rfc3339_datetime_re().match('2013-11-06T15:56:39.123-08:30').groups()
    ('2013', '11', '06', '15', '56', '39', '123', '-08:30')
    """
    return re.compile(
        ('^' if anchor else '') +
        '(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(Z|[+-]\d{2}:\d{2})' +
        ('$' if anchor else ''))