def sitemap_time_format(dt):
if dt.tzinfo:
dt = dt.astimezone(UTC_TIMEZONE)
return dt.strftime('%Y-%m-%dT%H:%M:%S+00:00')
python类tzinfo()的实例源码
def iso_time_format(dt):
if dt.tzinfo:
return convert_to_local_time(dt).strftime(ISO_TIME_FORMAT)
else:
return dt.strftime(ISO_TIME_FORMAT)
def string_as_datetime(time_str):
"""Expects timestamps inline with '2017-06-05T22:45:24.423+0000'"""
# split the utc offset part
naive_time_str, offset_str = time_str[:-5], time_str[-5:]
# parse the naive date/time part
naive_dt = datetime.strptime(naive_time_str, '%Y-%m-%dT%H:%M:%S.%f')
# parse the utc offset
offset = int(offset_str[-4:-2]) * 60 + int(offset_str[-2:])
if offset_str[0] == "-":
offset = -offset
dt = naive_dt.replace(tzinfo=FixedOffset(offset))
return dt
def datetimes_in_range(allow_naive=None, timezones=None, start_date=None, end_date=None, start_inclusive=True, end_inclusive=True):
"""Return a strategy for generating datetimes.
allow_naive=True will cause the values to sometimes be naive.
timezones is the set of permissible timezones. If set to an empty
collection all timezones must be naive. If set to None all available
timezones will be used.
"""
if timezones is None:
timezones = list(pytz.all_timezones)
timezones.remove(u'UTC')
timezones.insert(0, u'UTC')
timezones = [
tz if isinstance(tz, dt.tzinfo) else pytz.timezone(tz)
for tz in timezones
]
if allow_naive is None:
allow_naive = not timezones
if not (timezones or allow_naive):
raise InvalidArgument(
u'Cannot create non-naive datetimes with no timezones allowed'
)
return DatetimeStrategy(
allow_naive=allow_naive, timezones=timezones,
start_date=start_date,
end_date=end_date,
start_inclusive=start_inclusive,
end_inclusive=end_inclusive
)
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
)
def __new__(cls, document_class=dict,
tz_aware=False, uuid_representation=PYTHON_LEGACY,
unicode_decode_error_handler="strict",
tzinfo=None):
if not (issubclass(document_class, MutableMapping) or
_raw_document_class(document_class)):
raise TypeError("document_class must be dict, bson.son.SON, "
"bson.raw_bson_document.RawBSONDocument, or a "
"sublass of collections.MutableMapping")
if not isinstance(tz_aware, bool):
raise TypeError("tz_aware must be True or False")
if uuid_representation not in ALL_UUID_REPRESENTATIONS:
raise ValueError("uuid_representation must be a value "
"from bson.binary.ALL_UUID_REPRESENTATIONS")
if not isinstance(unicode_decode_error_handler, (string_type, None)):
raise ValueError("unicode_decode_error_handler must be a string "
"or None")
if tzinfo is not None:
if not isinstance(tzinfo, datetime.tzinfo):
raise TypeError(
"tzinfo must be an instance of datetime.tzinfo")
if not tz_aware:
raise ValueError(
"cannot specify tzinfo without also setting tz_aware=True")
return tuple.__new__(
cls, (document_class, tz_aware, uuid_representation,
unicode_decode_error_handler, tzinfo))
def __repr__(self):
document_class_repr = (
'dict' if self.document_class is dict
else repr(self.document_class))
uuid_rep_repr = UUID_REPRESENTATION_NAMES.get(self.uuid_representation,
self.uuid_representation)
return (
'CodecOptions(document_class=%s, tz_aware=%r, uuid_representation='
'%s, unicode_decode_error_handler=%r, tzinfo=%r)' %
(document_class_repr, self.tz_aware, uuid_rep_repr,
self.unicode_decode_error_handler,
self.tzinfo))
def _parse_codec_options(options):
"""Parse BSON codec options."""
return CodecOptions(
document_class=options.get(
'document_class', DEFAULT_CODEC_OPTIONS.document_class),
tz_aware=options.get(
'tz_aware', DEFAULT_CODEC_OPTIONS.tz_aware),
uuid_representation=options.get(
'uuidrepresentation', DEFAULT_CODEC_OPTIONS.uuid_representation),
unicode_decode_error_handler=options.get(
'unicode_decode_error_handler',
DEFAULT_CODEC_OPTIONS.unicode_decode_error_handler),
tzinfo=options.get('tzinfo', DEFAULT_CODEC_OPTIONS.tzinfo))
def test_datetime_tzinfo_io(self):
class TZ(tzinfo):
def utcoffset(self, date_time):
return timedelta(hours=-1)
def dst(self, date_time):
return None
now = datetime(1982, 1, 1, tzinfo=TZ())
dt = self.DatetimeTest.objects.create(test_id=1, created_at=now)
dt2 = self.DatetimeTest.objects(test_id=1).first()
self.assertEqual(dt2.created_at.timetuple()[:6], (now + timedelta(hours=1)).timetuple()[:6])
def timestamp(x):
"""Get a timestamp from a date in python 3 and python 2"""
if x.tzinfo is None:
# Naive dates to utc
x = x.replace(tzinfo=utc)
if hasattr(x, 'timestamp'):
return x.timestamp()
else:
return (x - datetime(1970, 1, 1, tzinfo=utc)).total_seconds()
def _isdst(self, dt):
# We can't use mktime here. It is unstable when deciding if
# the hour near to a change is DST or not.
#
# timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour,
# dt.minute, dt.second, dt.weekday(), 0, -1))
# return time.localtime(timestamp).tm_isdst
#
# The code above yields the following result:
#
# >>> import tz, datetime
# >>> t = tz.tzlocal()
# >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
# 'BRDT'
# >>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname()
# 'BRST'
# >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
# 'BRST'
# >>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname()
# 'BRDT'
# >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
# 'BRDT'
#
# Here is a more stable implementation:
#
timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400
+ dt.hour * 3600
+ dt.minute * 60
+ dt.second)
return time.localtime(timestamp+time.timezone).tm_isdst
def _isdst(self, dt):
if not self._start_delta:
return False
year = datetime.datetime(dt.year, 1, 1)
start = year+self._start_delta
end = year+self._end_delta
dt = dt.replace(tzinfo=None)
if start < end:
return dt >= start and dt < end
else:
return dt >= start or dt < end
def _delta(self, x, isend=0):
kwargs = {}
if x.month is not None:
kwargs["month"] = x.month
if x.weekday is not None:
kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week)
if x.week > 0:
kwargs["day"] = 1
else:
kwargs["day"] = 31
elif x.day:
kwargs["day"] = x.day
elif x.yday is not None:
kwargs["yearday"] = x.yday
elif x.jyday is not None:
kwargs["nlyearday"] = x.jyday
if not kwargs:
# Default is to start on first sunday of april, and end
# on last sunday of october.
if not isend:
kwargs["month"] = 4
kwargs["day"] = 1
kwargs["weekday"] = relativedelta.SU(+1)
else:
kwargs["month"] = 10
kwargs["day"] = 31
kwargs["weekday"] = relativedelta.SU(-1)
if x.time is not None:
kwargs["seconds"] = x.time
else:
# Default is 2AM.
kwargs["seconds"] = 7200
if isend:
# Convert to standard time, to follow the documented way
# of working with the extra hour. See the documentation
# of the tzinfo class.
delta = self._dst_offset-self._std_offset
kwargs["seconds"] -= delta.seconds+delta.days*86400
return relativedelta.relativedelta(**kwargs)
def _find_comp(self, dt):
if len(self._comps) == 1:
return self._comps[0]
dt = dt.replace(tzinfo=None)
try:
return self._cachecomp[self._cachedate.index(dt)]
except ValueError:
pass
lastcomp = None
lastcompdt = None
for comp in self._comps:
if not comp.isdst:
# Handle the extra hour in DST -> STD
compdt = comp.rrule.before(dt-comp.tzoffsetdiff, inc=True)
else:
compdt = comp.rrule.before(dt, inc=True)
if compdt and (not lastcompdt or lastcompdt < compdt):
lastcompdt = compdt
lastcomp = comp
if not lastcomp:
# RFC says nothing about what to do when a given
# time is before the first onset date. We'll look for the
# first standard component, or the first component, if
# none is found.
for comp in self._comps:
if not comp.isdst:
lastcomp = comp
break
else:
lastcomp = comp[0]
self._cachedate.insert(0, dt)
self._cachecomp.insert(0, lastcomp)
if len(self._cachedate) > 10:
self._cachedate.pop()
self._cachecomp.pop()
return lastcomp
def _isdst(self, dt):
if not self._dstmonth:
# dstmonth == 0 signals the zone has no daylight saving time
return False
dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek,
self._dsthour, self._dstminute,
self._dstweeknumber)
dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek,
self._stdhour, self._stdminute,
self._stdweeknumber)
if dston < dstoff:
return dston <= dt.replace(tzinfo=None) < dstoff
else:
return not dstoff <= dt.replace(tzinfo=None) < dston
def is_aware(value):
"""
Determines if a given datetime.datetime is aware.
The concept is defined in Python's docs:
http://docs.python.org/library/datetime.html#datetime.tzinfo
Assuming value.tzinfo is either None or a proper datetime.tzinfo,
value.utcoffset() implements the appropriate logic.
"""
return value.utcoffset() is not None
# add from https://github.com/angelbot/geoincentives/blob/7b156fc0d223a1e9376e83651c7c8ad5deaa2b0f/coffin/template/defaultfilters.py
def timesince(d):
time1 = datetime.datetime.utcnow()
format = '%Y-%m-%d %H:%M:%S'
delta = time1 - d.replace(tzinfo=None)
before = delta.days * 24 * 60 * 60 + delta.seconds
if before <= 60:
return 'just now'
else:
return datetime.timedelta(seconds=before)
def date(value, fmt=None):
date = dateutil.parser.parse(str(value))
native = date.replace(tzinfo=None)
format='%b %d, %Y'
return native.strftime(format)
def dst(self, dt):
if dt is None or dt.tzinfo is None:
# An exception may be sensible here, in one or both cases.
# It depends on how you want to treat them. The default
# fromutc() implementation (called by the default astimezone()
# implementation) passes a datetime with dt.tzinfo is self.
return ZERO
assert dt.tzinfo is self
# Find start and end times for US DST. For years before 1967, return
# ZERO for no DST.
if 2006 < dt.year:
dststart, dstend = DSTSTART_2007, DSTEND_2007
elif 1986 < dt.year < 2007:
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
elif 1966 < dt.year < 1987:
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
else:
return ZERO
start = first_sunday_on_or_after(dststart.replace(year=dt.year))
end = first_sunday_on_or_after(dstend.replace(year=dt.year))
# Can't compare naive to aware objects, so strip the timezone from
# dt first.
if start <= dt.replace(tzinfo=None) < end:
return HOUR
else:
return ZERO
def is_aware(value):
"""
Determines if a given datetime.datetime is aware.
The concept is defined in Python's docs:
http://docs.python.org/library/datetime.html#datetime.tzinfo
Assuming value.tzinfo is either None or a proper datetime.tzinfo,
value.utcoffset() implements the appropriate logic.
"""
return value.utcoffset() is not None