Python时区转换

Python Timezone conversion

我正在寻找一种快速输入时间的方法,然后python将其转换为其他时区(可能多达10个不同的时区)

对不起的。我对Python一点也不熟悉,如果有人能把我放在正确的方向上,我会非常感激的。


我发现最好的方法是将感兴趣的"时刻"转换为支持UTC时区的日期时间对象(在python中,日期时间对象不需要时区组件)。

然后可以使用astimezone转换为感兴趣的时区(引用)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from datetime import datetime
import pytz

utcmoment_naive = datetime.utcnow()
utcmoment = utcmoment_naive.replace(tzinfo=pytz.utc)

# print"utcmoment_naive: {0}".format(utcmoment_naive) # python 2
print("utcmoment_naive: {0}".format(utcmoment_naive))
print("utcmoment:       {0}".format(utcmoment))

localFormat ="%Y-%m-%d %H:%M:%S"

timezones = ['America/Los_Angeles', 'Europe/Madrid', 'America/Puerto_Rico']

for tz in timezones:
    localDatetime = utcmoment.astimezone(pytz.timezone(tz))
    print(localDatetime.strftime(localFormat))

# utcmoment_naive: 2017-05-11 17:43:30.802644
# utcmoment:       2017-05-11 17:43:30.802644+00:00
# 2017-05-11 10:43:30
# 2017-05-11 19:43:30
# 2017-05-11 13:43:30

因此,当您对本地时区(一个存在的时间)感兴趣时,您可以像这样将其转换为UTC(参考)。

1
2
3
4
5
6
7
8
9
10
11
12
localmoment_naive = datetime.strptime('2013-09-06 14:05:10', localFormat)

localtimezone = pytz.timezone('Australia/Adelaide')

try:
    localmoment = localtimezone.localize(localmoment_naive, is_dst=None)
    print("Time exists")

    utcmoment = localmoment.astimezone(pytz.utc)

except pytz.exceptions.NonExistentTimeError as e:
    print("NonExistentTimeError")


使用Pyz

1
2
3
4
5
6
7
8
9
from datetime import datetime
from pytz import timezone

fmt ="%Y-%m-%d %H:%M:%S %Z%z"
timezonelist = ['UTC','US/Pacific','Europe/Berlin']
for zone in timezonelist:

    now_time = datetime.now(timezone(zone))
    print now_time.strftime(fmt)


要在python中将一个时区转换为另一个时区,可以使用datetime.astimezone()

1
time_in_new_timezone = time_in_old_timezone.astimezone(new_timezone)

给定aware_dt(某个时区中的datetime对象),将其转换为其他时区并以给定的时间格式打印时间:

1
2
3
4
5
6
7
8
#!/usr/bin/env python3
import pytz  # $ pip install pytz

time_format ="%Y-%m-%d %H:%M:%S%z"
tzids = ['Asia/Shanghai', 'Europe/London', 'America/New_York']
for tz in map(pytz.timezone, tzids):
    time_in_tz = aware_dt.astimezone(tz)
    print(f"{time_in_tz:{time_format}}")

如果f""语法不可用,可以用"".format(**vars())替换。

在本地时区中,可以从当前时间设置aware_dt

1
2
3
4
5
from datetime import datetime
import tzlocal  # $ pip install tzlocal

local_timezone = tzlocal.get_localzone()
aware_dt = datetime.now(local_timezone) # the current time

或从本地时区的输入时间字符串:

1
2
naive_dt = datetime.strptime(time_string, time_format)
aware_dt = local_timezone.localize(naive_dt, is_dst=None)

其中time_string可以是:'2016-11-19 02:21:42'。对应于time_format = '%Y-%m-%d %H:%M:%S'

如果输入时间字符串对应于不存在或不明确的本地时间(如DST转换期间),则is_dst=None强制执行异常。你也可以通过is_dst=Falseis_dst=True。在python上查看包含更多详细信息的链接:如何将日期时间/时间戳从一个时区转换为另一个时区?


