Python Daylight Savings Time

Python daylight savings time

You can use time.localtime and look at the tm_isdst flag in the return value.

>>> import time
>>> time.localtime()
(2010, 5, 21, 21, 48, 51, 4, 141, 0)
>>> _.tm_isdst
0

Using time.localtime(), you can ask the same question for any arbitrary time to see whether DST would be (or was) in effect for your current time zone.

How to convert local time to UTC, considering daylight saving time?

Assuming Local contains date/time as observed locally, i.e. including DST active/inactive, you would convert to datetime object, set time zone, and convert to UTC.

Ex:

from datetime import datetime, timezone
from zoneinfo import ZoneInfo # Python 3.9

Local = ["2018/07/20 09:00", "2018/12/31 11:00", "2019/01/17 13:00", "2020/08/15 18:00"]

# to datetime object and set time zone
LocalZone = ZoneInfo("Europe/Vienna")
Local = [datetime.strptime(s, "%Y/%m/%d %H:%M").replace(tzinfo=LocalZone) for s in Local]

for dt in Local:
print(dt.isoformat(" "))
# 2018-07-20 09:00:00+02:00
# 2018-12-31 11:00:00+01:00
# 2019-01-17 13:00:00+01:00
# 2020-08-15 18:00:00+02:00

# to UTC
UTC = [dt.astimezone(timezone.utc) for dt in Local]

for dt in UTC:
print(dt.isoformat(" "))
# 2018-07-20 07:00:00+00:00
# 2018-12-31 10:00:00+00:00
# 2019-01-17 12:00:00+00:00
# 2020-08-15 16:00:00+00:00

Note: with Python 3.9, you don't need third party libraries for time zone handling in Python anymore. There is a deprecation shim for pytz.

How to convert from Unix epoch time and account for daylight saving time in Python?

The operating system has support for time zone conversions, and Python can use that. You don't need to handle it in your Python code.

You get to it using the pytz module. It is also preferred to use the datetime object.

import pytz
from datetime import datetime

MYTZ = "America/Los_Angeles"
TS = 1631491515.6691816

tzinfo = pytz.timezone(MYTZ)

t = datetime.fromtimestamp(TS, tzinfo)
print(t)

2021-09-12 17:05:15.669182-07:00

Is there a way to infer in Python if a date is the actual day in which the DST (Daylight Saving Time) change is made?

You can make use of datetime.dst() (a change in UTC offset is not necessarily a DST transition):

from datetime import datetime, time, timedelta
from zoneinfo import ZoneInfo # Python 3.9+

def is_date_of_DSTtransition(dt: datetime, zone: str) -> bool:
"""
check if the date part of a datetime object falls on the date
of a DST transition.
"""
_d = datetime.combine(dt.date(), time.min).replace(tzinfo=ZoneInfo(zone))
return _d.dst() != (_d+timedelta(1)).dst()

e.g. for tz Europe/Berlin:

for d in range(366):
if is_date_of_DSTtransition(datetime(2021, 1, 1) + timedelta(d), "Europe/Berlin"):
print((datetime(2021, 1, 1) + timedelta(d)).date())
# 2021-03-28
# 2021-10-31

Note: I'm using zoneinfo here instead of pytz; for legacy code, there is a pytz deprecation shim. Here's a pytz version anyway (needs an additional normalize):

import pytz
def is_date_of_DSTtransition(dt: datetime, zone: str) -> bool:
_d = pytz.timezone(zone).localize(datetime.combine(dt.date(), time.min))
return _d.dst() != pytz.timezone(zone).normalize(_d+timedelta(1)).dst()

Daylight savings time in Python

From the pytz documentation:

The preferred way of dealing with times is to always work in UTC, converting to localtime only when generating output to be read by humans.

So ideally you should be using utcnow instead of now.

Assuming for some reason that your hands are tied and you need to work with local times, you can still run into a problem with trying to localize the current time if you're doing it during the daylight saving transition window. The same datetime might occur twice, once during daylight time and again during standard time, and the localize method doesn't know how to settle the conflict unless you tell it explicitly with the is_dst parameter.

So to get the current UTC time:

utc = pytz.timezone('UTC')
now = utc.localize(datetime.datetime.utcnow())

And to convert it to your local time (but only when you must):

la = pytz.timezone('America/Los_Angeles')
local_time = now.astimezone(la)

Edit: as pointed out in the comments by @J.F. Sebastian, your first example using datetime.now(tz) will work in all cases. Your second example fails during the fall transition as I outlined above. I still advocate using UTC instead of local time for everything except display.

Django not accounting for Daylight Savings Time

Set your TIME_ZONE='America/New_York' (or whatever appropriate locale).

"EST" (UTC−05:00) and "EDT" (UTC−04:00) are different specific time offsets, and don't change with daylight savings, you need to use a location based timezone which will take into account daylight savings seasonal change.



Related Topics



Leave a reply



Submit