| import calendar |
| |
| from datetime import ( |
| date, |
| datetime, |
| timedelta, |
| tzinfo, |
| ) |
| |
| from email.utils import ( |
| formatdate, |
| mktime_tz, |
| parsedate_tz, |
| ) |
| |
| import time |
| |
| from webob.compat import ( |
| integer_types, |
| long, |
| native_, |
| text_type, |
| ) |
| |
| __all__ = [ |
| 'UTC', 'timedelta_to_seconds', |
| 'year', 'month', 'week', 'day', 'hour', 'minute', 'second', |
| 'parse_date', 'serialize_date', |
| 'parse_date_delta', 'serialize_date_delta', |
| ] |
| |
| _now = datetime.now # hook point for unit tests |
| |
| class _UTC(tzinfo): |
| def dst(self, dt): |
| return timedelta(0) |
| def utcoffset(self, dt): |
| return timedelta(0) |
| def tzname(self, dt): |
| return 'UTC' |
| def __repr__(self): |
| return 'UTC' |
| |
| UTC = _UTC() |
| |
| |
| |
| def timedelta_to_seconds(td): |
| """ |
| Converts a timedelta instance to seconds. |
| """ |
| return td.seconds + (td.days*24*60*60) |
| |
| day = timedelta(days=1) |
| week = timedelta(weeks=1) |
| hour = timedelta(hours=1) |
| minute = timedelta(minutes=1) |
| second = timedelta(seconds=1) |
| # Estimate, I know; good enough for expirations |
| month = timedelta(days=30) |
| year = timedelta(days=365) |
| |
| |
| def parse_date(value): |
| if not value: |
| return None |
| try: |
| value = native_(value) |
| except: |
| return None |
| t = parsedate_tz(value) |
| if t is None: |
| # Could not parse |
| return None |
| if t[-1] is None: |
| # No timezone given. None would mean local time, but we'll force UTC |
| t = t[:9] + (0,) |
| t = mktime_tz(t) |
| return datetime.fromtimestamp(t, UTC) |
| |
| def serialize_date(dt): |
| if isinstance(dt, (bytes, text_type)): |
| return native_(dt) |
| if isinstance(dt, timedelta): |
| dt = _now() + dt |
| if isinstance(dt, (datetime, date)): |
| dt = dt.timetuple() |
| if isinstance(dt, (tuple, time.struct_time)): |
| dt = calendar.timegm(dt) |
| if not (isinstance(dt, float) or isinstance(dt, integer_types)): |
| raise ValueError( |
| "You must pass in a datetime, date, time tuple, or integer object, " |
| "not %r" % dt) |
| return formatdate(dt, usegmt=True) |
| |
| |
| |
| def parse_date_delta(value): |
| """ |
| like parse_date, but also handle delta seconds |
| """ |
| if not value: |
| return None |
| try: |
| value = int(value) |
| except ValueError: |
| return parse_date(value) |
| else: |
| return _now() + timedelta(seconds=value) |
| |
| |
| def serialize_date_delta(value): |
| if isinstance(value, (float, int, long)): |
| return str(int(value)) |
| else: |
| return serialize_date(value) |