请注意:这个答案的第一部分是1.x版的摆锤。请参阅下面的2.x版答案。

希望我不会太迟!

钟摆库擅长于这个和其他日期时间计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.datetime.strptime(heres_a_time, '%Y-%m-%d %H:%M %z')
>>> for tz in some_time_zones:
...     tz, pendulum_time.astimezone(tz)
...    
('Europe/Paris', <Pendulum [1996-03-25T17:03:00+01:00]>)
('Europe/Moscow', <Pendulum [1996-03-25T19:03:00+03:00]>)
('America/Toronto', <Pendulum [1996-03-25T11:03:00-05:00]>)
('UTC', <Pendulum [1996-03-25T16:03:00+00:00]>)
('Canada/Pacific', <Pendulum [1996-03-25T08:03:00-08:00]>)
('Asia/Macao', <Pendulum [1996-03-26T00:03:00+08:00]>)

答案列出了可能与钟摆一起使用的时区名称。(它们和Pytz的一样。)

版本2:

  • some_time_zones是程序中可能使用的时区名称的列表。
  • heres_a_time是一个样本时间,以'-0400'的形式填写一个时区。
  • 我首先将时间转换为钟摆时间,以便后续处理。
  • 现在我可以展示一下这个时间在show_time_zones的每个时区里是什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.from_format('1996-03-25 12:03 -0400', 'YYYY-MM-DD hh:mm ZZ')
>>> for tz in some_time_zones:
...     tz, pendulum_time.in_tz(tz)
...    
('Europe/Paris', DateTime(1996, 3, 25, 17, 3, 0, tzinfo=Timezone('Europe/Paris')))
('Europe/Moscow', DateTime(1996, 3, 25, 19, 3, 0, tzinfo=Timezone('Europe/Moscow')))
('America/Toronto', DateTime(1996, 3, 25, 11, 3, 0, tzinfo=Timezone('America/Toronto')))
('UTC', DateTime(1996, 3, 25, 16, 3, 0, tzinfo=Timezone('UTC')))
('Canada/Pacific', DateTime(1996, 3, 25, 8, 3, 0, tzinfo=Timezone('Canada/Pacific')))
('Asia/Macao', DateTime(1996, 3, 26, 0, 3, 0, tzinfo=Timezone('Asia/Macao')))


1
2
3
4
5
6
7
8
9
10
11
12
13
import datetime
import pytz

def convert_datetime_timezone(dt, tz1, tz2):
    tz1 = pytz.timezone(tz1)
    tz2 = pytz.timezone(tz2)

    dt = datetime.datetime.strptime(dt,"%Y-%m-%d %H:%M:%S")
    dt = tz1.localize(dt)
    dt = dt.astimezone(tz2)
    dt = dt.strftime("%Y-%m-%d %H:%M:%S")

    return dt

-

  • dt:日期时间字符串
  • tz1:初始时区
  • tz2:目标时区

-

1
2
3
4
5
> convert_datetime_timezone("2017-05-13 14:56:32","Europe/Berlin","PST8PDT")
'2017-05-13 05:56:32'

> convert_datetime_timezone("2017-05-13 14:56:32","Europe/Berlin","UTC")
'2017-05-13 12:56:32'

-

1
2
3
4
5
6
7
8
9
10
11
> pytz.all_timezones[0:10]
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 'Africa/Algiers',
 'Africa/Asmara',
 'Africa/Asmera',
 'Africa/Bamako',
 'Africa/Bangui',
 'Africa/Banjul',
 'Africa/Bissau']

对于python时区转换,我使用taavi burns的pycon 2012演示文稿中的方便表。


对于python 3.2+简单日期是一个围绕pytz的包装器,它试图简化事情。

如果你有一个time,那么

1
SimpleDate(time).convert(tz="...")

可以做你想做的。但是时区是非常复杂的事情,所以它会变得更加复杂——看文档。