最近开发过程中遇到这样一个问题:
在使用 datetime 模块获取当前时间之后, 与程序中某些时间操作会报错:
TypeError: can't subtract offset-naive and offset-aware datetimes
这个我就有点纳闷了, 怎么会报这个错误呢? 然后我开始搜资料, 原来在有两种时间类型:naive 和 aware
-
naive
- 没有表明时区的时间. 如: datetime.datetime.now()
-
datetime.datetime(2019, 7, 8, 14, 13, 52, 534690)
-
aware
- 有时区的时间. 如:datetime.datetime.now(pytz.utc)
-
datetime.datetime(2019, 7, 8, 6, 22, 16, 245504, tzinfo=<UTC>)
可以发现 aware 类型时间在打印对象信息时多了一个 tzinfo, 没错, 这个就是用来标识时区的. 而因为我们获取当前的时候没有传入时区, 为 naive 类型, 所以与有些 aware 时间操作会发生异常, 其实解决方法也很简单, 将 naive 转化为 aware 类型就好了, 怎样转化呢? 我找到了这几种方式:
方式一
datetime.datetime.now().replace(tzinfo=pytz.utc)
方式二
datetime.datetime.now(pytz.utc)
方式三
pytz.utc.localize(datetime.datetime.now())
而第二种生成方式是在创建时间的时候指定时间, 其他两种可以用来转化 / 修改时区. 写了这么多, 你们肯定在疑惑一个东西:pytz
这是一个时区模块, 用来在 python 中进行一个时区的相关操作. 其提供的对象方法为
__all__ = [
'timezone', 'utc', 'country_timezones', 'country_names',
'AmbiguousTimeError', 'InvalidTimeError',
'NonExistentTimeError', 'UnknownTimeZoneError',
'all_timezones', 'all_timezones_set',
'common_timezones', 'common_timezones_set',
]
接下来我们一个个介绍:
-
timezone: 传入一个时区, 如:Asia/Shanghai, 返回一个时区对象
-
pytz.timezone('Asia/Shanghai') >>> <DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
-
-
utc: 返回一个 utc 时区对象
-
pytz.utc >>> <UTC>
-
-
country_timezones: 传入一个国家英文缩写, 返回拥有的时区, 如: 中国 (‘CN’), 不传则返回由 247 个国家缩写为 key, 时区为值的 dict
-
pytz.country_timezones('CN') >>> [u'Asia/Shanghai', u'Asia/Urumqi']
-
-
country_names: 拿一个国家英文缩写, 返回国家完整英文名称
-
pytz.country_names['CN'] >>> u'China'
-
-
all_timezones: 所有时区的列表 (591 个)
-
pytz.all_timezones >>> ['Asia/Shanghai', 'Asia/Urumqi', ...] # 有 591 个, 所以还是列一下咱们国家的时区
-
-
all_timezones_set: 所有时区的集合
-
pytz.all_timezones_set >>> {'Asia/Shanghai', 'Asia/Urumqi', ...}
-
-
common_timezones: 常用的时区列表 (439 个)
-
pytz.common_timezones >>> ['Asia/Shanghai', 'Asia/Urumqi', ...] # 有 439 个
-
-
common_timezones_set: 常用的时区集合
-
pytz.common_timezones >>> {'Asia/Shanghai', 'Asia/Urumqi', ...}
-
- AmbiguousTimeError: 模糊时间错误
- InvalidTimeError: 无效时间错误
- NonExistentTimeError: 不存在的时间错误
- UnknownTimeZoneError: 未知的时区错误