五月综合激情婷婷六月,日韩欧美国产一区不卡,他扒开我内裤强吻我下面视频 ,无套内射无矿码免费看黄,天天躁,日日躁,狠狠躁

新聞動態(tài)

淺談Python3中datetime不同時(shí)區(qū)轉(zhuǎn)換介紹與踩坑

發(fā)布日期:2022-02-20 08:33 | 文章來源:腳本之家

最近的項(xiàng)目需要根據(jù)用戶所屬時(shí)區(qū)制定一些特定策略,學(xué)習(xí)、應(yīng)用了若干python3的時(shí)區(qū)轉(zhuǎn)換相關(guān)知識,這里整理一部分記錄下來。

下面涉及的幾個(gè)概念及知識點(diǎn):

GMT時(shí)間:Greenwich Mean Time, 格林尼治平均時(shí)間

UTC時(shí)間:Universal Time Coordinated 世界協(xié)調(diào)時(shí),可以認(rèn)為是更精準(zhǔn)的GMT時(shí)間,但兩者誤差極小,在1s以內(nèi),一般可視為等同

LMT:Local Mean Time, 當(dāng)?shù)貥?biāo)準(zhǔn)時(shí)間

Python中的北京時(shí)間:Python的標(biāo)準(zhǔn)timezone中信息中并沒有Asia/Beijing,原因要追溯到國民政府期間上報(bào)給國際標(biāo)準(zhǔn)的五個(gè)時(shí)區(qū)城市沒有北京,因此一般使用Asia/Shanghai獲取東8區(qū)時(shí)間

Python使用到的時(shí)間相關(guān)函數(shù)及概念:

包含時(shí)區(qū)信息的datetime稱為: offset-aware datetime,反之稱為offset-naive datetime

pytz.timezone(x): pytz package中預(yù)定義的時(shí)區(qū)相關(guān)對象, pytz可通過 python3 -m pip install pytz 安裝

datetime(...) : 直接指定year/month/day/hour/second生成naive datetime

datetime(...tzinfo=tz) : 直接指定year/month/day/hour/second+時(shí)區(qū)信息生成offset-aware datetime

datetime.now(): 生成當(dāng)前默認(rèn)時(shí)區(qū)的 naive datetime

datetime.now(tzinfo=tz): 生成指定時(shí)區(qū)的offset-aware datetime

datetime.strptime(string, format) : 生成當(dāng)前默認(rèn)時(shí)區(qū)的string、format表示的 naive datetime

datetime.replace(tzinfo=tz): 直接替換datetime 時(shí)區(qū)信息為tz時(shí)區(qū)offset-aware datetime--不針對時(shí)區(qū)進(jìn)行任何轉(zhuǎn)換

datetime.astimezone(tz): 將時(shí)間轉(zhuǎn)換為新的tz時(shí)區(qū)的offset-aware datetime

下述代碼示例中,由于云主機(jī)位于日本,所以默認(rèn)時(shí)區(qū)為東9區(qū)(Asia/Tokyo)

Python中獲取當(dāng)前時(shí)刻時(shí)間:

In [1]: import pytz
In [2]: from datetime import datetime, timedelta
In [3]: datetime.now() # 默認(rèn)時(shí)區(qū)當(dāng)前時(shí)間
Out[3]: datetime.datetime(2021, 8, 1, 18, 36, 8, 352873)
In [4]: datetime.now(pytz.timezone('Asia/Tokyo')) # 指定Tokyo時(shí)區(qū)當(dāng)前時(shí)間
Out[4]: datetime.datetime(2021, 8, 1, 18, 36, 25, 421048, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)

可以看到,datetime.now()未指定時(shí)區(qū)時(shí),獲取到的對象是offset-navie datetime,而指定時(shí)區(qū)后則是offset-aware datetime,naive和aware的datetime是不可以執(zhí)行比較、相減相關(guān)操作的,只有同類型的datetime才能求時(shí)間差值、比較大小,如下:

In [5]: datetime.now() - datetime.now(pytz.timezone('Asia/Tokyo'))
---------------------------------------------------------------------------
TypeError  Traceback (most recent call last)
<ipython-input-5-8b6c111dc5de> in <module>
----> 1 datetime.now() - datetime.now(pytz.timezone('Asia/Tokyo'))
TypeError: can't subtract offset-naive and offset-aware datetimes
In [6]: datetime.now() - datetime.now() # 只有同樣的offset-naive datetime才能求差值
Out[6]: datetime.timedelta(days=-1, seconds=86399, microseconds=999991)
In [8]: datetime.now(pytz.timezone('Asia/Tokyo')) - datetime.now(pytz.timezone('Asia/Tokyo')) # 同樣的offset-aware datetime才能求差值
Out[8]: datetime.timedelta(days=-1, seconds=86399, microseconds=999976)

這里碰到了第一個(gè)坑,比如我們想獲得北京時(shí)間2021年1月1日0點(diǎn)的datetime,然后將其轉(zhuǎn)換為東京時(shí)間,直覺上我們很可能這么寫:

In [19]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Asia/Shanghai')) # 這里獲取北京時(shí)間20210101 0點(diǎn)的datetime
Out[19]: datetime.datetime(2021, 1, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>) # 注意獲取的是LMT時(shí)間
In [21]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Asia/Shanghai')).astimezone(pytz.timezone('Asia/Tokyo')) # 將北京時(shí)轉(zhuǎn)換為東京時(shí)間
Out[21]: datetime.datetime(2021, 1, 1, 0, 54, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>) # 獲取的是日本標(biāo)準(zhǔn)時(shí)間JST+9
In [22]: datetime.now(pytz.timezone('Asia/Shanghai')) # 示例獲取當(dāng)前時(shí)刻北京時(shí)間
Out[22]: datetime.datetime(2021, 8, 1, 18, 11, 6, 706727, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) # 獲取的是中國標(biāo)準(zhǔn)時(shí)間(CST+8)

仔細(xì)一看,北京時(shí)間的0點(diǎn)轉(zhuǎn)化為東京時(shí)間卻是0:54,相差是54分鐘,而不是1個(gè)小時(shí),這就奇怪了,仔細(xì)一看tzinfo中的信息是LMT+8:06:00 STD,表示這是LMT時(shí)間,相比UTC快8小時(shí)6分鐘,而不是東8區(qū)標(biāo)準(zhǔn)時(shí)間,而通過astimezone方法轉(zhuǎn)換后得到的就是日本標(biāo)準(zhǔn)時(shí)間(東9區(qū)),所以兩者之前的差值并不是1小時(shí)整。

第一個(gè)坑究其原因,通過datetime(..tzinfo=..)指定時(shí)區(qū)獲取的是LMT,而datetime.now(tz)、datetime.astimezone(tz) 獲取的卻是UTC(GMT)標(biāo)準(zhǔn)時(shí)間,LMT和GMT標(biāo)準(zhǔn)時(shí)間可能會有甚至十分鐘級的差值,這已經(jīng)足夠影響到程序的正常邏輯了。

所以如果要保證獲取標(biāo)準(zhǔn)時(shí)區(qū)的時(shí)間,建議避免使用Asia/Shanghai、Asia/Tokyo這類大洲/城市 字符串表示時(shí)間,而使用GMT、UTC這些無歧義的標(biāo)準(zhǔn)時(shí)區(qū),如下:

In [45]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT-9'))
Out[45]: datetime.datetime(2021, 1, 1, 0, 0, tzinfo=<StaticTzInfo 'Etc/GMT-9'>) # 東9區(qū)應(yīng)使用GMT-9

這里第二個(gè)坑出現(xiàn)了,由于歷史原因,Python中timezone的表示中,時(shí)區(qū)偏移以西為正,以東為負(fù),和我們熟悉的ISO標(biāo)準(zhǔn)剛好相反,所以東9區(qū)應(yīng)該表示為Etc/GMT-9, 而Etc/GMT+9表示的其實(shí)是西9區(qū),如下可以驗(yàn)證GMT-9與JST相差0, GMT+9與JST相差18小時(shí)(64800s):

In [50]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT-9')) - datetime(2021, 1, 1).astimezone(pytz.timezone('Asia/Tokyo'))
Out[50]: datetime.timedelta(0)
In [51]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT+9')) - datetime(2021, 1, 1).astimezone(pytz.timezone('Asia/Tokyo'))
Out[51]: datetime.timedelta(seconds=64800)

最后,獲取指定時(shí)區(qū)2021年1月1日datetime的方式,以北京時(shí)間為例:

In [56]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT-8'))
Out[56]: datetime.datetime(2021, 1, 1, 0, 0, tzinfo=<StaticTzInfo 'Etc/GMT-8'>)
In [58]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT-8')).astimezone(pytz.timezone('Asia/Shanghai'))
Out[58]: datetime.datetime(2021, 1, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) # 可見GMT-8和東八區(qū)標(biāo)準(zhǔn)時(shí)間(CST+8)一致

進(jìn)一步如果要獲取指定時(shí)區(qū)零點(diǎn)的時(shí)間戳就很簡單了:

In [44]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT0')).timestamp() # 獲取格林尼治時(shí)區(qū)2021年1月1日0點(diǎn)時(shí)間戳
Out[44]: 1609459200.0

另外兩種獲取指定時(shí)區(qū)時(shí)刻的方法,此三種方式彼此等價(jià):

In [51]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT0')) == datetime(2021, 1, 1).replace(tzinfo=pytz.timezone('Etc/GMT0'))
Out[51]: True
In [53]: datetime(2021, 1, 1, tzinfo=pytz.timezone('Etc/GMT0')) == datetime.strptime('20210101', '%Y%m%d').replace(tzinfo=pytz.timezone('Etc/GMT0'))

到此這篇關(guān)于淺談Python3中datetime不同時(shí)區(qū)轉(zhuǎn)換介紹與踩坑的文章就介紹到這了,更多相關(guān)Python3 datetime不同時(shí)區(qū)轉(zhuǎn)換 內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

香港快速服務(wù)器

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開通

自選配置、實(shí)時(shí)開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部