I have a python 2.7 codebase that I’m trying to containerize. Much as I’d like to, our devs cannot move to Python 3.
When running natively in their dev environments, datetimes respect timezones. I can confirm that the output is as expected on a Mac running Python 3.9.6
. But when we containerize this on Ubuntu base images, this no longer works correctly.
Using python:2.7.18-buster
works correctly, but that is a 3 year old image that doesn’t get updates. Both ubuntu:18.04
and ubuntu:16.04
fail.
The incorrect output when run at this time is
UTC Hour: 22
NY Hour: 22
1609459200.0
London Hour: 22
1609459200.0
The code to repro the issue is
import os
import datetime
import time
from dateutil.parser import parse
date_string="2021-01-01"
os.environ.get("TZ") # should be none, use system TZ, which is UTC
print ("UTC Hour: ", datetime.datetime.now().hour) # should be whatever hour it is in UTC
os.environ["TZ"] = "America/New_York"
print ("NY Hour:", datetime.datetime.now().hour) # should be whatever hour it is in EST
print (time.mktime(parse(date_string).timetuple())) # should be 1609477200.0
os.environ["TZ"] = "Europe/London"
print ("London Hour: ", datetime.datetime.now().hour) # should be whatever hour it is in GMT
print (time.mktime(parse(date_string).timetuple())) # should be 1609459200.0
2
Answers
It turns out that
python:2.7.18-buster
includes tzdata under/usr/share/zoneinfo
. Neitherubuntu:16.04
norubuntu:18.04
does this, so the function posted fails.Simply installing
tzdata
with apt resolves the issue.You can avoid changing environment variables by using aware datetime consistently. To calculate Unix time, derive it from a timedelta.
Note: tested with Python 2.7.18 on Linux, but not in a Docker environment.