Skip to content

Force UTC datetimes #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions intercom/traits/api_resource.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
import calendar

import datetime
import time
from pytz import utc

from intercom.lib.flat_store import FlatStore
from intercom.lib.typed_json_deserializer import JsonDeserializer
Expand Down Expand Up @@ -29,7 +31,7 @@ def datetime_value(value):

def to_datetime_value(value):
if value:
return datetime.datetime.fromtimestamp(int(value))
return datetime.datetime.utcfromtimestamp(int(value)).replace(tzinfo=utc)


class Resource(object):
Expand Down Expand Up @@ -93,7 +95,7 @@ def __setattr__(self, attribute, value):
elif self._flat_store_attribute(attribute):
value_to_set = FlatStore(value)
elif timestamp_field(attribute) and datetime_value(value):
value_to_set = time.mktime(value.timetuple())
value_to_set = calendar.timegm(value.utctimetuple())
else:
value_to_set = value
if attribute != 'changed_attributes':
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ inflection==0.3.0
requests==2.6.0
urllib3==1.10.2
six==1.9.0
pytz==2015.4
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@
classifiers=[],
packages=find_packages(),
include_package_data=True,
install_requires=["requests", "inflection", "certifi", "six"],
install_requires=["requests", "inflection", "certifi", "six", "pytz"],
zip_safe=False
)
33 changes: 17 additions & 16 deletions tests/unit/test_user.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import calendar

import json
import mock
Expand Down Expand Up @@ -32,13 +33,13 @@ def it_to_dict_itself(self):
as_dict = user.to_dict
eq_(as_dict["email"], "jim@example.com")
eq_(as_dict["user_id"], "12345")
eq_(as_dict["created_at"], time.mktime(created_at.timetuple()))
eq_(as_dict["created_at"], calendar.timegm(created_at.utctimetuple()))
eq_(as_dict["name"], "Jim Bob")

@istest
def it_presents_created_at_and_last_impression_at_as_datetime(self):
now = datetime.utcnow()
now_ts = time.mktime(now.timetuple())
now_ts = calendar.timegm(now.utctimetuple())
user = User.from_api(
{'created_at': now_ts, 'last_impression_at': now_ts})
self.assertIsInstance(user.created_at, datetime)
Expand All @@ -60,9 +61,9 @@ def it_presents_a_complete_user_record_correctly(self):
eq_('Joe Schmoe', user.name)
eq_('the-app-id', user.app_id)
eq_(123, user.session_count)
eq_(1401970114, time.mktime(user.created_at.timetuple()))
eq_(1393613864, time.mktime(user.remote_created_at.timetuple()))
eq_(1401970114, time.mktime(user.updated_at.timetuple()))
eq_(1401970114, calendar.timegm(user.created_at.utctimetuple()))
eq_(1393613864, calendar.timegm(user.remote_created_at.utctimetuple()))
eq_(1401970114, calendar.timegm(user.updated_at.utctimetuple()))

Avatar = create_class_instance('Avatar') # noqa
Company = create_class_instance('Company') # noqa
Expand All @@ -79,14 +80,14 @@ def it_presents_a_complete_user_record_correctly(self):
eq_('bbbbbbbbbbbbbbbbbbbbbbbb', user.companies[0].id)
eq_('the-app-id', user.companies[0].app_id)
eq_('Company 1', user.companies[0].name)
eq_(1390936440, time.mktime(
user.companies[0].remote_created_at.timetuple()))
eq_(1401970114, time.mktime(
user.companies[0].created_at.timetuple()))
eq_(1401970114, time.mktime(
user.companies[0].updated_at.timetuple()))
eq_(1401970113, time.mktime(
user.companies[0].last_request_at.timetuple()))
eq_(1390936440, calendar.timegm(
user.companies[0].remote_created_at.utctimetuple()))
eq_(1401970114, calendar.timegm(
user.companies[0].created_at.utctimetuple()))
eq_(1401970114, calendar.timegm(
user.companies[0].updated_at.utctimetuple()))
eq_(1401970113, calendar.timegm(
user.companies[0].last_request_at.utctimetuple()))
eq_(0, user.companies[0].monthly_spend)
eq_(0, user.companies[0].session_count)
eq_(1, user.companies[0].user_count)
Expand Down Expand Up @@ -129,7 +130,7 @@ def it_allows_update_last_request_at(self):
@istest
def it_allows_easy_setting_of_custom_data(self):
now = datetime.utcnow()
now_ts = time.mktime(now.timetuple())
now_ts = calendar.timegm(now.utctimetuple())

user = User()
user.custom_attributes["mad"] = 123
Expand Down Expand Up @@ -317,7 +318,7 @@ def it_gets_sets_rw_keys(self):
'name': 'Bob Smith',
'last_seen_ip': '1.2.3.4',
'last_seen_user_agent': 'ie6',
'created_at': time.mktime(created_at.timetuple())
'created_at': calendar.timegm(created_at.utctimetuple())
}
user = User(**payload)
expected_keys = ['custom_attributes']
Expand Down Expand Up @@ -392,7 +393,7 @@ def setUp(self): # noqa
'custom_attributes': {
'mad': 123,
'another': 432,
'other': time.mktime(created_at.timetuple()),
'other': calendar.timegm(created_at.utctimetuple()),
'thing': 'yay'
}
}
Expand Down
8 changes: 6 additions & 2 deletions tests/unit/traits/test_api_resource.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
import calendar

import unittest

from datetime import datetime
from pytz import utc
from intercom.traits.api_resource import Resource
from nose.tools import assert_raises
from nose.tools import eq_
Expand Down Expand Up @@ -34,7 +36,8 @@ def it_does_not_set_type_on_parsing_json(self):

@istest
def it_coerces_time_on_parsing_json(self):
eq_(datetime.fromtimestamp(1374056196), self.api_resource.created_at)
dt = datetime.utcfromtimestamp(1374056196).replace(tzinfo=utc)
eq_(dt, self.api_resource.created_at)

@istest
def it_dynamically_defines_accessors_for_non_existent_properties(self):
Expand All @@ -55,7 +58,8 @@ def it_accepts_unix_timestamps_into_dynamically_defined_date_setters(self):
@istest
def it_exposes_dates_correctly_for_dynamically_defined_getters(self):
self.api_resource.foo_at = 1401200468
eq_(datetime.fromtimestamp(1401200468), self.api_resource.foo_at)
dt = datetime.utcfromtimestamp(1401200468).replace(tzinfo=utc)
eq_(dt, self.api_resource.foo_at)

# @istest
# def it_throws_regular_error_when_non_existant_getter_is_called_that_is_backed_by_an_instance_variable(self): # noqa
Expand Down