Use Python to find out if a timezone currently in daylight savings time

30,599

Solution 1

import pytz
from datetime import datetime, timedelta

def is_dst(zonename):
    tz = pytz.timezone(zonename)
    now = pytz.utc.localize(datetime.utcnow())
    return now.astimezone(tz).dst() != timedelta(0)

Usage:

>>> is_dst("America/Los_Angeles")
False

>>> is_dst("America/Sao_Paulo")
True

Solution 2

from datetime import datetime
import pytz

isdst_now_in = lambda zonename: bool(datetime.now(pytz.timezone(zonename)).dst())

Example:

>>> isdst_now_in("America/Los_Angeles") # 2014-10-27 12:32:07 PDT-0700
True
>>> isdst_now_in("Australia/Melbourne") # 2014-10-28 06:32:07 AEDT+1100
True

Here's stdlib-only version on Unix using time.tzset() function:

import os
import time
from contextlib import contextmanager

@contextmanager
def local_timezone(zonename):
    #NOTE: it manipulates global state
    oldname = os.environ.get('TZ')
    try:
        os.environ['TZ'] = zonename
        time.tzset()
        yield
    finally:
        if oldname is None:
           del os.environ['TZ']
        else:
           os.environ['TZ'] = oldname
        time.tzset()

def time_isdst_now_in(zonename):
    with local_timezone(zonename):
         return time.localtime().tm_isdst > 0

The usage is the same:

>>> time_isdst_now_in('Europe/London') # 2014-04-17 18:42:11 BST+0100
True

Note: time.daylight is not used due to issues in some edge cases.

Share:
30,599

Related videos on Youtube

Joey Mason
Author by

Joey Mason

Updated on July 09, 2022

Comments

  • Joey Mason
    Joey Mason almost 2 years

    We have a server that runs on GMT time. I need to write a Python script that determines if it's currently (at this very second) Daylight Savings Time (DST) in Los Angeles, CA. How can I accomplish this? I took a look at pytz and time, but I can't figure it out. I realize that I could create some logic such as comparing the current time in LA to GMT time, but it would be a lot cleaner if I could use a standard library instead.

    Thanks

    Edit: Here's some sample code of me setting up the timezone:

    from pytz import timezone
    import pytz
    from datetime import datetime, timedelta
    
    tz = timezone('America/Los_Angeles')
    // Instantiate a datetime object using tz? 
    

    Edit: Here's a snippet of code that will work. It's not elegant, which is why I'm asking if there's a library or something that is made for this. Maybe like a is_dst() function.

    utc = timezone("UTC")
    now = utc.localize(datetime.utcnow())
    los_angeles_tz = timezone('America/Los_Angeles')
    los_angeles_time = now.astimezone(los_angeles_tz)
    
    delta = los_angeles_time.utcoffset()
    dstDelta = timedelta(hours=-8)
    
    is_dst = (delta == dstDelta)
    
    • kgu87
      kgu87 over 10 years
    • Jon Clements
      Jon Clements over 10 years
      @Marcin to be fair - it's not the most friendly area of Python's library to have a stab at attempting a solution with. So while technically off-topic, it's not exactly an unreasonable question.
    • Marcin
      Marcin over 10 years
      @JonClements Perhaps so, but it would be nice to see something that demonstrates OP went beyond opening the docs and saying "gosh this looks hard, maybe someone on SO can solve my problem".
    • jfs
      jfs almost 9 years
  • jfs
    jfs over 9 years
    @user1615497: you could use datetime.now(tz) to get the current time in tz timezone e.g., is_dst = lambda zonename: bool(datetime.now(pytz.timezone(zonename)).dst())
  • Matt Johnson-Pint
    Matt Johnson-Pint over 9 years
    @J.F.Sebastian - pytz docs make it clear that localize needs to be used; that passing a pytz time zone to the tzinfo parameter of a datetime is not sufficient. Is this wrong?
  • jfs
    jfs over 9 years
    it is wrong for now(tz) in general and UTC timezone in particular. now() is documented to call tz.fromutc() that is overridden by pytz timezone to do the right thing (use _utc_transition_times to get valid tzinfo). In addition, UTC is a special case: zero UTC offset, always
  • jfs
    jfs almost 7 years