# Path: resync/w3c_datetime.py
# def str_to_datetime(s, context='datetime'):
#     """Set timestamp from an W3C Datetime Last-Modified value.
# 
#     The sitemaps.org specification says that <lastmod> values
#     must comply with the W3C Datetime format
#     (http://www.w3.org/TR/NOTE-datetime). This is a restricted
#     subset of ISO8601. In particular, all forms that include a
#     time must include a timezone indication so there is no
#     notion of local time (which would be tricky on the web). The
#     forms allowed are:
# 
#         Year:
#           YYYY (eg 1997)
#         Year and month:
#           YYYY-MM (eg 1997-07)
#         Complete date:
#           YYYY-MM-DD (eg 1997-07-16)
#         Complete date plus hours and minutes:
#           YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
#         Complete date plus hours, minutes and seconds:
#           YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
#         Complete date plus hours, minutes, seconds and a decimal fraction
#         of a second
#           YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
#         where:
#           TZD  = time zone designator (Z or +hh:mm or -hh:mm)
# 
#     We do not anticipate the YYYY and YYYY-MM forms being used but
#     interpret them as YYYY-01-01 and YYYY-MM-01 respectively. All
#     dates are interpreted as having time 00:00:00.0 UTC.
# 
#     Datetimes not specified to the level of seconds are intepreted
#     as 00.0 seconds.
#     """
#     t = None
#     if (s is None):
#         return(t)
#     if (s == ''):
#         raise ValueError('Attempt to set empty %s' % (context))
#     # Make a date into a full datetime
#     m = re.match(r"\d\d\d\d(\-\d\d(\-\d\d)?)?$", s)
#     if (m is not None):
#         if (m.group(1) is None):
#             s += '-01-01'
#         elif (m.group(2) is None):
#             s += '-01'
#         s += 'T00:00:00Z'
#     # Now have datetime with timezone info
#     m = re.match(r"(.*\d{2}:\d{2}:\d{2})(\.\d+)([^\d].*)?$", s)
#     # Chop out fractional seconds if present
#     fractional_seconds = 0
#     if (m is not None):
#         s = m.group(1)
#         if (m.group(3) is not None):
#             s += m.group(3)
#         fractional_seconds = float(m.group(2))
#     # Now check that only allowed formats supplied (the parse
#     # function in dateutil is rather lax) and separate out
#     # timezone information to be handled separately
#     #
#     # Seems that one should be able to handle timezone offset
#     # with dt.tzinfo module but this has variation in behavior
#     # between python 2.6 and 2.7... so do here for now
#     m = re.match(r"(\d\d\d\d\-\d\d\-\d\dT\d\d:\d\d(:\d\d)?)(Z|([+-])"
#                  r"(\d\d):(\d\d))$", s)
#     if (m is None):
#         raise ValueError("Bad datetime format (%s)" % s)
#     str = m.group(1) + 'Z'
#     dt = dateutil_parser.parse(str)
#     offset_seconds = 0
#     if (m.group(3) != 'Z'):
#         hh = int(m.group(5))
#         mm = int(m.group(6))
#         if (hh > 23 or mm > 59):
#             raise ValueError("Bad timezone offset (%s)" % s)
#         offset_seconds = hh * 3600 + mm * 60
#         if (m.group(4) == '-'):
#             offset_seconds = -offset_seconds
#     # timetuple() ignores timezone information so we have to add in
#     # the offset here, and any fractional component of the seconds
#     return(timegm(dt.timetuple()) + offset_seconds + fractional_seconds)
# 
# def datetime_to_str(dt='now', no_fractions=False):
#     """The Last-Modified data in ISO8601 syntax, Z notation.
# 
#     The lastmod is stored as unix timestamp which is already
#     in UTC. At preesent this code will return 6 decimal digits
#     if any fraction of a second is given. It would perhaps be
#     better to return only the number of decimal digits necessary,
#     up to a resolution of 1 microsecond.
# 
#     Special cases:
#     - Returns datetime str for 'now' if no parameter given.
#     - Returns None if None is supplied.
#     """
#     if (dt is None):
#         return None
#     elif (dt == 'now'):
#         dt = time.time()
#     if (no_fractions):
#         dt = int(dt)
#     else:
#         dt += 0.0000001  # improve rounding to microseconds
#     return datetime.utcfromtimestamp(dt).isoformat() + 'Z'


import unittest
import re
from resync.w3c_datetime import str_to_datetime, datetime_to_str


def rt(dts):
    """ Do simple round-trip """
    return(datetime_to_str(str_to_datetime(dts)))


class TestW3cDatetime(unittest.TestCase):

    def test01_datetime_to_str(self):
        """Writing."""
        self.assertEqual(datetime_to_str(0),
                         "1970-01-01T00:00:00Z")
        self.assertEqual(datetime_to_str(0.000001),
                         "1970-01-01T00:00:00.000001Z")

