1from datetime import datetime
2from pytz import timezone, all_timezones
3# must read else Bug:
4# https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html
5
6# aware dt-obj
7dt_obj = datetime.strptime('2021-05-19T01:55:10+0000', '%Y-%m-%dT%H:%M:%S%z')
8# double confirmaiton: aware dt-obj
9dt_obj.tzinfo
10# correct
11dt_obj.astimezone(timezone('US/Pacific'))
12# correct
13dt_obj.replace(tzinfo=timezone('UTC')).astimezone(timezone('US/Pacific'))
14# confirmation: desired tz
15dt_obj.replace(tzinfo=timezone('UTC')).astimezone(timezone('US/Pacific')).tzinfo
16# ~~~~~~~
17# naive datetime object
18datetime.utcnow()
19# confirmation: naive dt-obj
20print(datetime.utcnow().tzinfo)
21# incorrect because started with naive datetime object
22datetime.utcnow().astimezone(timezone('US/Pacific'))
23# correct because add/replace tzinfo of initial dt-obj before conversion to desired tz
24# SEE article link above. The following is probably correct only bc starting w/ utc.
25datetime.utcnow().replace(tzinfo=timezone('UTC')).astimezone(timezone('US/Pacific'))
26# confirmation: aware dt-obj
27datetime.utcnow().replace(tzinfo=timezone('UTC')).astimezone(timezone('US/Pacific')).tzinfo
28
29from dateutil import tz
30dt=datetime(2018, 11, 1,20,0,0)
31
32print(dt)
33# 2018-11-01 20:00:00
34print(dt.replace(tzinfo=tz.gettz('UTC')).astimezone(tz.gettz('US/Eastern')))
35# 2018-11-01 16:00:00-04:00
36print(datetime(2018, 11, 1,20,0,0,tzinfo=tz.gettz('UTC')).astimezone(tz.gettz('US/Eastern')))
37# 2018-11-01 16:00:00-04:00
38print(dt.replace(tzinfo=timezone('UTC')).astimezone(timezone('US/Eastern')))
39# 2018-11-01 16:00:00-04:00
40print(datetime(2018, 11, 1,20,0,0,tzinfo=timezone('UTC')).astimezone(timezone('US/Eastern')))
41# 2018-11-01 16:00:00-04:00
42print(timezone('UTC').localize(dt).astimezone(timezone('US/Eastern')))
43# 2018-11-01 16:00:00-04:00
44
45# ~~ VS ~~
46dt=datetime(2018, 11, 1,16,0,0)
47print(dt)
48# 2018-11-01 16:00:00
49print(dt.replace(tzinfo=tz.gettz('US/Eastern')).astimezone(tz.gettz('US/Pacific')))
50# 2018-11-01 13:00:00-07:00
51print(datetime(2018, 11, 1,16,0,0,tzinfo=tz.gettz('US/Eastern')).astimezone(tz.gettz('US/Pacific')))
52# 2018-11-01 13:00:00-07:00
53print(dt.replace(tzinfo=timezone('US/Eastern')).astimezone(timezone('US/Pacific'))) # Bug vector
54# 2018-11-01 13:56:00-07:00 # incorrect!
55print(datetime(2018, 11, 1,16,0,0,tzinfo=timezone('US/Eastern')).astimezone(timezone('US/Pacific'))) # Bug vector
56# 2018-11-01 13:56:00-07:00 # incorrect!
57print(timezone('US/Eastern').localize(dt).astimezone(timezone('US/Pacific')))
58# 2018-11-01 13:00:00-07:00
59
60# ~~~~~~~~~~~
61# len(all_timezones) == 593
62for zone in all_timezones:
63 print(zone)
1import pytz
2from dateutil import tz
3from datetime import datetime, timedelta
4# must read source link else Bug:
5
6NYC_p = pytz.timezone('America/New_York') # 1.53 µs
7NYC_d = tz.gettz('America/New_York') # 863 ns
8# tz Awareness
9dt_p = NYC_p.localize(datetime(2018, 11, 1)) # 35.4 µs
10dt_d = datetime(2018, 11, 1, tzinfo=NYC_d) # 1.38 µs
11
12dt_p.utcoffset() # 655 ns
13dt_d.utcoffset() # 13.9 µs
14
15LA_p = pytz.timezone('America/Los_Angeles')
16LA_d = tz.gettz('America/Los_Angeles')
17# tz Conversion
18NYC_p.localize(datetime(2018, 11, 1)).astimezone(LA_p) # 44.8 µs
19datetime(2018, 11, 1, tzinfo=NYC_d).astimzone(LA_d) # 32.8 µs
20
21# ~~~~~ Date Arithmetic
22dt_winter = datetime(2018, 2, 14, 12, tzinfo=NYC_d)
23dt_spring = dt_winter + timedelta(days=60)
24print(dt_spring)
25# 2018-04-15 12:00:00-04:00 # correct
26
27dt_winter = NYC_p.localize(datetime(2018, 2, 14, 12)) # potential Bug vector1
28dt_spring = dt_winter + timedelta(days=60)
29print(dt_spring)
30# 2018-04-15 12:00:00-05:00 # incorrect. subtle gotcha!
31print(NYC_p.normalize(dt_spring)) # potential Bug vector2
32# 2018-04-15 13:00:00-04:00 # correct