import pytz
from datetime import datetime
print(datetime.now().replace(tzinfo=pytz.timezone('Asia/Shanghai')))
输出
2023-06-17 13:03:10.299279+08:06
pytz 只支持 上海时间,不支持 北京时间
但是上海时间有一个很恶心的地方,会比北京时间多 6 分钟
同样的问题,在我使用一些 linux 发行版(带GUI)的时候,也遇到过这样的问题,只能设置上海时间,没有北京时间可以选
why?是有什么国际法规定吗?
from zoneinfo import ZoneInfo
from datetime import datetime
import pytz
print(datetime.now().replace(tzinfo=pytz.timezone('Asia/Shanghai')))
tz = ZoneInfo('Asia/Shanghai')
print(datetime.now(tz))
不过 python3.9 内置的 zoneinfo,但是不会出现多 6 分钟的问题
输出如下:
2023-06-17 13:36:54.594807+08:06
2023-06-17 13:36:54.605920+08:00
这其实是两个问题。
首先你这里差 6 分钟是因为 pytz 内部默认采用的是一种叫 Local Mean Time(LMT,当地平均时间)的时区。这种时区是纯粹按照地理经度来划分的,大概每个经度差 4 分钟左右……
当我们提到 “Asia/Shanghai” 这个时区名称的时候,其实是有三种时区的(到目前为止,以后说不定还会增加):
你直接这么 print 出来,是按 LMT 的方式格式化输出的。所以你得到了一个差了 6 分钟的结果。
而我们通常所说 “Asia/Shanghai”,在绝大部分情况下指的是标准时间而非平均时间。
在 pytz 里你要想以标准时间输出的话,需要手动 normalize
或 localize
。具体写法就不给了,你自己就能查到。
至于 pytz 默认为啥要采用 LMT 存储,这个我们就不得而知了。但项目已经开源这么久了,这种上古级别的 feature 想要改是很难的了。
其次是关于所谓“北京时间”的问题。
如果你仅仅是想要一个 UTC+8,前面我已经解释了原因和做法。
而如果你问的是为什么罕见有 “Asia/Beijing” 或 “Asia/Peking” 这种时区名称。上面 @非马梦衢 已经解释了部分原因。其中提到一点:
参考于当地时区内人口最多的地方,如果北京和上海人口相当,那选择最为著名的地方。
那么到底是谁“参考”、又是谁“选择”的呢?
其实就是计算机中时区数据库,通常来自于 Time Zone Database(简称 tzdb)这一开源项目。虽然它现在名义上已被 ICANN 接管,是一项“半国际标准”。但实质上从开始到现在,它始终都是 Paul Eggert (保罗·埃格特)一个人维护的,所以几乎可以看作是一个私人项目。这个人是一个很“固执”的老头,他自有一套判断标准来决定讲哪些地区或城市纳入到该数据库中。
实际上世界上很多其他国家和地区的人,也都吐槽过自己所在国家或地区的代表性城市也没有出现在 tzdb 里,对吐槽感兴趣的话可以看 https://www.36kr.com/p/1473253583024389 这篇报道。
也有一些软件出于种种原因,没有完全使用 tzdb,而是自己另行维护了一套时区数据库。它们就有可能是支持 Asia/Beijing 或 Asia/Peking 这种写法的。比较典型的比如 Windows。
所以回到你的问题里,“为什么很多东西不支持北京时间”,其实不是不支持“北京标准时间”、而是仅仅不支持 “Asia/Beijing” 这个时区名称而已。为啥不支持 —— 因为它们直接用的 tzdb,里面确实就是没有 Asia/Beijing。
维基百科是这么讲的:
IANA time zone database
The territory of the People's Republic of China is covered in the IANA time zone database by the following zones. "Asia/Shanghai" is used instead of "Asia/Beijing" because Shanghai is the most populous location in the zone.
维基百科也讲述了上海时间的由来历史, 仅供参考, Time_in_China#History
还有一个参考,是在某个github上看到一段文字,摘录部分,具体可参考链接: Timezone list does not contain Beijing
意思是说在现有的国际上,时钟数据库选择了以上海时间作为中国的标准时间来用的,是参考于当地时区内人口最多的地方,如果北京和上海人口相当,那选择最为著名的地方。
Here are the general guidelines used for choosing timezone names, in decreasing order of importance:
Use the most populous among locations in a region, e.g., prefer Asia/Shanghai to Asia/Beijing. Among locations with similar populations, pick the best-known location, e.g., prefer Europe/Rome to Europe/Milan.
这份维基百科的time zone数据库罗列了世界所有的时区: List_of_tz_database_time_zones
总之,在国际上来看,上海比北京知名度更高,所以他们的设计就是以上海为准。
本文向大家介绍为什么Java不支持<<相关面试题,主要包含被问及为什么Java不支持<<时的应答技巧和注意事项,需要的朋友参考一下 Java添加了运算符“ >>>”来执行逻辑右移,但是由于 逻辑和算术左移运算是相同的 ,因此Java中没有“ <<<”运算符。 来自Java的Shifts …
我注意到一件奇怪的事情,显然Firefox说它支持HTTPS上的Brotli,但不支持HTTP?Brotli与gzip类似,但效率更高,为什么它会将其限制为HTTPS?在HTTPS选项卡上,我看到: 他被派去了。但在另一个网站上,我没有看到。为什么它不能做Brotli压缩HTTP?
问题内容: 是当今的浏览器是否经过深思熟虑的设计决策或存在问题,这些问题将在以后的版本中得到解决? 问题答案: JavaScript不支持多线程,因为浏览器中的JavaScript解释器是单线程(AFAIK)。甚至谷歌浏览器也不允许单个网页的JavaScript同时运行,因为这会在现有网页中引起大量的并发问题。Chrome所做的全部工作就是将多个组件(不同的选项卡,插件等)分离到单独的进程中,但是
在EpolDatagramChannelConfig类中,有4个方法如下所示: 这些是: SETLOOPBACKMODE已禁用 是否由于Netty中的问题而禁用了支持,或者EPoll根本不支持UDP多播? 谢谢
问题内容: Java为什么不包括对无符号整数的支持? 在我看来,这是一个奇怪的遗漏,因为它们允许人们编写不太可能在意外大的输入上产生溢出的代码。 此外,使用无符号整数可以是一种自我证明的形式,因为它们指示无符号int打算保留的值永远不会为负。 最后,在某些情况下,无符号整数对于某些操作(例如除法)可能更有效。 包括这些的不利之处是什么? 问题答案: 在两行之间阅读时,我认为逻辑是这样的: 通常,J
问题内容: 我已经多次看到,负填充的前景可能会帮助某些页面元素的CSS开发变得越来越好。但是,W3C CSS中没有负填充的规定。这背后的原因是什么?该属性是否有阻碍其使用的阻碍?感谢您的回答。 更新 例如,我看到的情况是,如果您使用的字体的垂直间距为20px,并且希望在字体底部应用虚线边框,例如出现超链接时。在这种情况下,您会发现样式太简陋,因为虚线边框会出现在指定单词下方20px。如果您使用负边