# Path: resync/w3c_datetime.py
# def str_to_datetime(s, context='datetime'):
#     """Set timestamp from an W3C Datetime Last-Modified value.
# 
#     The sitemaps.org specification says that <lastmod> values
#     must comply with the W3C Datetime format
#     (http://www.w3.org/TR/NOTE-datetime). This is a restricted
#     subset of ISO8601. In particular, all forms that include a
#     time must include a timezone indication so there is no
#     notion of local time (which would be tricky on the web). The
#     forms allowed are:
# 
#         Year:
#           YYYY (eg 1997)
#         Year and month:
#           YYYY-MM (eg 1997-07)
#         Complete date:
#           YYYY-MM-DD (eg 1997-07-16)
#         Complete date plus hours and minutes:
#           YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
#         Complete date plus hours, minutes and seconds:
#           YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
#         Complete date plus hours, minutes, seconds and a decimal fraction
#         of a second
#           YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
#         where:
#           TZD  = time zone designator (Z or +hh:mm or -hh:mm)
# 
#     We do not anticipate the YYYY and YYYY-MM forms being used but
#     interpret them as YYYY-01-01 and YYYY-MM-01 respectively. All
#     dates are interpreted as having time 00:00:00.0 UTC.
# 
#     Datetimes not specified to the level of seconds are intepreted
#     as 00.0 seconds.
#     """
#     t = None
#     if (s is None):
#         return(t)
#     if (s == ''):
#         raise ValueError('Attempt to set empty %s' % (context))
#     # Make a date into a full datetime
#     m = re.match(r"\d\d\d\d(\-\d\d(\-\d\d)?)?$", s)
#     if (m is not None):
#         if (m.group(1) is None):
#             s += '-01-01'
#         elif (m.group(2) is None):
#             s += '-01'
#         s += 'T00:00:00Z'
#     # Now have datetime with timezone info
#     m = re.match(r"(.*\d{2}:\d{2}:\d{2})(\.\d+)([^\d].*)?$", s)
#     # Chop out fractional seconds if present
#     fractional_seconds = 0
#     if (m is not None):
#         s = m.group(1)
#         if (m.group(3) is not None):
#             s += m.group(3)
#         fractional_seconds = float(m.group(2))
#     # Now check that only allowed formats supplied (the parse
#     # function in dateutil is rather lax) and separate out
#     # timezone information to be handled separately
#     #
#     # Seems that one should be able to handle timezone offset
#     # with dt.tzinfo module but this has variation in behavior
#     # between python 2.6 and 2.7... so do here for now
#     m = re.match(r"(\d\d\d\d\-\d\d\-\d\dT\d\d:\d\d(:\d\d)?)(Z|([+-])"
#                  r"(\d\d):(\d\d))$", s)
#     if (m is None):
#         raise ValueError("Bad datetime format (%s)" % s)
#     str = m.group(1) + 'Z'
#     dt = dateutil_parser.parse(str)
#     offset_seconds = 0
#     if (m.group(3) != 'Z'):
#         hh = int(m.group(5))
#         mm = int(m.group(6))
#         if (hh > 23 or mm > 59):
#             raise ValueError("Bad timezone offset (%s)" % s)
#         offset_seconds = hh * 3600 + mm * 60
#         if (m.group(4) == '-'):
#             offset_seconds = -offset_seconds
#     # timetuple() ignores timezone information so we have to add in
#     # the offset here, and any fractional component of the seconds
#     return(timegm(dt.timetuple()) + offset_seconds + fractional_seconds)
# 
# def datetime_to_str(dt='now', no_fractions=False):
#     """The Last-Modified data in ISO8601 syntax, Z notation.
# 
#     The lastmod is stored as unix timestamp which is already
#     in UTC. At preesent this code will return 6 decimal digits
#     if any fraction of a second is given. It would perhaps be
#     better to return only the number of decimal digits necessary,
#     up to a resolution of 1 microsecond.
# 
#     Special cases:
#     - Returns datetime str for 'now' if no parameter given.
#     - Returns None if None is supplied.
#     """
#     if (dt is None):
#         return None
#     elif (dt == 'now'):
#         dt = time.time()
#     if (no_fractions):
#         dt = int(dt)
#     else:
#         dt += 0.0000001  # improve rounding to microseconds
#     return datetime.utcfromtimestamp(dt).isoformat() + 'Z'


# Path: tests/test_w3c_datetime.py
import unittest
import re
from resync.w3c_datetime import str_to_datetime, datetime_to_str



def rt(dts):
    """ Do simple round-trip """
    return(datetime_to_str(str_to_datetime(dts)))


class TestW3cDatetime(unittest.TestCase):

    def test01_datetime_to_str(self):
        """Writing."""
        self.assertEqual(datetime_to_str(0),
                         "1970-01-01T00:00:00Z")
        self.assertEqual(datetime_to_str(0.000001),
                         "1970-01-01T00:00:00.000001Z")

        self.assertEqual(datetime_to_str(0.1),