If you have the /etc/timezone file set to a timezone string, zoneinfo.ZoneInfo("UTC") has the utcoffset of that timezone instead of 0
Bug report
Bug description:
To reproduce:
Build and run the following Dockerfile:
FROM python:3.10-slim
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
then in python:
import zoneinfo
import datetime
print(str(zoneinfo.ZoneInfo("UTC").utcoffset(datetime.datetime(2024, 3, 12, 0, 0, 0, 0))))
That will output 8:00:00 instead of the expected 0:00:00. Removing the echo statement from the Dockerfile returns it to 0:00:00 as expected.
CPython versions tested on:
3.10, 3.11
Operating systems tested on:
No response
I cannot reproduce it on Ubuntu 22.04.4 LTS, Docker version 25.0.4. Did I reproduce it properly?
Folder structure:
.
├── Dockerfile
└── script.py
My Dockerfile:
FROM python:3.10-slim
RUN echo "Asia/Shanghai" > /etc/timezone
COPY . .
CMD ["sh", "-c", "python script.py && cat /etc/timezone"]
My script.py:
import zoneinfo
import datetime
print("UTC", str(zoneinfo.ZoneInfo("UTC").utcoffset(datetime.datetime(2024, 3, 12, 0, 0, 0, 0))))
print("Asia/Shanghai", str(zoneinfo.ZoneInfo("Asia/Shanghai").utcoffset(datetime.datetime(2024, 3, 12, 0, 0, 0, 0))))
Build and run:
$ sudo docker build -t zit .
$ sudo docker run --name c1 zit:latest
The output:
UTC 0:00:00
Asia/Shanghai 8:00:00
Asia/Shanghai
@chaoyihu my apologies, in attempt to make the repro as simple as possible I accidentally made it no longer reproduce - the problem has to do with /etc/localtime not /etc/timezone. Here's a version of your Dockerfile that works:
FROM python:3.10-slim
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY . .
CMD ["sh", "-c", "python script.py"]
When I run that with your script.py, I get:
UTC 8:00:00
Asia/Shanghai 8:00:00
(Another user reported hitting this problem when they mounted the host /etc/localtime into the container - I have not attempted that myself though)
Just an update. I think this is unrelated to python and it actually looks like a docker issue.
The cause seems to be that binary files /usr/share/zoneinfo/Asia/Shanghai and /usr/share/zoneinfo/UTC are the same in the docker container. But I am still trying to find out why they would be the same.
To reproduce:
Create a comp.sh:
echo "$1"
echo "$2"
if diff "$1" "$2" >/dev/null; then
echo "same"
else
echo "differ"
fi
In Dockerfile:
FROM python:3.10-slim
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY . .
CMD ["sh", "-c", "./comp.sh /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/UTC"]
Build and run. The container outputs:
/usr/share/zoneinfo/Asia/Shanghai
/usr/share/zoneinfo/UTC
same
Compared to the expected output on local machine:
/usr/share/zoneinfo/Asia/Shanghai
/usr/share/zoneinfo/UTC
differ
Weird, but nothing we can or should do about this, so I am going to close it.
Probably a good cautionary tale to add to the many reasons to use datetime.timezone.UTC to represent UTC instead of ZoneInfo("UTC").