首页 > 编程语言 >python datetime 时区陷阱

python datetime 时区陷阱

时间:2022-12-09 14:23:46浏览次数:45  
标签:12 tz 2022 python datetime 陷阱 print now

datetime 时区陷阱

目录


问题

  • 在用 python 开发的时候,我们经常用 datetime 模块的 datetime 函数来构造时;
  • 例如:我们需要构造一个 '2022-12-09 12:00:00' 的时间对象,则可以这样:t = datetime.datetime(2022, 12, 9, 12, 0, 0)
  • datetime 构造的时间真的没有问题,真的对吗?

答案

直接告诉你答案:

  • 答案是:datetime 函数构造的时间不一定对,以北京时间为例,datetime 要快 6 分钟
  • 解决办法:使用 pytz.timezone 的 localize 方法进行处理即可

错误示范:

from pytz import timezone
from datetime import datetime

tz = timezone('Asia/Shanghai')
t = datetime.datetime(2022, 12, 9, 12, 0, 0, tzinfo=tz)
print(t)

正确示范:

from pytz import timezone
from datetime import datetime

tz = timezone('Asia/Shanghai')
t = tz.localize(datetime.datetime(2022, 12, 9, 12, 0, 0))
print(t)

分析经过(可忽略)


情况一:不设置时区

依赖于 python 配置里的默认时区,程序里不设置时区

from datetime import datetime

now = datetime.now()
manual_now = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second, now.microsecond)
print(now)
print(manual_now)
diff = manual_now.timestamp() - now.timestamp()
print(f'datetime构造时间与默认时间差:{diff} 秒')

输出:

2022-12-09 11:34:24.450903
2022-12-09 11:34:24.450903
datetime构造时间与默认时间差:0.0 秒

注:可见在不设置时区时,datetime 函数构造的时间和默认时间没有区别,是对的


情况二:设置时区(以北京时间为例)

设置时区需要用到 pytz 模块,未安装的可以先安装一下

pip install pytz

1)使用 datetime 函数的 tzinfo 参数

from pytz import timezone
from datetime import datetime


tz = timezone('Asia/Shanghai')
now = datetime.now(tz)
print(now)
manual_now = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second, now.microsecond, tzinfo=tz)
print(manual_now)
diff = manual_now.timestamp() - now.timestamp()
print(f'datetime构造时间与北京时间差:{diff} 秒')

输出

2022-12-09 11:36:20.493618+08:00
2022-12-09 11:36:20.493618+08:06
datetime构造时间与北京时间差:-360.0 秒

注1:打印两个时间的时候,表面上是一样的,但要注意后面的+08:06。通过比例两者的时间戳,直接使用 tzinfo 参数构造出来的时间,比实际时间快 360 秒(即 6 分钟)
注2:其本质是因为时区的设置只有 'Asia/Shanghai'(即上海时间),而没有 'Asia/Beijing'(即北京时间),上海时间实际上是比北京时间快 6 分钟的
注3:如果你再换成 'Asia/Hong_Kong'(即香港时间),会发现香港时间比北京时间慢 23 分钟


2)时区本地化

严格意义上,设置时区后的结果并没有错,但生活上我们都是使用的北京时间(大部分系统也是使用的北京时间),所有我们还是需要对时间进行“本地化”

使用 tzinfo.localize 方法对 datetime 进行本地化处理:

from pytz import timezone
from datetime import datetime

tz = timezone('Asia/Shanghai')
now = datetime.now(tz)
print(now)

true_now = tz.localize(datetime(now.year, now.month, now.day, now.hour, now.minute, now.second, now.microsecond))
print(true_now)
diff = true_now.timestamp() - now.timestamp()
print(f'使用tz.localize处理datetime与北京时间差:{diff} 秒')

输出:

2022-12-09 11:45:10.528836+08:00
2022-12-09 11:45:10.528836+08:00
使用tz.localize处理datetime与北京时间差:0.0 秒

注:经过 localize 函数处理后的时间为真正的北京时间

回归问题

回归一开始的问题:如果我们需要构造一个 '2022-12-09 12:00:00' 的时间对象,正确的做法为:

from pytz import timezone
from datetime import datetime

tz = timezone('Asia/Shanghai')
bj_time = tz.localize(datetime(2022, 12, 9, 12, 0, 0))
print(bj_time)

标签:12,tz,2022,python,datetime,陷阱,print,now
From: https://www.cnblogs.com/tujia/p/16968544.html

相关文章

  • 利用Python实现批量ping的小工具
    一、原理:主要涉及的系统命令:ping-n1-w1IP地址  -n为ping的次数,在linux下为-c;-w为等待超时时间;利用Python多线程缩短时间,提升运行效率。 二、其它说明DEV_N......
  • DateTimeFormatter日期格式化
    DateTimeFormatter日期格式化​​DateTimeFormatter​​​​工具类​​DateTimeFormatter使用旧的Date对象时,我们用SimpleDateFormat进行格式化显示。使用新的LocalDateTime......
  • 【类库合集】Python常用类库合集
    1)SSH类库——Paramiko简介:SSH是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。SSH客户端适用于多种平台,几乎所有UNIX平台—包括HP-UX、Linux、AIX、Solaris、D......
  • [附源码]Python计算机毕业设计Django疫情物资管理系统
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • Python数据分析实践项目 教育平台的线上课程智能推荐
        嗨喽!大家好,我是“流水不争先,争的是滔滔不绝”的翀,欢迎大家来交流学习,一起入坑数据分析,希望我们一起好好学习,天天向上,目前在社会毒打中~~文章目录​​摘要​​......
  • java-net-php-python-jsp汽车租赁管理系统计算机毕业设计程序
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • Python对json的操作总结
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • [python]Anaconda介绍、安装及使用
    一、什么是Anaconda?简介Anaconda(​​官方网站​​)就是可以便捷获取包且对包能够进行管理,同时对环境可以统一管理的发行版本。Anaconda包含了conda、Python在内的超过180个科......
  • python基础-模块和包
    1.什么是python的包  包就是一个文件夹,里面放着一个个py文件或子包;  在包中可以被调用的一个个py文件,我们叫做模块;    如上,test就是一个包、two.py就是test下......
  • PYTHON 异常处理
    1.1异常处理有时可将程序错误(Error)称作程序异常(Exception)。出现错误程序终止。出现异常程序终止,也可以捕捉异常和撰写异常处理程序,处理完程序可以继续运行。1.1......