Question

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)
Was it helpful?

Solution 2

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)

OTHER TIPS

timezone.localize has is_dst parameter that defaults to False. It is used for ambiguous or non-existing input dates. You can set it to None to raise an exception instead in such cases.

Why do you expect to get a different result only because an index inside your list is different for datetime(2013,4,7,2)?

>>> from datetime import datetime
>>> import pytz
>>> timezone = pytz.timezone('Australia/Sydney')
>>> timezone.localize(datetime(2013,4,7,2))
datetime.datetime(2013, 4, 7, 2, 0,
                  tzinfo=<DstTzInfo 'Australia/Sydney' EST+10:00:00 STD>)
>>> timezone.localize(datetime(2013,4,7,2), is_dst=False)
datetime.datetime(2013, 4, 7, 2, 0,
                  tzinfo=<DstTzInfo 'Australia/Sydney' EST+10:00:00 STD>)
>>> timezone.localize(datetime(2013,4,7,2), is_dst=True)
datetime.datetime(2013, 4, 7, 2, 0,
                  tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
>>> timezone.localize(datetime(2013,4,7,2), is_dst=None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/pytz/tzinfo.py", line 344, in localize
    raise AmbiguousTimeError(dt)
pytz.exceptions.AmbiguousTimeError: 2013-04-07 02:00:00

Unless you provide is_dst parameter explicitely there is no way for pytz to find out what time is datetime(2013,4,7,2).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top