How do I check if daylight saving time is in effect?
8 Answers
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.

- 951,095
- 183
- 1,149
- 1,285
-
It may be a bit more clear to use time.daylight property. It will return a non-zero result if your current time zone has DST. – brian buck May 21 '10 at 15:33
-
13@brian buck: That's different though. For a given time zone, `time.daylight` is constant because a daylight zone either exists or it doesn't. On the other hand, the `tm_isdst` flag reflects whether the given time is *within* the DST start and end dates. – Greg Hewgill May 21 '10 at 19:28
-
1This confusion over `time.daylight` appears to be a bigger issue: http://bugs.python.org/issue7229. – Zach Young Dec 06 '11 at 22:19
-
2it should be `_.tm_isdst > 0` (`-1` value is possible). – jfs Feb 22 '14 at 08:05
-
10Ahhh! I hate these sort of answers for Python questions as it is a command line example that does not illuminate (to me) how to put this into a function. (My naive effort to try time.localtime().tm_isdst does not work.) So I will plumb further and augment the answer. – Jiminion Apr 08 '16 at 15:36
-
This likely works perfectly on your laptop, but it uses the computer's timezone, and one rarely knows which computer their code will run on. See my answer for an explanation of the problems and a more complete solution. – krethika May 02 '19 at 17:41
-
Is there a way to write _.tm_isdst as a variable? I want to use it in an if else statement (if _.tm_isdst > 0 etc. – Andrew Mar 29 '21 at 20:08
The accepted answer is fine if you are running code on your laptop, but most python applications are running on a server using UTC as local time, so they will NEVER be in daylight savings time according to the accepted answer.
The second problem is that different regions implement daylight savings on
different days and times. So even if you have an unambiguous time, such as
datetime.utcnow()
, it could be daylight savings time in one timezone but not
in another.
The best we can do then, is tell whether a given time occurs during DST for a
specific timezone, and the best method I can find for doing it has already
been implemtend by pytz localize
function and we can use it to get a
pretty good answer that works both on our laptop and on a server.
import pytz
from datetime import datetime
def is_dst(dt=None, timezone="UTC"):
if dt is None:
dt = datetime.utcnow()
timezone = pytz.timezone(timezone)
timezone_aware_date = timezone.localize(dt, is_dst=None)
return timezone_aware_date.tzinfo._dst.seconds != 0
Some examples
>>> is_dst() # it is never DST in UTC
False
>>> is_dst(datetime(2019, 1, 1), timezone="US/Pacific")
False
>>> is_dst(datetime(2019, 4, 1), timezone="US/Pacific")
True
>>> is_dst(datetime(2019, 3, 10, 2), timezone="US/Pacific")
NonExistentTimeError
>>> is_dst(datetime(2019, 11, 3, 1), timezone="US/Pacific")
AmbiguousTimeError
In our is_dst
function, we specified is_dst=None
as a parameter to
timezone.localize
, which will cause nonsense times to throw errors. You
could use is_dst=False
to ignore these errors and return False
for those
times.

- 3,908
- 1
- 24
- 27
-
1@otocan feel free to share the code you ran, python version, and anything else that might be relevant. – krethika Feb 13 '20 at 17:33
-
I get AttributeError: 'str' object has no attribute 'tzinfo' in is_dst timezone_aware_date = timezone.localize(dt, is_dst=None) File "C:\Applicazioni_Tommaso\Phyton\lib\site-packages\pytz\tzinfo.py", line 317, in localize if dt.tzinfo is not None: AttributeError: 'str' object has no attribute 'tzinfo' – Tms91 May 14 '20 at 13:42
-
1@Tms91 dt should be a datetime, not a string. You can create a datetime object by parsing the string with `datetime.strptime` – krethika May 15 '20 at 05:30
Assuming you want to perform this on a datetime
Use pytz
to make it timezone aware and then check its dst
property:
import datetime
import pytz
def is_dst(dt,timeZone):
aware_dt = timeZone.localize(dt)
return aware_dt.dst() != datetime.timedelta(0,0)
timeZone = pytz.timezone("Europe/London")
dt = datetime.datetime(2019,8,2)
is_dst(dt,timeZone)
True
dt = datetime.datetime(2019,2,2)
is_dst(dt,timeZone)
False

- 824
- 11
- 16
-
1I really dislike stuff that's not needed, like those brackets around the True and False, but then the entire if statement isn't needed either, just return the comparison. – Mark Lawrence Feb 19 '20 at 14:08
-
1I think the if/else helped somewhat in understanding the logic at a glance, but basically you're right. – otocan Feb 20 '20 at 15:07
I would have posted this as a comment to the answer by @mehtunguh above, but my current reputation level does not allow me to comment.
I think there may be an issue with the is_dst
function as written when the dt
argument is omitted.
When the dt
argument is omitted, dt
is set to datetime.utcnow()
which returns a naive datetime representing the current UTC time. When that is passed to pytz.localize
, the resulting localized time is not the current time in the specified time zone, but rather the local time that has the same hour, minute, second, as the current UTC time.
So, for example, as I write this it is 10:50 AM EST in the US/Eastern time zone, and datetime.utcnow()
returns a datetime value with hour=15
and minute=50
. As written, when invoked as is_dst(timezone='US/Eastern')
, is_dst
is not checking whether the current local time of 10:50 AM EST is during daylight saving time, it is checking whether 3:50 PM EST is during daylight saving time.
I think is_dst
should perhaps be coded as follows:
import datetime
import pytz
def is_dst(dt=None, timezone='UTC'):
timezone = pytz.timezone(timezone)
if dt is None:
dt = datetime.datetime.now(datetime.timezone.utc)
if dt.tzinfo is None:
tz_aware_dt = timezone.localize(dt, is_dst=None)
else:
tz_aware_dt = dt.astimezone(timezone)
return tz_aware_dt.tzinfo._dst.seconds != 0
This version allows passing either a naive datetime value or a timezone-aware datetime value as the dt
argument. When the dt
argument is omitted, it uses a timezone-aware version of the current UTC time so that when that gets localized to the specified timezone it represents the current time in that timezone.

- 55
- 5
None of the above helped me so I found my own workaround.
I relate to the logic implemented in https://gist.github.com/dpapathanasiou/09bd2885813038d7d3eb while there's still a problem, it doesn't work in real life apparently :(
Currently I'm in Israel and here we move the clock in the end of the month,
while in Australia they have already moved the clock.
All the codes return True
for both Asia/Jerusalem
and Australia/Sydney
.
Eventually I used an external 3rd party API - https://worldtimeapi.org/ - by which I analyse whether the utc_offset
is 11 hours (rather that 10:05).
from requests import get as Get
is_dst = True
try:
tz_check = Get('https://worldtimeapi.org/api/timezone/Australia/Sydney')
is_dst = tz_check.json().get('utc_offset') == '+11:00'
except Exception as e:
print('!!! Error getting timezone', e)
I agree this is a private case, but I hope this can help someone :)

- 3,310
- 2
- 21
- 31
Expanding @Greg Hewgill's answer above, plus coping with local timezone (with help of pip install tzlocal
), you get:
import time
from datetime import datetime, timedelta
from tzlocal import get_localzone
def to_local(dt):
"""From any timezone to local datetime - also cope with DST"""
localtime = time.localtime()
if localtime.tm_isdst:
utctime = time.gmtime()
hours_delta = timedelta(hours=(localtime.tm_hour - utctime.tm_hour))
dt = dt - hours_delta
return dt.replace(tzinfo=get_localzone())

- 7,286
- 2
- 34
- 19
I'm from the UK and this is how I handled my server returning the wrong time for half the year:
import pytz
from typing import Optional
from datetime import datetime
class BritishTime(datetime):
timezone = pytz.timezone('Europe/London')
@classmethod
def dst(cls, dt: Optional[datetime] = None):
dt = dt if dt is not None else cls.now()
return cls.timezone.dst(dt)
Now if I create a datetime object with BritishTime
, it has the dst
method which I can use to both check and update the time, something like this:
def get_correct_time(timestamp):
updated = BritishTime.fromtimestamp(timestamp)
return updated + updated.dst()
Works pretty well.

- 1,325
- 8
- 12
Below, I'll show yet another way, but this could never be overemphasized:
DST rules are magic (determined by local law) and can change from year to year.
# IMHO a really nasty magic.
(From the Python doc for the time
module.)
In Unix, yet another way is to simply invoke the date
command, if you are familiar with the target timezone:
import subprocess
# First Sun of 2022-03
subprocess.run(['date', '--date=2022-03-06 00:00:00'], env={"TZ": "US/Eastern"})
# Next Sun, 00:00 (
subprocess.run(['date', '--date=2022-03-13 00:00:00'], env={"TZ": "US/Eastern"})
# Ditto, 12:00
subprocess.run(['date', '--date=2022-03-13 12:00:00'], env={"TZ": "US/Eastern"})
The output:
Thu Mar 10 12:00:00 EST 2022
Sun Mar 13 00:00:00 EST 2022
Sun Mar 13 12:00:00 EDT 2022
EST
is for the not-DST season, and EDT
for the DST.
Anyway the transition period between the DST/non-DST is really tricky.

- 1,348
- 1
- 16
- 21