如何将日期时间从一个任意时区转换为另一个任意时区
How to convert a datetime from one arbitrary timezone to another arbitrary timezone
假设我在请求中收到一个任意的日期时间对象,就像这样,它可能来自任何可能的时区——我不知道是哪个时区。
为了举例,假设它来自东海岸
import pytz
from colander import iso8601
...
ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00')
假装ests1是进来的对象
使用 pytz,我可以了解一下它的时区
etz = ests1.timetz() # 00:00:00-04:00
etzi = ests1.tzinfo # <FixedOffset '-04:00' datetime.timedelta(-1, 72000)>
etzn = ests1.tzname() # '-04:00' # EST
edst = ests1.dst() # '0:00:00'
请注意,无论 ests1 是什么日期 - dst() 似乎总是 return 相同的值
我想做这样的事情:
psts1 = pytz.timezone(etzn
).localize(dtime.datetime.fromtimestamp(ests1)
).astimezone(pytz.timezone('US/Pacific'))
但这只会导致
UnknownTimeZoneError: '-04:00'
我也试过这个:
def convert_dt_to_pstz(dt):
pstoffset = -25200 # -7 * 60 * 60 - but what about DST? how do we tell which offset to use? -8 or -7
return dt.astimezone(tzoffset(None,pstoffset)) # convert to PST
但问题是我不知道如何判断日期是否需要针对夏令时进行调整。
我也试过这个:
utc_date = ests1.astimezone(pytz.utc) # 2016-04-01T04:00:00+00:00
ptz = pytz.timezone('US/Pacific')
new_date = utc_date.replace(tzinfo=ptz) # 2016-04-01T04:00:00-07:53
但是看看 new_date 的奇怪结果:-07:53
??
请注意,我不能使用与 "now" 或服务器位置相对应的任何信息,因为它可能在任何地方
我想我这次做对了:
from datetime import datetime as dtime
import pytz
from colander import iso8601
ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00')
epoch = dtime(1970, 1, 1, tzinfo=pytz.UTC) # 1970-01-01T00:00:00+00:00
ept = (ests1 - epoch).total_seconds() # 1459483200.0
utc_date = dtime.fromtimestamp(ept, tz=pytz.UTC) # 2016-04-01T04:00:00+00:00
ptz = pytz.timezone('US/Pacific')
pst_date = dtime.fromtimestamp(ept, tz=ptz) # 2016-03-31T21:00:00-07:00
ests2 = iso8601.parse_date('2016-02-01T00:00:00.0000-04:00')
ept2 = (ests2 - epoch).total_seconds() # 1454299200.00
utc_date2 = dtime.fromtimestamp(ept2, tz=pytz.UTC) # 2016-02-01T04:00:00+00:00
pst_date2 = dtime.fromtimestamp(ept2, tz=ptz) # 2016-01-31T20:00:00-08:00
所以,好像就这么简单
def convert_to_tz(dt,tz_new):
seconds = (dt - epoch).total_seconds()
return dtime.fromtimestamp(seconds, tz=tz_new)
要将时区感知 datetime
对象转换为不同的时区,use datetime.astimezone()
method:
pacific_time = ests1.astimezone(pytz.timezone('US/Pacific'))
一般来说,pytz
docs建议对结果调用pytz.timezone('US/Pacific').normalize()
,但这里不需要,因为ests1
时区有固定的utc偏移量。
假设我在请求中收到一个任意的日期时间对象,就像这样,它可能来自任何可能的时区——我不知道是哪个时区。 为了举例,假设它来自东海岸
import pytz
from colander import iso8601
...
ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00')
假装ests1是进来的对象
使用 pytz,我可以了解一下它的时区
etz = ests1.timetz() # 00:00:00-04:00
etzi = ests1.tzinfo # <FixedOffset '-04:00' datetime.timedelta(-1, 72000)>
etzn = ests1.tzname() # '-04:00' # EST
edst = ests1.dst() # '0:00:00'
请注意,无论 ests1 是什么日期 - dst() 似乎总是 return 相同的值
我想做这样的事情:
psts1 = pytz.timezone(etzn
).localize(dtime.datetime.fromtimestamp(ests1)
).astimezone(pytz.timezone('US/Pacific'))
但这只会导致
UnknownTimeZoneError: '-04:00'
我也试过这个:
def convert_dt_to_pstz(dt):
pstoffset = -25200 # -7 * 60 * 60 - but what about DST? how do we tell which offset to use? -8 or -7
return dt.astimezone(tzoffset(None,pstoffset)) # convert to PST
但问题是我不知道如何判断日期是否需要针对夏令时进行调整。
我也试过这个:
utc_date = ests1.astimezone(pytz.utc) # 2016-04-01T04:00:00+00:00
ptz = pytz.timezone('US/Pacific')
new_date = utc_date.replace(tzinfo=ptz) # 2016-04-01T04:00:00-07:53
但是看看 new_date 的奇怪结果:-07:53 ??
请注意,我不能使用与 "now" 或服务器位置相对应的任何信息,因为它可能在任何地方
我想我这次做对了:
from datetime import datetime as dtime
import pytz
from colander import iso8601
ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00')
epoch = dtime(1970, 1, 1, tzinfo=pytz.UTC) # 1970-01-01T00:00:00+00:00
ept = (ests1 - epoch).total_seconds() # 1459483200.0
utc_date = dtime.fromtimestamp(ept, tz=pytz.UTC) # 2016-04-01T04:00:00+00:00
ptz = pytz.timezone('US/Pacific')
pst_date = dtime.fromtimestamp(ept, tz=ptz) # 2016-03-31T21:00:00-07:00
ests2 = iso8601.parse_date('2016-02-01T00:00:00.0000-04:00')
ept2 = (ests2 - epoch).total_seconds() # 1454299200.00
utc_date2 = dtime.fromtimestamp(ept2, tz=pytz.UTC) # 2016-02-01T04:00:00+00:00
pst_date2 = dtime.fromtimestamp(ept2, tz=ptz) # 2016-01-31T20:00:00-08:00
所以,好像就这么简单
def convert_to_tz(dt,tz_new):
seconds = (dt - epoch).total_seconds()
return dtime.fromtimestamp(seconds, tz=tz_new)
要将时区感知 datetime
对象转换为不同的时区,use datetime.astimezone()
method:
pacific_time = ests1.astimezone(pytz.timezone('US/Pacific'))
一般来说,pytz
docs建议对结果调用pytz.timezone('US/Pacific').normalize()
,但这里不需要,因为ests1
时区有固定的utc偏移量。