Skip to content

Commit 0e94972

Browse files
committed
Merge pull request #109 from shotgunsoftware/ticket/35260_sgtimezone_scoping
For #35260: Refactoring scoping of sgtimezone to support serialization
2 parents e49a9b3 + 026a5e0 commit 0e94972

File tree

1 file changed

+78
-37
lines changed

1 file changed

+78
-37
lines changed

shotgun_api3/lib/sgtimezone.py

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
# current users of api2 to install new modules and modify PYTHONPATH info.
66
# ----------------------------------------------------------------------------
77

8+
from datetime import tzinfo, timedelta, datetime
9+
import time as _time
10+
811
class SgTimezone(object):
9-
from datetime import tzinfo, timedelta, datetime
10-
import time as _time
12+
'''
13+
Shotgun's server infrastructure is configured for Coordinated Universal
14+
Time (UTC). In order to provide relevant local timestamps to users, we wrap
15+
the datetime module's tzinfo to provide convenient conversion methods.
16+
'''
1117

1218
ZERO = timedelta(0)
1319
STDOFFSET = timedelta(seconds = -_time.timezone)
@@ -18,41 +24,76 @@ class SgTimezone(object):
1824
DSTDIFF = DSTOFFSET - STDOFFSET
1925

2026
def __init__(self):
21-
self.utc = self.UTC()
22-
self.local = self.LocalTimezone()
27+
self.utc = UTC()
28+
self.local = LocalTimezone()
29+
30+
@classmethod
31+
def UTC(cls):
32+
'''
33+
For backwards compatibility, from when UTC was a nested class,
34+
we allow instantiation via SgTimezone
35+
'''
36+
return UTC()
37+
38+
@classmethod
39+
def LocalTimezone(cls):
40+
'''
41+
For backwards compatibility, from when LocalTimezone was a nested
42+
class, we allow instantiation via SgTimezone
43+
'''
44+
return LocalTimezone()
2345

24-
class UTC(tzinfo):
25-
26-
def utcoffset(self, dt):
27-
return SgTimezone.ZERO
28-
29-
def tzname(self, dt):
30-
return "UTC"
31-
32-
def dst(self, dt):
33-
return SgTimezone.ZERO
46+
class UTC(tzinfo):
47+
'''
48+
Implementation of datetime's tzinfo to provide consistent calculated
49+
offsets against Coordinated Universal Time (UTC)
50+
'''
51+
52+
def utcoffset(self, dt):
53+
return SgTimezone.ZERO
3454

35-
class LocalTimezone(tzinfo):
36-
37-
def utcoffset(self, dt):
38-
if self._isdst(dt):
39-
return SgTimezone.DSTOFFSET
40-
else:
41-
return SgTimezone.STDOFFSET
42-
43-
def dst(self, dt):
44-
if self._isdst(dt):
45-
return SgTimezone.DSTDIFF
46-
else:
47-
return SgTimezone.ZERO
48-
49-
def tzname(self, dt):
50-
return _time.tzname[self._isdst(dt)]
51-
52-
def _isdst(self, dt):
53-
tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1)
54-
import time as _time
55-
stamp = _time.mktime(tt)
56-
tt = _time.localtime(stamp)
57-
return tt.tm_isdst > 0
55+
def tzname(self, dt):
56+
return "UTC"
57+
58+
def dst(self, dt):
59+
return SgTimezone.ZERO
5860

61+
class LocalTimezone(tzinfo):
62+
'''
63+
Implementation of datetime's tzinfo to provide convenient conversion
64+
between Shotgun server time and local user time
65+
'''
66+
67+
def utcoffset(self, dt):
68+
'''
69+
Difference between the user's local timezone and UTC timezone in seconds
70+
'''
71+
if self._isdst(dt):
72+
return SgTimezone.DSTOFFSET
73+
else:
74+
return SgTimezone.STDOFFSET
75+
76+
def dst(self, dt):
77+
'''
78+
Daylight savings time (dst) offset in seconds
79+
'''
80+
if self._isdst(dt):
81+
return SgTimezone.DSTDIFF
82+
else:
83+
return SgTimezone.ZERO
84+
85+
def tzname(self, dt):
86+
'''
87+
Name of the user's local timezone, including a reference
88+
to daylight savings time (dst) if applicable
89+
'''
90+
return _time.tzname[self._isdst(dt)]
91+
92+
def _isdst(self, dt):
93+
'''
94+
Calculate whether the timestamp in question was in daylight savings
95+
'''
96+
tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1)
97+
stamp = _time.mktime(tt)
98+
tt = _time.localtime(stamp)
99+
return tt.tm_isdst > 0

0 commit comments

Comments
 (0)