def test_json_decoder_hook(self):
serialized_data = json.dumps(
{'time': '2017-01-19T21:41:18.056446Z',
'date': '2013-04-05', 'date_str': '2013-04-05',
'non_date': '8570', 'id': '060444c9-e2d7-4a55-964d-e495f2d5527f',
'description': 'foo', 'data': {'count': 4},
'foobar_field': 'foobar'}
)
converters = {'date_str': str}
extra_decoders = (parse_foobar,)
object_hook = make_json_decoder_hook(
converters=converters, extra_str_decoders=extra_decoders
)
expected = {
'time': datetime(2017, 1, 19, 21, 41, 18, 56446,
tzinfo=iso8601.UTC),
'date': datetime(2013, 4, 5).date(),
'date_str': '2013-04-05', 'non_date': '8570',
'id': UUID('060444c9-e2d7-4a55-964d-e495f2d5527f', version=4),
'description': 'foo', 'data': {'count': 4}, 'foobar_field': True
}
result = json.loads(serialized_data, object_hook=object_hook)
self.assertEqual(expected, result)
python类UTC的实例源码
def test_base_attributes(self):
dt = datetime.datetime(1955, 11, 5, 0, 0, tzinfo=iso8601.UTC)
datatime = fields.DateTimeField()
obj = MyObj(self.context)
obj.created_at = dt
obj.updated_at = dt
expected = {'mogan_object.name': 'MyObj',
'mogan_object.namespace': 'mogan',
'mogan_object.version': '1.5',
'mogan_object.changes':
['created_at', 'updated_at'],
'mogan_object.data':
{'created_at': datatime.stringify(dt),
'updated_at': datatime.stringify(dt),
}
}
actual = obj.obj_to_primitive()
# mogan_object.changes is built from a set and order is undefined
self.assertEqual(sorted(expected['mogan_object.changes']),
sorted(actual['mogan_object.changes']))
del expected['mogan_object.changes'], actual['mogan_object.changes']
self.assertEqual(expected, actual)
def test_parse_no_timezone():
"""issue 4 - Handle datetime string without timezone
This tests what happens when you parse a date with no timezone. While not
strictly correct this is quite common. I'll assume UTC for the time zone
in this case.
"""
d = iso8601.parse_date("2007-01-01T08:00:00")
assert d.year == 2007
assert d.month == 1
assert d.day == 1
assert d.hour == 8
assert d.minute == 0
assert d.second == 0
assert d.microsecond == 0
assert d.tzinfo == iso8601.UTC
def parse_datetime(date):
"""
Validates date is in iso8601 format. Returns parsed datetime in UTC as as
native datetime (tzinfo=None).
"""
if not isinstance(date, basestring):
raise Invalid('date is not a string')
try:
return iso8601.parse_date(date).astimezone(iso8601.UTC).replace(
tzinfo=None)
except:
raise Invalid('date is not in iso8601 format')
def default(self, o):
if isinstance(o, models.SendJob):
return self._encode_send_job(o)
if isinstance(o, models.RemindJob):
return self._encode_remind_job(o)
if isinstance(o, models.DisabledReply):
return self._encode_disabled_reply(o)
if isinstance(o, models.Snippet):
return self._encode_snippet(o)
if isinstance(o, datetime.datetime):
return o.replace(tzinfo=UTC).isoformat()
if isinstance(o, datetime.date):
return o.isoformat()
return json.JSONEncoder.default(self, o)
def datetime_or_none(dt):
"""Validate a datetime or None value."""
if dt is None:
return None
elif isinstance(dt, datetime.datetime):
if dt.utcoffset() is None:
# NOTE(danms): Legacy objects from sqlalchemy are stored in UTC,
# but are returned without a timezone attached.
# As a transitional aid, assume a tz-naive object is in UTC.
return dt.replace(tzinfo=iso8601.UTC)
else:
return dt
raise ValueError(_("A datetime.datetime is required here"))
def get_alerts_by_date(start, end):
'''
Get alerts between given date start and end.
both start and end are datetime objects with timezone info
'''
# We store webhooks by date and time so we search for those first.
webhooks_prefix = _get_webhooks_key_prefix()
webhook_objects = _get_bucket_objects(webhooks_prefix)
alert_ids = []
for obj in webhook_objects:
key = obj.get('Key')
# Remove webhook path prefix (and delimiter) and split string into
# time prefix and alert ID.
webhook_time_prefix, alert_id = key[len(webhooks_prefix) + 1:].rsplit('/', 1)
# There are more compact ways of doing the following but I prefer to
# show the sequence of events.
#
# split prefix into a list of strings.
webhook_time_prefix_list = webhook_time_prefix.split('/')
# use list comprehension to create a list of ints. See also:
# map(int, webhook_time_prefix_list)
webhook_time_prefix_ints = [int(e) for e in webhook_time_prefix_list]
# use *expression syntax to pass in values as a set of arguments. Also
# supply tzinfo because the datetime objects we're supplied have them.
webhook_time = datetime.datetime(*webhook_time_prefix_ints, tzinfo=UTC)
if start < webhook_time < end:
alert_ids.append(alert_id)
alerts = []
for alert_id in alert_ids:
alert_data = get_alert_by_id(alert_id)
alerts.append(alert_data)
return alerts
def setUp(self):
super(TestDateTime, self).setUp()
self.dt = datetime.datetime(2016, 11, 5, tzinfo=iso8601.UTC)
self.field = fields.DateTimeField()
self.coerce_good_values = [(self.dt, self.dt),
(utils.isotime(self.dt), self.dt)]
self.coerce_bad_values = [1, 'foo']
self.to_primitive_values = [(self.dt, utils.isotime(self.dt))]
self.from_primitive_values = [(utils.isotime(self.dt), self.dt)]
def test_stringify(self):
self.assertEqual(
'2016-11-05T18:00:00Z',
self.field.stringify(
datetime.datetime(2016, 11, 5, 18, 0, 0,
tzinfo=iso8601.iso8601.UTC)))
def datetime(value, default_tzinfo=iso8601.UTC, context=None):
"""validates that a a field is an ISO 8601 string, and converts it to a datetime object."""
if not value:
return
try:
return iso8601.parse_date(value, default_timezone=default_tzinfo)
except iso8601.ParseError as e:
raise ValidationException('Invalid date: %s' % (e))
def test_docs():
artist_serializer = serializer(
field('name', validators=[validators.required()])
)
album_schema = serializer(
field('title', validators=[validators.required()]),
field('release_date',
validators=[validators.required(), validators.datetime()],
formatters=[formatters.format_datetime()]),
child('artist', serializer=artist_serializer, validators=[validators.required()])
)
class Artist(object):
def __init__(self, name):
self.name = name
class Album(object):
def __init__(self, title, release_date, artist):
self.title = title
self.release_date = release_date
self.artist = artist
bowie = Artist(name='David Bowie')
album = Album(
artist=bowie,
title='Hunky Dory',
release_date=datetime.datetime(1971, 12, 17)
)
assert album_schema.serialize(album) == {
'artist': {'name': 'David Bowie'},
'release_date': '1971-12-17T00:00:00',
'title': 'Hunky Dory'
}
assert album_schema.deserialize(album_schema.serialize(album)) == {
'artist': {'name': 'David Bowie'},
'release_date': datetime.datetime(1971, 12, 17, 0, 0, tzinfo=iso8601.UTC),
'title': 'Hunky Dory'
}
input = album_schema.serialize(album)
del input['artist']
errors = None
try:
album_schema.deserialize(input)
except Exception as e:
errors = e.errors
assert errors == {'artist': ['This field is required']}