0

I need to convert a series of naive datetimes to their local tz. Local tz is stored separately as ISO8601 format (e.g. '-0800' for PST).

I've tried replacing the datetime with a new one, adding the offset:

>>>utc_time 
datetime.datetime(2014, 1, 24, 0, 32, 30, 998654)
>>>tz_offset
u'-0800'
>>>local_time = utc_time.replace(tzinfo=tz_offset)
*** TypeError: tzinfo argument must be None or of a tzinfo subclass, not type 'unicode'

and tried using pytz to localize(), which requires calling timezone() first:

>>>timezone(tz_offset)
*** UnknownTimeZoneError: '-0800'

*doc for this step here:http://pytz.sourceforge.net/#localized-times-and-date-arithmetic

Any suggestions for making these offsets work?

*similar question here but uses a different format, I think.

Community
  • 1
  • 1
Thain
  • 245
  • 1
  • 3
  • 9

2 Answers2

2

The same timezone may have different utc offsets on different dates. Use timezone names instead of a string utc offset:

import datetime
import pytz # $ pip install pytz

utc_time = datetime.datetime(2014, 1, 24, 0, 32, 30, 998654)
utc_dt = utc_time.replace(tzinfo=pytz.utc) # make it timezone aware
pc_dt = utc_dt.astimezone(pytz.timezone('America/Los_Angeles')) # convert to PST

print(pc_dt.strftime('%Y-%m-%d %H:%M:%S.%f %Z%z'))
# -> 2014-01-23 16:32:30.998654 PST-0800
jfs
  • 399,953
  • 195
  • 994
  • 1,670
1

As the error message said, you need a tzinfo subclass (i.e. tzinfo object), which pytz.timezone returns from a timezone string, but it does not understand the offset format you are providing.

Another relevant thread to your problem, which links to this google app engine application, which also provide some source code. Here is a quick and naive example, if you desire.

class NaiveTZInfo(datetime.tzinfo):

    def __init__(self, hours):
        self.hours = hours

    def utcoffset(self, dt):
        return datetime.timedelta(hours=self.hours)

    def dst(self, dt):
        return datetime.timedelta(0)

    def tzname(self, dt):
        return '+%02d' % self.hours

To handle your offset format, you have to write your own parsing logic for the format you are providing.

>>> t = NaiveTZInfo(-5)
>>> u = datetime.datetime(2014, 1, 24, 0, 32, 30, 998654)
>>> v = u.replace(tzinfo=t)
>>> str(v)
'2014-01-24 00:32:30.998654-05:00'
Community
  • 1
  • 1
metatoaster
  • 17,419
  • 5
  • 55
  • 66