Source code for wheezy.core.datetime

""" ``datetime`` module.
"""

from email.utils import parsedate
from time import localtime, mktime

from wheezy.core.introspection import import_name

# The lines below are equivalent to:
# from datetime import timedelta
# However it is not used due module name confict
# since the use of relative imports by default.
# absolute imports are available since python 2.5,
# however we want keep compatibility with python 2.4
datetime = import_name("datetime.datetime")
time = import_name("datetime.time")
timedelta = import_name("datetime.timedelta")
tzinfo = import_name("datetime.tzinfo")


ZERO = timedelta(0)
WEEKDAYS = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
MONTHS = (
    None,
    "Jan",
    "Feb",
    "Mar",
    "Apr",
    "May",
    "Jun",
    "Jul",
    "Aug",
    "Sep",
    "Oct",
    "Nov",
    "Dec",
)


[docs]def format_http_datetime(stamp): """Formats datetime to a string following rfc1123 pattern. >>> now = datetime(2011, 9, 19, 10, 45, 30, 0, UTC) >>> format_http_datetime(now) 'Mon, 19 Sep 2011 10:45:30 GMT' if timezone is not set in datetime instance the ``stamp`` is assumed to be in UTC (``datetime.utcnow``). >>> now = datetime(2011, 9, 19, 10, 45, 30, 0) >>> format_http_datetime(now) 'Mon, 19 Sep 2011 10:45:30 GMT' >>> now = datetime.utcnow() >>> assert format_http_datetime(now) if ``stamp`` is a string just return it >>> format_http_datetime('x') 'x' >>> format_http_datetime(100) # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... """ if isinstance(stamp, datetime): if stamp.tzinfo: stamp = stamp.astimezone(UTC).timetuple() else: stamp = localtime(mktime(stamp.timetuple())) elif isinstance(stamp, str): return stamp else: raise TypeError("Expecting type ``datetime.datetime``.") year, month, day, hh, mm, ss, wd, y, z = stamp return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( WEEKDAYS[wd], day, MONTHS[month], year, hh, mm, ss, )
[docs]def format_iso_datetime(stamp): """Return a string representing the date and time in ISO 8601 format. If the time is in UTC, adds a 'Z' directly after the time without a space. see http://en.wikipedia.org/wiki/ISO_8601. >>> class EET(tzinfo): ... def utcoffset(self, dt): ... return timedelta(minutes=120) ... def dst(self, dt): ... return timedelta() >>> format_iso_datetime(datetime(2012, 2, 22, 12, 52, 29, 300)) '2012-02-22T12:52:29' >>> format_iso_datetime(datetime(2012, 2, 22, 12, 52, 29, 300, ... tzinfo=UTC)) '2012-02-22T12:52:29Z' >>> format_iso_datetime(datetime(2012, 2, 22, 12, 52, 29, 300, ... tzinfo=EET())) '2012-02-22T12:52:29+02:00' """ if stamp.tzinfo: if stamp.utcoffset() == ZERO: return datetime(*stamp.timetuple()[:6]).isoformat() + "Z" if stamp.microsecond: stamp = stamp.replace(microsecond=0) return stamp.isoformat()
[docs]def format_iso_time(stamp): """Return a string representing the time in ISO 8601 format. If the time is in UTC, adds a 'Z' directly after the time without a space. see http://en.wikipedia.org/wiki/ISO_8601. >>> class EET(tzinfo): ... def utcoffset(self, dt): ... return timedelta(minutes=120) ... def dst(self, dt): ... return timedelta() >>> format_iso_time(time(12, 52, 29, 300)) '12:52:29' >>> format_iso_time(time(12, 52, 29, 300, ... tzinfo=UTC)) '12:52:29Z' >>> format_iso_time(time(12, 52, 29, 300, ... tzinfo=EET())) '12:52:29+02:00' """ if stamp.microsecond: stamp = stamp.replace(microsecond=0) if stamp.tzinfo: if stamp.utcoffset() == ZERO: return stamp.replace(tzinfo=None).isoformat() + "Z" else: return stamp.isoformat() else: return stamp.isoformat()
[docs]def parse_http_datetime(stamp): """Parses a string in rfc1123 format to ``datetime``. >>> parse_http_datetime('Mon, 19 Sep 2011 10:45:30 GMT') datetime.datetime(2011, 9, 19, 10, 45, 30) """ return datetime.fromtimestamp(mktime(parsedate(stamp)))
[docs]def total_seconds(delta): """Returns a total number of seconds for the given delta. ``delta`` can be ``datetime.timedelta``. >>> total_seconds(timedelta(hours=2)) 7200 or int: >>> total_seconds(100) 100 otherwise raise ``TypeError``. >>> total_seconds('100') # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... """ if isinstance(delta, int): return delta elif isinstance(delta, timedelta): return delta.seconds + delta.days * 86400 else: raise TypeError( "Expecting type datetime.timedelta " "or int for seconds" )
[docs]class utc(tzinfo): # noqa: N801 """UTC timezone.""" __slots__ = "name" def __init__(self, name): self.name = name
[docs] def tzname(self, dt): """Name of time zone. >>> GMT.tzname(None) 'GMT' >>> UTC.tzname(None) 'UTC' """ return self.name
[docs] def utcoffset(self, dt): """Offset from UTC. >>> UTC.utcoffset(None) datetime.timedelta(0) """ return ZERO
[docs] def dst(self, dt): """DST is not in effect. >>> UTC.dst(None) datetime.timedelta(0) """ return ZERO
GMT = utc("GMT") UTC = utc("UTC")