简体   繁体   中英

Add time zone offset (in ISO 8601 format) to naive datetime

I need to convert a series of naive datetimes to their local tz. Local tz is stored separately as ISO8601 format (eg '-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.

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

As the error message said, you need a tzinfo subclass (ie 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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM