2012-03-07 19:42:16 +00:00
|
|
|
"""
|
|
|
|
Utility to return datetime.datetime.utcnow() by default but allows for a custom utcnow() (e.g., for testing)
|
|
|
|
|
|
|
|
>>> import regluit
|
|
|
|
>>> from regluit.utils.localdatetime import now
|
|
|
|
>>> now()
|
|
|
|
datetime.datetime(2012, 3, 8, 14, 0, 35, 409270)
|
|
|
|
>>> now()
|
|
|
|
datetime.datetime(2012, 3, 8, 14, 0, 36, 985271)
|
|
|
|
>>> n = now()
|
|
|
|
>>> n
|
|
|
|
datetime.datetime(2012, 3, 8, 14, 1, 54, 650679)
|
|
|
|
>>> regluit.utils.localdatetime._now = lambda: n
|
|
|
|
>>> now()
|
|
|
|
datetime.datetime(2012, 3, 8, 14, 1, 54, 650679)
|
|
|
|
>>> now()
|
|
|
|
datetime.datetime(2012, 3, 8, 14, 1, 54, 650679)
|
|
|
|
>>> now()
|
|
|
|
|
2012-03-10 00:57:17 +00:00
|
|
|
DST handled:
|
|
|
|
|
|
|
|
>>> ptz = pytz.timezone('America/Los_Angeles')
|
|
|
|
>>> make_naive(datetime.datetime(2012,03,11,10,tzinfo=utc), ptz)
|
|
|
|
datetime.datetime(2012, 3, 11, 3, 0)
|
|
|
|
>>> make_naive(datetime.datetime(2012,03,11,9,tzinfo=utc), ptz)
|
|
|
|
datetime.datetime(2012, 3, 11, 1, 0)
|
|
|
|
|
|
|
|
>>> make_aware(datetime.datetime(2012,11,4,1,30), ptz)
|
|
|
|
Traceback (most recent call last):
|
|
|
|
File "<console>", line 1, in <module>
|
|
|
|
File "/Users/raymondyee/C/src/Gluejar/regluit/utils/localdatetime.py", line 90, in make_aware
|
|
|
|
return timezone.localize(value, is_dst=None)
|
|
|
|
File "/Users/raymondyee/.virtualenvs/regluit/lib/python2.7/site-packages/pytz/tzinfo.py", line 349, in localize
|
|
|
|
raise AmbiguousTimeError(dt)
|
|
|
|
AmbiguousTimeError: 2012-11-04 01:30:00
|
|
|
|
|
2012-03-07 19:42:16 +00:00
|
|
|
|
|
|
|
"""
|
|
|
|
|
2012-03-10 00:57:17 +00:00
|
|
|
import pytz
|
2012-03-07 19:42:16 +00:00
|
|
|
import datetime
|
|
|
|
import django
|
2012-03-09 18:34:14 +00:00
|
|
|
from django.conf import settings
|
2012-03-07 19:42:16 +00:00
|
|
|
|
|
|
|
# for Django 1.3.x, return a timestamp naive now()
|
|
|
|
# for Django 1.4 should switch to django.utils.timezone.now()
|
|
|
|
# see https://code.djangoproject.com/browser/django/trunk/django/utils/timezone.py?rev=17642#L232
|
|
|
|
|
2012-03-09 18:34:14 +00:00
|
|
|
# if there is a LOCALDATETIME_NOW in the Django settings, use that to be _now
|
|
|
|
|
|
|
|
if hasattr(settings, 'LOCALDATETIME_NOW') and settings.LOCALDATETIME_NOW is not None:
|
|
|
|
_now = settings.LOCALDATETIME_NOW
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
_now = django.utils.timezone.now
|
|
|
|
except AttributeError, e:
|
|
|
|
_now = datetime.datetime.now
|
2012-03-07 19:42:16 +00:00
|
|
|
|
|
|
|
now = lambda: _now()
|
|
|
|
|
|
|
|
# provide a replacement for datetime.date.today()
|
|
|
|
# this will be timezone naive -- is that what we really want?
|
|
|
|
|
|
|
|
date_today = lambda: _now().date()
|
|
|
|
|
2012-03-10 00:57:17 +00:00
|
|
|
# borrow a lot of the routines/code that will be in Django 1.4+ django.utils.timezone
|
|
|
|
# https://code.djangoproject.com/browser/django/trunk/django/utils/timezone.py
|
|
|
|
|
|
|
|
utc = pytz.utc
|
|
|
|
|
|
|
|
def get_default_timezone():
|
|
|
|
return pytz.timezone(settings.TIME_ZONE)
|
|
|
|
|
|
|
|
def is_aware(value):
|
|
|
|
"""
|
|
|
|
Determines if a given datetime.datetime is aware.
|
|
|
|
|
|
|
|
The logic is described in Python's docs:
|
|
|
|
http://docs.python.org/library/datetime.html#datetime.tzinfo
|
|
|
|
"""
|
|
|
|
return value.tzinfo is not None and value.tzinfo.utcoffset(value) is not None
|
|
|
|
|
|
|
|
def is_naive(value):
|
|
|
|
"""
|
|
|
|
Determines if a given datetime.datetime is naive.
|
|
|
|
|
|
|
|
The logic is described in Python's docs:
|
|
|
|
http://docs.python.org/library/datetime.html#datetime.tzinfo
|
|
|
|
"""
|
|
|
|
return value.tzinfo is None or value.tzinfo.utcoffset(value) is None
|
2012-03-07 19:42:16 +00:00
|
|
|
|
2012-03-10 00:57:17 +00:00
|
|
|
def make_aware(value, timezone):
|
|
|
|
"""
|
|
|
|
Makes a naive datetime.datetime in a given time zone aware.
|
|
|
|
"""
|
|
|
|
if hasattr(timezone, 'localize'):
|
|
|
|
# available for pytz time zones
|
|
|
|
return timezone.localize(value, is_dst=None)
|
|
|
|
else:
|
|
|
|
# may be wrong around DST changes
|
|
|
|
return value.replace(tzinfo=timezone)
|
|
|
|
|
|
|
|
def make_naive(value, timezone):
|
|
|
|
"""
|
|
|
|
Makes an aware datetime.datetime naive in a given time zone.
|
|
|
|
"""
|
|
|
|
value = value.astimezone(timezone)
|
|
|
|
if hasattr(timezone, 'normalize'):
|
|
|
|
# available for pytz time zones
|
|
|
|
value = timezone.normalize(value)
|
|
|
|
return value.replace(tzinfo=None)
|
|
|
|
|
2012-03-12 22:42:20 +00:00
|
|
|
def isoformat(value):
|
|
|
|
"""
|
|
|
|
if value is naive, assume it's in the default_timezone
|
|
|
|
"""
|
|
|
|
if is_naive(value):
|
|
|
|
return make_aware(value, get_default_timezone()).isoformat()
|
|
|
|
else:
|
|
|
|
return value.isoformat()
|
|
|
|
|
2012-03-26 22:02:26 +00:00
|
|
|
def zuluformat(value):
|
|
|
|
"""format value in zulu format -- e.g., 2012-03-26T17:47:22.654449Z"""
|
|
|
|
return "{0}Z".format(as_utc_naive(value).isoformat())
|
|
|
|
|
2012-03-10 00:57:17 +00:00
|
|
|
def as_utc_naive(value):
|
|
|
|
"""
|
|
|
|
if value is naive, assume it's in the default time zone, then convert to UTC but make naive
|
|
|
|
"""
|
|
|
|
if is_naive(value):
|
|
|
|
return make_naive(make_aware(value, get_default_timezone()), utc)
|
|
|
|
else:
|
|
|
|
return make_naive(value, utc)
|
|
|
|
|
|
|
|
def as_default_timezone_naive(value):
|
|
|
|
"""
|
|
|
|
if value is naive, assume it's in UTC and convert to the default tz and make it naive
|
|
|
|
"""
|
|
|
|
if is_naive(value):
|
|
|
|
return make_naive(make_aware(value, utc), get_default_timezone())
|
|
|
|
else:
|
|
|
|
return make_naive(value, get_default_timezone())
|