1
2
datetime.datetime(2021, 1, 26, 10, 30, 42, 586335)
datetime.datetime(2021, 1, 26, 2, 30, 52, 265876, tzinfo=<UTC>)

datetime除了data方法生成的时间是时区概念,其他如time、datetime等都是有时区概念,即指定了tzinfo信息

上面的两种datetime的表现方式,第一个是没有时区的,显示的是系统的时区,第二个是显示的UTC时区的时间,和本地的相差8小时。

pytz模块

pytz模块用于时区的转换,常配合datetime模块使用。

常用方法:

  • pytz.country_timezones(‘国家代码’)

该方法可以拿到某个国家的时区名列表

1
2
>>> pytz.country_timezones('cn')
['Asia/Shanghai', 'Asia/Urumqi']

可以看到上海时区和乌鲁木齐时区

  • pytz.timezone(‘时区名’)

可以获取一个tzinfo的对象,可以当作datetime的参数使用,生成对应时区的时间

1
2
3
4
5
>>> utc = pytz.timezone('UTC')
>>> datetime.datetime.now(tz=utc)
datetime.datetime(2021, 1, 26, 2, 46, 54, 453111, tzinfo=<UTC>)
>>> datetime.datetime(2021, 1, 26, 10, 0 ,0 ,tzinfo=utc)
datetime.datetime(2021, 1, 26, 10, 0, tzinfo=<UTC>)
  • from pytz import all_timezones,common_timezones

可以查看有那些时区

带时区时间的生成

生成带时区的时间一般有两种方法,

一种是使用datetime的构造函数,传入pytz 的 tzinfo对象生成

1
2
3
>>> sh = pytz.timezone('Asia/Shanghai')
>>> datetime.datetime(2021, 1, 26, 10, 0 ,0 ,tzinfo=sh)
datetime.datetime(2021, 1, 26, 10, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)

这里就生成了一个带上海时区的datetime对象。但是这中间有一个问题,我们发现生成的时间对象的时区是LMT,不是标准的CST,和UTC的时差不是8个小时整。这样在时区切换时会产生6分钟的误差,造成一些不好的影响。

另一种是使用pytz的tzinfo这个时区对象的localize方法

localize是给无时区的时间加上标准时区的方法

1
2
3
4
5
>>> d = datetime.datetime(2021, 1, 26, 10, 0 ,0)
>>> d
datetime.datetime(2021, 1, 26, 10, 0)
>>> sh.localize(d)
datetime.datetime(2021, 1, 26, 10, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)

现在可以看到生成的是标准的CST了。

综合这两种方法,生成带时区的时间时,最好使用timezone.localize()来生成。不要在时间对象的构造函数中传入tzinfo的方式来实现。

给有时区的时间转换时区

给有时区的时间转换时区,使用datetime对象的astimezone方法

1
2
3
4
>>> d
datetime.datetime(2021, 1, 26, 10, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
>>> d.astimezone(utc)
datetime.datetime(2021, 1, 26, 2, 0, tzinfo=<UTC>)