cpython icon indicating copy to clipboard operation
cpython copied to clipboard

If you have the /etc/timezone file set to a timezone string, zoneinfo.ZoneInfo("UTC") has the utcoffset of that timezone instead of 0

Open gibsondan opened this issue 1 year ago • 4 comments

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

gibsondan avatar Mar 12 '24 20:03 gibsondan

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 avatar Mar 15 '24 18:03 chaoyihu

@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

gibsondan avatar Mar 15 '24 19:03 gibsondan

(Another user reported hitting this problem when they mounted the host /etc/localtime into the container - I have not attempted that myself though)

gibsondan avatar Mar 15 '24 19:03 gibsondan

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

chaoyihu avatar Mar 22 '24 02:03 chaoyihu

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").

pganssle avatar Feb 08 '25 18:02 pganssle