pythonlinuxdatetimeraspberry-pisubprocess

Python doesn't register change in timezone after being started


I have the a program running on a Raspberry Pi which, for the purpose of this question, can be boiled down to the following:

import datetime
import subprocess

#Change system timzone
subprocess.run('sudo timedatectl set-timezone America/Toronto', shell=True)

#Print date and time and timezone
print(datetime.datetime.now())

If I set my timezone to, let's say, Los Angeles, and then run this program, even though subprocess successfully runs the command to change the system timezone, the print command shows the time in the original timezone, as if it wasn't changed.

Now, if run:

import datetime

#Print date and time and timezone
print(datetime.datetime.now())

It shows the time with the changed timezone.

Why does Python (seemingly) not register the timezone changing if it was done while Python was running (using subprocess), and how can I avoid this problem?


Solution

  • You're seeing this because Python reads the system timezone only once when the process starts. Changing it mid-execution with timedatectl won't affect the current process.

    Fixes:

    1. Restart the script after changing timezone:

    sudo timedatectl set-timezone America/Toronto
    python script.py
    

    2. Use zoneinfo (Python 3.9+):

    from datetime import datetime
    from zoneinfo import ZoneInfo
    
    print(datetime.now(ZoneInfo("America/Toronto")))
    

    3. Use TZ + tzset() (Linux only):

    import os, time
    
    os.environ['TZ'] = 'America/Toronto'
    time.tzset()
    

    Only works with TZ, not timedatectl.

    TL;DR: Changing the system timezone doesn't affect a running Python process. Use zoneinfo, or restart the script.