Skip to content

Instantly share code, notes, and snippets.

@cbogart
Created July 24, 2020 18:33
Show Gist options
  • Save cbogart/d3952bdc8b24a2b487deac84ce01d83a to your computer and use it in GitHub Desktop.
Save cbogart/d3952bdc8b24a2b487deac84ce01d83a to your computer and use it in GitHub Desktop.
Moving a list of times forward a few months, taking into account daylight savings, and maybe a new timezone
import datetime
import pytz
# Note pytz is not standard python library, but there
# are no standard timezone classes before Python 3.2!!
# This is Python 2.7 code.
source_timezone = "America/New_York"
destination_timezone = "America/New_York"
# There are 2 kinds of dates:
# Naive dates just have date and time, and we have no idea what time zone they represent,
# unless we know from context somehow
# Timezoned dates have a time zone associated. We can convert to other timezones, and
# the hours (and sometimes minutes) change, but also the zone changes
# We typically store dates timezoned, in UTC as the timezone.
# This exercise demos taking UTC dates for events that happened in Pittsburgh at midnight,
# converting them to timezoned Pittsburgh dates, then making them naive, so
# they all show up as midnight dates.
# Then we shift them forward a few weeks
# Then force them to be pittsburgh timezone-aware dates again,
# Then finally shift back to UTC to be standard.
# Suppose we have a list of module start and end dates; these are
# stored internally as UTC. If you call, for example
# Course.objects.get(slug="f16-15319").start_time, you'll
# get an object of type datetime.datetime, that is timezone-aware,
# with timezone set to UTC
# Example has two pittsburgh-midnight dates before, and two after
# the time change
original_module_dates_utc = \
[datetime.datetime(2020,1,1,5,0,0, tzinfo=pytz.utc),
datetime.datetime(2020,1,7,5,0,0, tzinfo=pytz.utc),
datetime.datetime(2020,7,1,4,0,0, tzinfo=pytz.utc),
datetime.datetime(2020,7,7,4,0,0, tzinfo=pytz.utc)]
#
# Note: never do datetime(...tzinfo=pytz.<something other than UTC>); this will not handle dst correctly
# see http://pytz.sourceforge.net/
#
print("Original dates as UTC")
for o in original_module_dates_utc:
print(o)
#
# Convert from UTC to local time, naive
def utc2local_naive_tz(t, the_tz):
t_naive = t.astimezone(pytz.timezone(the_tz))
t_naive = t_naive.replace(tzinfo=None)
return t_naive
print("Original dates as local, naive, assuming they happened in ", source_timezone)
original_dates_as_pgh_local_naive = \
[utc2local_naive_tz(t, source_timezone) for t in original_module_dates_utc]
for o in original_dates_as_pgh_local_naive:
print(o)
#
# Offset the dates without affecting the times, so that
# the translation ignores daylight savings changes
print("new dates as local, naive")
def addweeks(t,w):
return t + datetime.timedelta(days=w*7)
new_dates_as_pgh_local_naive = \
[addweeks(t,25) for t in original_dates_as_pgh_local_naive]
for n in new_dates_as_pgh_local_naive:
print(n)
#
# Convert back to UTC
#
def naive2utc_assuming_tz(t, dest):
t_utc = pytz.timezone(dest).localize(t)
t_utc = t_utc.astimezone(pytz.utc)
return t_utc
new_dates_as_utc = \
[naive2utc_assuming_tz(t,destination_timezone)
for t in new_dates_as_pgh_local_naive]
print("assuming those times were " + destination_timezone + ", convert back to utc")
for n in new_dates_as_utc:
print(n)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment