时间和时区时间是一个绝对值,不论身处哪里都是一样的,比如Unix时间戳,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
为了方便世界不同地区计时的需要,引入了时区的概念,也就是同一个时刻,在不同时区显示的时间不同,比如东八区显示的时间就比格林威治时间早8小时。
时区对象生成时区对象使用 datetime 模块中的 timezone 函数生成:
代码语言:javascript复制>>> from datetime import timezone
>>>from datetime import timedelta
>>>timezone.utc # utc时区
datetime.timezone.utc
>>>tz = timezone(timedelta(hours=),'Asia/Shanghai') # 中国时区 ,第二个参数是自定义名字,其实可以任意输入
>>>tz
datetime.timezone(datetime.timedelta(seconds=28800), 'Asia/Shanghai')
>>>tz.tzname(None)
'Asia/Shanghai'
>>>tz.utcoffset(None)
datetime.timedelta(seconds=28800)
使用zoneinfo 对象(推荐):(Python 3.9 开始,标准库中引入)
代码语言:javascript复制import zoneinfo
tz = zoneinfo.ZoneInfo("Asia/Shanghai")
zoneinfo.available_timezones() # 获取支持的时区 {'Pacific/Pohnpei', ... , 'Africa/Mbabane'}
第三方库:dateutil
安装:python -m pip install python-dateutil
代码语言:javascript复制>>> from dateutil import tz
>>> tz.gettz() # tzfile('/etc/localtime')
>>> tz.gettz('CST') # tzlocal()
>>> tz.gettz('Asia/Shanghai') # tzfile('/usr/share/zoneinfo/Asia/Shanghai')
>>> tz.gettz('UTC+8') # tzstr('UTC+8')
这个库支持各种格式的时区字符串(见文末补充知识),还是挺方便的。
时区只是此库中一个功能,还有时间字符串转换成时间,时间段定义,时间转换功能。
第三方时区库:pytz(不推荐)
pip install pytz
代码语言:javascript复制>>> pytz.timezone('Asia/Shanghai')
可以看到,生成的时区为LMT(Local Mean Time),这是一个历史上的时间标准,可以看到它比正常时区差了6分钟。
获取当前时区代码语言:javascript复制>>> import time
>>> time.timezone # -28800 减去这些秒等于UTC
>>> time.tzname # ('CST', 'CST')
>>> time.localtime().tm_gmtoff # 28800 比GMT快这些秒
>>> time.localtime().tm_zone # 'CST'
生成当前时间再获取
local_timezone = datetime.now().astimezone().tzinfo
使用专用的库
pip install tzlocal
代码语言:javascript复制import tzlocal
tzlocal.get_localzone_name()
tzlocal.get_localzone()
更改时区更改 Python 进程内的时区,不影响操作系统
代码语言:javascript复制# 修改
os.environ['TZ']='US/Eastern'
time.tzset()
# 恢复
del(os.environ['TZ']) #如果提前保存了TZ的值,在这里恢复也行
time.tzset()
# 注:现在的一些系统已经没有了TZ环境变量,只是有些程序依然使用它
时间对象时间对象有两种,一种带时区,一种不带时区。
带时区的被称为感知型(aware),不带时区的被称为简单型(naive)
生成当前时区时间的naive时间系统time模块和datetime模块分别有两个函数用来获取当前的localtime和utctime,这两个都是根据当前时区生成的时间对象,不包含时区信息(生成naive型时间)。
代码语言:javascript复制>>> import time
>>> time.localtime()
time.struct_time(tm_year=2020, tm_mon=3, tm_mday=9, tm_hour=18, tm_min=21, tm_sec=18, tm_wday=0, tm_yday=69, tm_isdst=0)
>>> time.gmtime()
time.struct_time(tm_year=2020, tm_mon=3, tm_mday=9, tm_hour=10, tm_min=21, tm_sec=24, tm_wday=0, tm_yday=69, tm_isdst=0)
代码语言:javascript复制>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2020, 3, 9, 18, 21, 2, 913020)
>>> datetime.datetime.utcnow()
datetime.datetime(2020, 3, 9, 10, 21, 8, 697175)
注:如果程序不需要支持时区,只需要配置好系统的时间和时区,代码中直接使用naive时间就可以了。
生成某个时区的时间代码语言:javascript复制from datetime import datetime
from zoneinfo import ZoneInfo
# 生成特定时区的时间
datetime.now(ZoneInfo('Asia/Shanghai')) # 先生成时区,再生成时间,时区对象可以用上文介绍的其他库生成
# 生成当前时区的时间
datetime.now().astimezone() # 实际上是生成了navie时间,又被转换了下
时间的时区转换时区替换dt.replace(tzinfo=tz)
时区转换dt.astimezone(tz=tz)
代码语言:javascript复制from datetime import datetime
from zoneinfo import ZoneInfo
# 给没有时区的时间对象添加时区
datetime.now().replace(tzinfo=ZoneInfo('Asia/Shanghai'))
# 从一个时区转换到另一个时区
datetime.now().astimezone(tz=ZoneInfo('Europe/Paris')) # 时间从东八区转换为东一区
注:如果原始时间没有时区信息,astimezone()会把他当做当前系统时区的时间;如果tz参数为None,astimezone()会将其转换为当前时区。
补充知识:时区的各种表示GMT 或 UTC 加偏移量格式 :GMT±[hh]:[mm] 或 UTC±[hh]:[mm]。
示例 :
GMT+08:00 表示东八区时间,比格林尼治时间快 8 小时 。
UTC-05:00 表示西五区时间,比协调世界时慢 5 小时。
Olson 时区(Olson timezones)是指基于 Olson 时区数据库 (也称为 TZ database 或 Zoneinfo database )定义的一套全球时区规则和命名系统。这一数据库由 Arthur David Olson 创建,并由 Paul Eggert 等人维护,广泛应用于计算机程序和操作系统中。
Olson 时区的核心特点是使用“区域/位置 ”的命名方式,例如:
代码语言:javascript复制America/New_York
Asia/Shanghai
Europe/London
这种命名方式通过地理区域和具体城市来唯一标识一个时区,避免了传统时区命名(如 GMT+8)可能带来的歧义
缩写表示法常见缩写 :
CST:中国标准时间(China Standard Time,UTC+8)。
EST:美国东部标准时间(Eastern Standard Time,UTC-5)。
PST:太平洋标准时间(Pacific Standard Time,UTC-8)。
缩写有时会有冲突,造成歧义
ISO 8601 标准表示法格式 :±[hh]:[mm],表示相对于 UTC 的偏移量。
示例 :
2025-03-18T12:00:00+08:00 表示北京时间(UTC+8)。
2025-03-18T04:00:00Z 表示 UTC 时间(Z 表示零时区)
数字偏移量表示法格式 :仅用数字表示相对于 UTC 的小时和分钟偏移。
示例 :
+0800 表示东八区时间。
-0500 表示西五区时间