Search code examples
pythonpytz

Daylight savings transition at wrong time


I've got a list of dates with no timezone info, however I know the timezone and the fact that they're localtime. I want to convert to standard time in order to perform timezone analysis

In Sydney daylight savings ends at 3am DST, so the first 5 rows should by +11:00 DST and the remainder +10:00 STD. The result I get is the first row is +11:00 DST and the remainder is +10:00 STD.

Is there a built in way of localising a list of dates, given that I know they're sorted. It appears you're expected to know if is_dst=True or is_dst=False in order to handle the overlap.

Regards Dave

import pytz

times = [
    datetime(2013,4,7,1,45,0)
    ,datetime(2013,4,7,2,0,0)
    ,datetime(2013,4,7,2,15,0)
    ,datetime(2013,4,7,2,30,0)
    ,datetime(2013,4,7,2,45,0)
    ,datetime(2013,4,7,2,00,0)
    ,datetime(2013,4,7,2,15,0)
    ,datetime(2013,4,7,2,30,0)
]
#
timezone = pytz.timezone('Australia/Sydney')
localized = map(timezone.localize, times)

for t,l in zip(times, localized):
    print(t,l)

Solution

  • This is the solution I came up with, data is sorted, so I set is_dst=True the first time I encounter and ambiguous time and False the 2nd. Also if a non-existant time is encountered I reset is_dst

    seen = set()
    
    get_datetime = operator.itemgetter('datetime')
    for row in data:
        dt = get_datetime(row)
    
        try:
            localized = timezone.localize(dt, is_dst=None)
        except pytz.NonExistentTimeError:
            localized = timezone.localize(dt, is_dst=True)
            seen = set()
        except pytz.AmbiguousTimeError:
            localized = timezone.localize(dt, is_dst=(dt not in seen)) 
            seen.add(dt)