时间是一个绝对值,不论身处哪里都是一样的,比如Unix时间戳,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
为了方便世界不同地区计时的需要,引入了时区的概念,也就是同一个时刻,在不同时区显示的时间不同,比如东八区显示的时间就比格林威治时间早8小时。
使用 datetime 模块中的 timezone 函数生成:
>>> 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 开始,标准库中引入)
import zoneinfo
tz = zoneinfo.ZoneInfo("Asia/Shanghai")
zoneinfo.available_timezones() # 获取支持的时区 {'Pacific/Pohnpei', ... , 'Africa/Mbabane'}
第三方库:dateutil
安装:python -m pip install python-dateutil
>>> 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
>>> pytz.timezone('Asia/Shanghai')
<DstTzInfo 'Asia/Shanghai' LMT+:06: STD>
可以看到,生成的时区为LMT(Local Mean Time),这是一个历史上的时间标准,可以看到它比正常时区差了6分钟。
>>> 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
import tzlocal
tzlocal.get_localzone_name()
tzlocal.get_localzone()
更改 Python 进程内的时区,不影响操作系统
# 修改
os.environ['TZ']='US/Eastern'
time.tzset()
# 恢复
del(os.environ['TZ']) #如果提前保存了TZ的值,在这里恢复也行
time.tzset()
# 注:现在的一些系统已经没有了TZ环境变量,只是有些程序依然使用它
时间对象有两种,一种带时区,一种不带时区。 带时区的被称为感知型(aware),不带时区的被称为简单型(naive)
系统time模块和datetime模块分别有两个函数用来获取当前的localtime和utctime,这两个都是根据当前时区生成的时间对象,不包含时区信息(生成naive型时间)。
>>> 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)
>>> 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时间就可以了。
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)
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±[hh]:[mm] 或 UTC±[hh]:[mm]。 示例 : GMT+08:00 表示东八区时间,比格林尼治时间快 8 小时 。 UTC-05:00 表示西五区时间,比协调世界时慢 5 小时。
是指基于 Olson 时区数据库 (也称为 TZ database 或 Zoneinfo database )定义的一套全球时区规则和命名系统。这一数据库由 Arthur David Olson 创建,并由 Paul Eggert 等人维护,广泛应用于计算机程序和操作系统中。 Olson 时区的核心特点是使用“区域/位置 ”的命名方式,例如:
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)。 缩写有时会有冲突,造成歧义
格式 :±[hh]:[mm],表示相对于 UTC 的偏移量。 示例 : 2025-03-18T12:00:00+08:00 表示北京时间(UTC+8)。 2025-03-18T04:00:00Z 表示 UTC 时间(Z 表示零时区)
格式 :仅用数字表示相对于 UTC 的小时和分钟偏移。 示例 : +0800 表示东八区时间。 -0500 表示西五区时间