使用 Python datetime 處理日期和時(shí)間

      網(wǎng)友投稿 1693 2025-03-31

      目錄


      用日期和時(shí)間編程

      計(jì)算機(jī)如何計(jì)算時(shí)間

      如何報(bào)告標(biāo)準(zhǔn)日期

      時(shí)間應(yīng)該如何存儲(chǔ)在你的程序中

      使用 Python 日期時(shí)間模塊

      創(chuàng)建 Python 日期時(shí)間實(shí)例

      使用字符串創(chuàng)建 Python 日期時(shí)間實(shí)例

      開(kāi)始你的 PyCon 倒計(jì)時(shí)

      使用時(shí)區(qū)

      使用 dateutil 將時(shí)區(qū)添加到 Python 日期時(shí)間

      比較 Naive 和 Aware Python datetime 實(shí)例

      改進(jìn)你的 PyCon 倒計(jì)時(shí)

      使用 Python 日期時(shí)間進(jìn)行算術(shù)運(yùn)算

      完成你的 PyCon 倒計(jì)時(shí)

      在 PyCon 倒計(jì)時(shí)中使用relativedelta

      在 PyCon 倒計(jì)時(shí)中顯示 PyCon 日期

      完成你的 PyCon 倒計(jì)時(shí)

      Python datetime 和 dateutil 的替代品

      進(jìn)一步閱讀

      結(jié)論

      處理日期和時(shí)間是編程中最大的挑戰(zhàn)之一。在處理時(shí)區(qū)、夏令時(shí)和不同的書(shū)面日期格式之間,很難跟蹤您所引用的日期和時(shí)間。幸運(yùn)的是,內(nèi)置的 Pythondatetime模塊可以幫助您管理日期和時(shí)間的復(fù)雜性質(zhì)。

      在本教程中,您將學(xué)習(xí):

      為什么用日期和時(shí)間編程是一個(gè)挑戰(zhàn)

      Pythondatetime模塊中有哪些函數(shù)可用

      如何以特定格式打印或讀取日期和時(shí)間

      如何對(duì)日期和時(shí)間進(jìn)行算術(shù)運(yùn)算

      另外,您將開(kāi)發(fā)一個(gè)簡(jiǎn)潔的應(yīng)用程序來(lái)倒計(jì)時(shí)到下一個(gè) PyCon US 的剩余時(shí)間!

      讓我們開(kāi)始吧!

      用日期和時(shí)間編程

      如果您曾經(jīng)開(kāi)發(fā)過(guò)需要跟蹤多個(gè)地理區(qū)域的時(shí)間的軟件,那么您可能會(huì)明白為什么隨著時(shí)間的推移編程會(huì)如此痛苦。根本的脫節(jié)是計(jì)算機(jī)程序更喜歡完全有序和有規(guī)律的事件,但大多數(shù)人使用和指代時(shí)間的方式是非常不規(guī)則的。

      注意:如果您想更多地了解為什么時(shí)間處理起來(lái)如此復(fù)雜,那么網(wǎng)絡(luò)上有許多很棒的資源。以下是一些不錯(cuò)的起點(diǎn):

      Computerphile:時(shí)間和時(shí)區(qū)問(wèn)題

      使用時(shí)區(qū):您希望不需要知道的一切

      時(shí)間數(shù)據(jù)編程的復(fù)雜性

      這種不規(guī)則性的一個(gè)很好的例子是夏令時(shí)。在美國(guó)和加拿大,時(shí)鐘在 3 月的第二個(gè)星期日快進(jìn)一小時(shí),在 11 月的第一個(gè)星期日快退一小時(shí)。然而,這只是自 2007 年以來(lái)的情況。在 2007 年之前,時(shí)鐘在 4 月的第一個(gè)星期日提前,在 10 月的最后一個(gè)星期日后退。

      當(dāng)您考慮時(shí)區(qū)時(shí),事情變得更加復(fù)雜。理想情況下,時(shí)區(qū)邊界將完全遵循經(jīng)度線。但是,由于歷史和政治原因,時(shí)區(qū)線很少是直的。通常,相隔很遠(yuǎn)的地區(qū)發(fā)現(xiàn)自己處于同一時(shí)區(qū),而相鄰地區(qū)處于不同的時(shí)區(qū)。有一些時(shí)區(qū)的形狀非常時(shí)髦。

      使用 Python datetime 處理日期和時(shí)間

      計(jì)算機(jī)如何計(jì)算時(shí)間

      幾乎所有的計(jì)算機(jī)都從一個(gè)叫做Unix 時(shí)代的時(shí)刻開(kāi)始計(jì)算時(shí)間。這發(fā)生在 1970 年 1 月 1 日的 00:00:00 UTC。UTC 代表Coordinated Universal Time,是指經(jīng)度為 0°的時(shí)間。UTC 通常也稱為格林威治標(biāo)準(zhǔn)時(shí)間或 GMT。UTC 未針對(duì)夏令時(shí)進(jìn)行調(diào)整,因此它每天始終保持二十四小時(shí)。

      根據(jù)定義,Unix 時(shí)間以與 UTC 相同的速率流逝,因此 UTC 中的一秒步長(zhǎng)對(duì)應(yīng)于 Unix 時(shí)間中的一秒步長(zhǎng)。您通常可以通過(guò)計(jì)算自 Unix 紀(jì)元以來(lái)的秒數(shù)來(lái)計(jì)算自 1970 年 1 月 1 日以來(lái)任何給定時(shí)刻的 UTC 日期和時(shí)間,閏秒除外。閏秒偶爾會(huì)添加到 UTC 以說(shuō)明地球自轉(zhuǎn)速度變慢,但不會(huì)添加到 Unix 時(shí)間。

      注意:有一個(gè)與 Unix 時(shí)間相關(guān)的有趣錯(cuò)誤。由于許多較舊的操作系統(tǒng)是 32 位的,因此它們將 Unix 時(shí)間存儲(chǔ)在 32 位有符號(hào)整數(shù)中。

      這意味著在 2038 年 1 月 19 日 03:14:07,整數(shù)將溢出,從而導(dǎo)致所謂的2038 年問(wèn)題或 Y2038。與Y2K 問(wèn)題類似,Y2038 需要更正以避免對(duì)關(guān)鍵系統(tǒng)造成災(zāi)難性后果。

      計(jì)算機(jī)如何計(jì)算時(shí)間

      幾乎所有的計(jì)算機(jī)都從一個(gè)叫做Unix 時(shí)代的時(shí)刻開(kāi)始計(jì)算時(shí)間。這發(fā)生在 1970 年 1 月 1 日的 00:00:00 UTC。UTC 代表Coordinated Universal Time,是指經(jīng)度為 0°的時(shí)間。UTC 通常也稱為格林威治標(biāo)準(zhǔn)時(shí)間或 GMT。UTC 未針對(duì)夏令時(shí)進(jìn)行調(diào)整,因此它每天始終保持二十四小時(shí)。

      根據(jù)定義,Unix 時(shí)間以與 UTC 相同的速率流逝,因此 UTC 中的一秒步長(zhǎng)對(duì)應(yīng)于 Unix 時(shí)間中的一秒步長(zhǎng)。您通常可以通過(guò)計(jì)算自 Unix 紀(jì)元以來(lái)的秒數(shù)來(lái)計(jì)算自 1970 年 1 月 1 日以來(lái)任何給定時(shí)刻的 UTC 日期和時(shí)間,閏秒除外。閏秒偶爾會(huì)添加到 UTC 以說(shuō)明地球自轉(zhuǎn)速度變慢,但不會(huì)添加到 Unix 時(shí)間。

      注意:有一個(gè)與 Unix 時(shí)間相關(guān)的有趣錯(cuò)誤。由于許多較舊的操作系統(tǒng)是 32 位的,因此它們將 Unix 時(shí)間存儲(chǔ)在 32 位有符號(hào)整數(shù)中。

      這意味著在 2038 年 1 月 19 日 03:14:07,整數(shù)將溢出,從而導(dǎo)致所謂的2038 年問(wèn)題或 Y2038。與Y2K 問(wèn)題類似,Y2038 需要更正以避免對(duì)關(guān)鍵系統(tǒng)造成災(zāi)難性后果。

      幾乎所有的編程語(yǔ)言,包括Python,都包含了 Unix 時(shí)間的概念。Python 的標(biāo)準(zhǔn)庫(kù)包含一個(gè)名為的模塊time,可以打印自 Unix 紀(jì)元以來(lái)的秒數(shù):

      >>>

      >>> import time >>> time.time() 1579718137.550164

      在本例中,導(dǎo)入所述time模塊和執(zhí)行time()打印的Unix時(shí)間,或因?yàn)闀r(shí)代的秒(不包括閏秒)號(hào)碼。

      除了 Unix 時(shí)間,計(jì)算機(jī)還需要一種向用戶傳達(dá)時(shí)間信息的方法。正如您在上一個(gè)示例中看到的那樣,人類幾乎不可能解析 Unix 時(shí)間。相反,Unix 時(shí)間通常轉(zhuǎn)換為 UTC,然后可以使用time zone offsets將其轉(zhuǎn)換為本地時(shí)間。

      在互聯(lián)網(wǎng)編號(hào)分配機(jī)構(gòu)(IANA)維護(hù)一個(gè)數(shù)據(jù)庫(kù)的所有時(shí)區(qū)偏移值的。IANA 還發(fā)布定期更新,其中包括時(shí)區(qū)偏移的任何更改。此數(shù)據(jù)庫(kù)通常包含在您的操作系統(tǒng)中,但某些應(yīng)用程序可能包含更新的副本。

      該數(shù)據(jù)庫(kù)包含所有指定時(shí)區(qū)的副本以及它們與 UTC 偏移的小時(shí)數(shù)和分鐘數(shù)。因此,在冬季,當(dāng)夏令時(shí)無(wú)效時(shí),美國(guó)東部時(shí)區(qū)的偏移量為 -05:00,即與 UTC 的負(fù)五小時(shí)。其他地區(qū)有不同的偏移量,可能不是整數(shù)小時(shí)。例如,尼泊爾的 UTC 偏移量是 +05:45,即從 UTC 開(kāi)始的正五小時(shí)四十五分鐘。

      如何報(bào)告標(biāo)準(zhǔn)日期

      Unix 時(shí)間是計(jì)算機(jī)計(jì)算時(shí)間的方式,但人類通過(guò)計(jì)算任意日期的秒數(shù)來(lái)確定時(shí)間的效率非常低。相反,我們以年、月、日等為單位工作。但即使有了這些約定,另一層復(fù)雜性源于不同的語(yǔ)言和文化有不同的日期書(shū)寫(xiě)方式。

      例如,在美國(guó),日期通常從月份開(kāi)始,然后是日期,然后是年份。這意味著 2020 年 1 月 31 日被寫(xiě)為01-31-2020。這與日期的長(zhǎng)格式書(shū)面版本非常匹配。

      但是,歐洲大部分地區(qū)和許多其他地區(qū)的日期都是從日開(kāi)始,然后是月,然后是年。這意味著 2020 年 1 月 31 日寫(xiě)為31-01-2020。在跨文化交流時(shí),這些差異會(huì)導(dǎo)致各種混亂。

      為幫助避免溝通錯(cuò)誤,國(guó)際標(biāo)準(zhǔn)化組織 (ISO) 制定了ISO 8601。該標(biāo)準(zhǔn)規(guī)定所有日期都應(yīng)按從最重要到最不重要的數(shù)據(jù)的順序?qū)懭搿_@意味著格式為年、月、日、小時(shí)、分鐘和秒:

      YYYY-MM-DD HH:MM:SS

      在這個(gè)例子中,YYYY代表一個(gè)四位數(shù)年份,MM并DD有兩位數(shù)的月和日,從零如果需要的話。之后,HH,?MM, 和SS代表兩位數(shù)的小時(shí)、分鐘和秒,必要時(shí)從零開(kāi)始

      這種格式的優(yōu)點(diǎn)是可以毫無(wú)歧義地表示日期。如果日期是有效的月數(shù),則寫(xiě)為DD-MM-YYYY或MM-DD-YYYY可能被誤解的日期。稍后您將看到如何在 Python 中使用 ISO 8601 格式datetime。

      時(shí)間應(yīng)該如何存儲(chǔ)在你的程序中

      大多數(shù)使用 time 的開(kāi)發(fā)人員都聽(tīng)說(shuō)過(guò)將本地時(shí)間轉(zhuǎn)換為 UTC 并存儲(chǔ)該值以供以后參考的建議。在許多情況下,尤其是當(dāng)您存儲(chǔ)過(guò)去的日期時(shí),這些信息足以進(jìn)行任何必要的算術(shù)運(yùn)算。

      但是,如果您的程序的用戶輸入了他們本地時(shí)間的未來(lái)日期,則可能會(huì)出現(xiàn)問(wèn)題。時(shí)區(qū)和夏令時(shí)規(guī)則變化相當(dāng)頻繁,正如您在 2007 年美國(guó)和加拿大夏令時(shí)更改時(shí)看到的那樣。如果用戶位置的時(shí)區(qū)規(guī)則在他們輸入的未來(lái)日期之前發(fā)生變化,則 UTC 將無(wú)法提供足夠的信息來(lái)轉(zhuǎn)換回正確的本地時(shí)間。

      注意:有許多優(yōu)秀的資源可幫助您確定在應(yīng)用程序中存儲(chǔ)時(shí)間數(shù)據(jù)的適當(dāng)方式。這里有幾個(gè)地方可以開(kāi)始:

      夏令時(shí)和時(shí)區(qū)最佳實(shí)踐

      存儲(chǔ) UTC 不是銀彈

      如何保存未來(lái)事件的日期時(shí)間

      在 .NET Framework 中使用 DateTime 編碼最佳實(shí)踐

      在這種情況下,您需要存儲(chǔ)本地時(shí)間,包括用戶輸入的時(shí)區(qū),以及用戶保存時(shí)間時(shí)有效的 IANA 時(shí)區(qū)數(shù)據(jù)庫(kù)版本。這樣,您將始終能夠?qū)⒈镜貢r(shí)間轉(zhuǎn)換為 UTC。但是,這種方法并不總是允許您將 UTC 轉(zhuǎn)換為正確的本地時(shí)間。

      使用 Pythondatetime模塊

      如您所見(jiàn),在編程中處理日期和時(shí)間可能很復(fù)雜。幸運(yùn)的是,如今您很少需要從頭開(kāi)始實(shí)現(xiàn)復(fù)雜的功能,因?yàn)橛性S多開(kāi)源庫(kù)可以提供幫助。這在 Python 中絕對(duì)是這樣,它在標(biāo)準(zhǔn)庫(kù)中包含三個(gè)獨(dú)立的模塊來(lái)處理日期和時(shí)間:

      calendar輸出日歷并使用理想化的公歷提供功能。

      datetime?提供用于操作日期和時(shí)間的類。

      time?提供不需要日期的時(shí)間相關(guān)功能。

      在本教程中,您將專注于使用 Pythondatetime模塊。的主要重點(diǎn)datetime是降低訪問(wèn)與日期、時(shí)間和時(shí)區(qū)相關(guān)的對(duì)象屬性的復(fù)雜性。由于這些對(duì)象非常有用,calendar還從datetime.

      time功能不如datetime.?許多函數(shù)time返回一個(gè)特殊的struct_time實(shí)例。該對(duì)象具有用于訪問(wèn)存儲(chǔ)數(shù)據(jù)的命名元組接口,使其類似于 的實(shí)例datetime。但是,它不支持 的所有功能datetime,尤其是使用時(shí)間值執(zhí)行算術(shù)的能力。

      datetime?提供了三個(gè)類,它們構(gòu)成了大多數(shù)人會(huì)使用的高級(jí)接口:

      datetime.date是一個(gè)理想化的日期,假定公歷無(wú)限延伸到未來(lái)和過(guò)去。這個(gè)對(duì)象存儲(chǔ)year,month以及day為屬性。

      datetime.time是一個(gè)理想化的時(shí)間,假設(shè)每天有 86,400 秒,沒(méi)有閏秒。此對(duì)象存儲(chǔ)的hour,minute,second,microsecond,和tzinfo(時(shí)區(qū)信息)。

      datetime.datetime是 adate和 a的組合time。它具有兩個(gè)類的所有屬性。

      創(chuàng)建 Pythondatetime實(shí)例

      表示日期和時(shí)間的三個(gè)類datetime具有相似的初始值設(shè)定項(xiàng)。它們可以通過(guò)傳遞關(guān)鍵字參數(shù)對(duì)于每個(gè)屬性,諸如被實(shí)例化year,date或hour。您可以嘗試下面的代碼來(lái)了解每個(gè)對(duì)象是如何創(chuàng)建的:

      >>>

      >>> from datetime import date, time, datetime >>> date(year=2020, month=1, day=31) datetime.date(2020, 1, 31) >>> time(hour=13, minute=14, second=31) datetime.time(13, 14, 31) >>> datetime(year=2020, month=1, day=31, hour=13, minute=14, second=31) datetime.datetime(2020, 1, 31, 13, 14, 31)

      在此代碼中,您從中導(dǎo)入三個(gè)主要類,datetime并通過(guò)將參數(shù)傳遞給構(gòu)造函數(shù)來(lái)實(shí)例化它們中的每一個(gè)。您可以看到這段代碼有些冗長(zhǎng),如果您沒(méi)有整數(shù)形式的所需信息,則無(wú)法使用這些技術(shù)來(lái)創(chuàng)建datetime實(shí)例。

      幸運(yùn)的是,datetime提供了其他幾種創(chuàng)建datetime實(shí)例的便捷方式。這些方法不需要您使用整數(shù)來(lái)指定每個(gè)屬性,而是允許您使用其他一些信息:

      date.today()創(chuàng)建一個(gè)datetime.date具有當(dāng)前本地日期的實(shí)例。

      datetime.now()創(chuàng)建一個(gè)datetime.datetime具有當(dāng)前本地日期和時(shí)間的實(shí)例。

      datetime.combine()將datetime.date和datetime.time的datetime.datetime實(shí)例合并為一個(gè)實(shí)例。

      datetime當(dāng)您事先不知道需要傳遞給基本初始化程序的信息時(shí),這三種創(chuàng)建實(shí)例的方法會(huì)很有幫助。您可以嘗試使用此代碼來(lái)查看備用初始值設(shè)定項(xiàng)是如何工作的:

      >>>

      >>> from datetime import date, time, datetime >>> today = date.today() >>> today datetime.date(2020, 1, 24) >>> now = datetime.now() >>> now datetime.datetime(2020, 1, 24, 14, 4, 57, 10015) >>> current_time = time(now.hour, now.minute, now.second) >>> datetime.combine(today, current_time) datetime.datetime(2020, 1, 24, 14, 4, 57)

      在這段代碼中,你使用date.today(),datetime.now()以及datetime.combine()創(chuàng)建的實(shí)例date,datetime和time對(duì)象。每個(gè)實(shí)例都存儲(chǔ)在不同的變量中:

      today是一個(gè)date只有年、月和日的實(shí)例。

      now是datetime具有年、月、日、小時(shí)、分鐘、秒和微秒的實(shí)例。

      current_time是一個(gè)time實(shí)例,其小時(shí)、分鐘和秒設(shè)置為與 相同的值now。

      在最后一行,您將日期信息today與時(shí)間信息組合current_time以生成一個(gè)新datetime實(shí)例。

      警告:?datetime還提供datetime.utcnow(),它返回datetime當(dāng)前 UTC 的一個(gè)實(shí)例。但是,Python文檔建議不要使用此方法,因?yàn)樗诮Y(jié)果實(shí)例中不包含任何時(shí)區(qū)信息。

      在實(shí)例之間進(jìn)行算術(shù)或比較時(shí),使用datetime.utcnow()可能會(huì)產(chǎn)生一些令人驚訝的結(jié)果datetime。在后面的部分中,您將看到如何將時(shí)區(qū)信息分配給datetime實(shí)例。

      使用字符串創(chuàng)建 Pythondatetime實(shí)例

      創(chuàng)建date實(shí)例的另一種方法是使用.fromisoformat().?要使用此方法,您提供一個(gè)字符串與您了解了在ISO 8601格式的日期更早。例如,您可以提供一個(gè)指定了年、月和日期的字符串:

      2020-01-31

      根據(jù) ISO 8601 格式,此字符串表示 2020 年 1 月 31 日的日期。您可以date使用以下示例創(chuàng)建實(shí)例:

      >>>

      >>> from datetime import date >>> date.fromisoformat("2020-01-31") datetime.date(2020, 1, 31)

      在此代碼中,您用于date.fromisoformat()創(chuàng)建date2020 年 1 月 31 日的實(shí)例。此方法非常有用,因?yàn)樗?ISO 8601 標(biāo)準(zhǔn)。但是,如果您有一個(gè)表示日期和時(shí)間但不是 ISO 8601 格式的字符串怎么辦?

      幸運(yùn)的是,Pythondatetime提供了一個(gè)被調(diào)用的方法.strptime()來(lái)處理這種情況。該方法使用一種特殊的迷你語(yǔ)言來(lái)告訴 Python 字符串的哪些部分與datetime屬性相關(guān)聯(lián)。

      要使用 構(gòu)造一個(gè)datetime字符串.strptime(),您必須使用來(lái)自迷你語(yǔ)言的格式化代碼告訴 Python 字符串的每個(gè)部分代表什么。你可以試試這個(gè)例子,看看它是如何.strptime()工作的:

      >>>

      1>>> date_string = "01-31-2020 14:45:37" 2>>> format_string = "%m-%d-%Y %H:%M:%S"

      在第 1 行,您創(chuàng)建date_string,它表示 2020 年 1 月 31 日下午 2:45:37 的日期和時(shí)間。在第 2 行,您創(chuàng)建format_string,它使用迷你語(yǔ)言指定如何將 的部分date_string轉(zhuǎn)換為datetime屬性。

      在 中format_string,您包含幾個(gè)格式代碼以及所有的破折號(hào) (?-)、冒號(hào) (?:) 和空格,與它們?cè)赿ate_string.?要處理 中的日期和時(shí)間date_string,請(qǐng)包含以下格式代碼:

      迷你語(yǔ)言中所有選項(xiàng)的完整列表超出了本教程的范圍,但您可以在網(wǎng)絡(luò)上找到一些很好的參考資料,包括 Python 的文檔和名為strftime.org的網(wǎng)站。

      現(xiàn)在已經(jīng)定義了date_string和format_string,您可以使用它們來(lái)創(chuàng)建datetime實(shí)例。以下是.strptime()工作原理的示例:

      >>>

      3>>> from datetime import datetime 4>>> datetime.strptime(date_string, format_string) 5datetime.datetime(2020, 1, 31, 14, 45, 37)

      在此代碼中,您datetime在第 3 行導(dǎo)入并在第 4 行使用datetime.strptime()withdate_string和。最后,第 5 行顯示了創(chuàng)建的實(shí)例中的屬性值。您可以看到它們與上表中顯示的值匹配。format_stringdatetime.strptime()

      注意:有更高級(jí)的方法來(lái)創(chuàng)建datetime實(shí)例,但它們涉及使用必須安裝的第三方庫(kù)。一個(gè)特別簡(jiǎn)潔的庫(kù)稱為dateparser,它允許您提供自然語(yǔ)言字符串輸入。輸入甚至支持多種語(yǔ)言:

      >>>

      1>>> import dateparser 2>>> dateparser.parse("yesterday") 3datetime.datetime(2020, 3, 13, 14, 39, 1, 350918) 4>>> dateparser.parse("morgen") 5datetime.datetime(2020, 3, 15, 14, 39, 7, 314754)

      在此代碼中,您用于通過(guò)傳遞兩個(gè)不同的時(shí)間字符串表示dateparser來(lái)創(chuàng)建兩個(gè)datetime實(shí)例。在第 1 行,您導(dǎo)入dateparser.?然后,在第 2 行,您使用.parse()參數(shù)"yesterday"來(lái)創(chuàng)建datetime過(guò)去二十四小時(shí)的實(shí)例。在撰寫(xiě)本文時(shí),這是 2020 年 3 月 13 日下午 2:39。

      在第 3 行,您使用.parse()了參數(shù)"morgen"。Morgen是明天的德語(yǔ)單詞,因此在未來(lái) 24 小時(shí)內(nèi)dateparser創(chuàng)建一個(gè)datetime實(shí)例。在撰寫(xiě)本文時(shí),這是 3 月 15 日下午 2:39。

      開(kāi)始你的 PyCon 倒計(jì)時(shí)

      現(xiàn)在您有足夠的信息開(kāi)始為明年的PyCon US 制作倒計(jì)時(shí)時(shí)鐘!PyCon US 2021 將于 2021 年 5 月 12 日在賓夕法尼亞州匹茲堡舉行。隨著 2020 年的活動(dòng)被取消,許多 Pythonistas 對(duì)明年的聚會(huì)格外興奮。這是跟蹤您需要等待多長(zhǎng)時(shí)間并同時(shí)提高datetime技能的好方法!

      首先,創(chuàng)建一個(gè)名為的文件pyconcd.py并添加以下代碼:

      # pyconcd.py from datetime import datetime PYCON_DATE = datetime(year=2021, month=5, day=12, hour=8) countdown = PYCON_DATE - datetime.now() print(f"Countdown to PyCon US 2021: {countdown}")

      在此代碼,您導(dǎo)入datetime從datetime和定義常量,PYCON_DATE即存儲(chǔ)下一個(gè)PYCON美國(guó)的日期。您不希望 PyCon 的日期發(fā)生變化,因此您將變量全部大寫(xiě)以表明它是一個(gè)常量。

      接下來(lái),您計(jì)算 與 之間的差異datetime.now(),即當(dāng)前時(shí)間PYCON_DATE。取兩個(gè)datetime實(shí)例之間的差異返回一個(gè)datetime.timedelta實(shí)例。

      timedelta實(shí)例表示兩個(gè)datetime實(shí)例之間的時(shí)間變化。名稱中的delta是對(duì)希臘字母 delta 的引用,它在科學(xué)和工程中用于表示變化。稍后您將了解有關(guān)如何使用timedelta更一般的算術(shù)運(yùn)算的更多信息。

      最后,截至 2020 年 4 月 9 日晚上 9:30 之前的打印輸出為:

      Countdown to PyCon US 2021: 397 days, 10:35:32.139350

      距離 PyCon US 2021 僅剩 397 天!此輸出有點(diǎn)笨拙,因此稍后您將看到如何改進(jìn)格式。如果您在不同的日子運(yùn)行此腳本,您將獲得不同的輸出。如果您在 2021 年 5 月 12 日上午 8 點(diǎn)之后運(yùn)行腳本,您將獲得負(fù)的剩余時(shí)間!

      使用時(shí)區(qū)

      正如您之前看到的,存儲(chǔ)日期發(fā)生的時(shí)區(qū)是確保您的代碼正確的一個(gè)重要方面。Pythondatetime提供了tzinfo,它是一個(gè)抽象基類,允許datetime.datetime并datetime.time包含時(shí)區(qū)信息,包括夏令時(shí)的概念。

      但是,datetime不提供與 IANA 時(shí)區(qū)數(shù)據(jù)庫(kù)交互的直接方式。Pythondatetime.tzinfo文檔建議使用名為dateutil.?您可以安裝dateutil使用pip:

      $ python -m pip install python-dateutil

      請(qǐng)注意,您從 PyPI 安裝的包python-dateutil的名稱 , 與您用于導(dǎo)入包的名稱不同,即dateutil.

      使用dateutil到時(shí)區(qū)添加到Pythondatetime

      dateutil如此有用的一個(gè)原因是它包含一個(gè)到 IANA 時(shí)區(qū)數(shù)據(jù)庫(kù)的接口。這消除了為您的datetime實(shí)例分配時(shí)區(qū)的麻煩。試試這個(gè)例子,看看如何設(shè)置一個(gè)datetime實(shí)例以使用您的本地時(shí)區(qū):

      >>>

      >>> from dateutil import tz >>> from datetime import datetime >>> now = datetime.now(tz=tz.tzlocal()) >>> now datetime.datetime(2020, 1, 26, 0, 55, 3, 372824, tzinfo=tzlocal()) >>> now.tzname() 'Eastern Standard Time'

      在本例中,您導(dǎo)入?tzfromdateutil和datetimefrom?datetime。然后,您可以使用datetime來(lái)創(chuàng)建一個(gè)設(shè)置為當(dāng)前時(shí)間的實(shí)例.now()。

      您還將tz關(guān)鍵字傳遞給.now()并設(shè)置為tz等于tz.tzlocal()。在 中dateutil,tz.tzlocal()返回 的具體實(shí)例datetime.tzinfo。這意味著它可以代表所有需要的時(shí)區(qū)偏移和夏令時(shí)信息datetime。

      您還可以使用 打印時(shí)區(qū)的名稱.tzname(),它會(huì)打印'Eastern Standard Time'.?這是 Windows 的輸出,但在 macOS 或 Linux 上,'EST'如果您在冬季處于美國(guó)東部時(shí)區(qū),則您的輸出可能會(huì)讀取。

      您還可以創(chuàng)建與計(jì)算機(jī)報(bào)告的時(shí)區(qū)不同的時(shí)區(qū)。為此,您將使用tz.gettz()并傳遞您感興趣的時(shí)區(qū)的官方IANA 名稱。以下是如何使用的示例tz.gettz():

      >>>

      >>> from dateutil import tz >>> from datetime import datetime >>> London_tz = tz.gettz("Europe/London") >>> now = datetime.now(tz=London_tz) >>> now datetime.datetime(2020, 1, 26, 6, 14, 53, 513460, tzinfo=tzfile('GB-Eire')) >>> now.tzname() 'GMT'

      在此示例中,您使用tz.gettz()檢索英國(guó)倫敦的時(shí)區(qū)信息并將其存儲(chǔ)在London_tz.?然后檢索當(dāng)前時(shí)間,將時(shí)區(qū)設(shè)置為L(zhǎng)ondon_tz。

      在 Windows 上,這為tzinfo屬性提供了值tzfile('GB-Eire')。在 macOS 或 Linux 上,該tzinfo屬性將類似于tzfile('/usr/share/zoneinfo/Europe/London),但根據(jù)dateutil提取時(shí)區(qū)數(shù)據(jù)的位置,它可能會(huì)略有不同。

      您還用于tzname()打印時(shí)區(qū)的名稱,即 now?'GMT',意思是格林威治標(biāo)準(zhǔn)時(shí)間。此輸出在 Windows、macOS 和 Linux 上是相同的。

      在前面的部分中,您了解到不應(yīng)使用.utcnow()以datetime當(dāng)前 UTC 時(shí)間創(chuàng)建實(shí)例。現(xiàn)在您知道如何使用dateutil.tz為datetime實(shí)例提供時(shí)區(qū)。這是根據(jù) Python 文檔中的建議修改的示例:

      >>>

      >>> from dateutil import tz >>> from datetime import datetime >>> datetime.now(tz=tz.UTC) datetime.datetime(2020, 3, 14, 19, 1, 20, 228415, tzinfo=tzutc())

      在此代碼中,您用于tz.UTC將時(shí)區(qū)設(shè)置datetime.now()為 UTC 時(shí)區(qū)。建議使用這種方法比使用utcnow(),因?yàn)閡tcnow()回報(bào)天真的?datetime實(shí)例,而這里展示的方法返回一個(gè)認(rèn)識(shí)?datetime實(shí)例。

      接下來(lái),您將走一小段路來(lái)了解樸素實(shí)例與感知?datetime實(shí)例。如果您已經(jīng)了解這一切,那么您可以跳過(guò)以使用時(shí)區(qū)信息改進(jìn)您的 PyCon 倒計(jì)時(shí)。

      比較 Naive 和 Aware Pythondatetime實(shí)例

      Pythondatetime實(shí)例支持兩種類型的操作,naive 和aware。它們之間的基本區(qū)別在于,naive 實(shí)例不包含時(shí)區(qū)信息,而感知實(shí)例包含時(shí)區(qū)信息。更正式地,引用 Python 文檔:

      一個(gè)有意識(shí)的對(duì)象代表一個(gè)特定的時(shí)間,它是不可解釋的。一個(gè)天真的對(duì)象不包含足夠的信息來(lái)明確地相對(duì)于其他日期/時(shí)間對(duì)象定位自己。(來(lái)源)

      這是使用 Python 的一個(gè)重要區(qū)別datetime。一個(gè)感知?datetime實(shí)例可以明確地將自己與其他感知datetime實(shí)例進(jìn)行比較,并且在算術(shù)運(yùn)算中使用時(shí)將始終返回正確的時(shí)間間隔。

      datetime另一方面,樸素的實(shí)例可能是模棱兩可的。這種歧義的一個(gè)例子與夏令時(shí)有關(guān)。實(shí)行夏令時(shí)的地區(qū)在春季將時(shí)鐘向前撥一小時(shí),在秋季撥開(kāi)一小時(shí)。這通常發(fā)生在當(dāng)?shù)貢r(shí)間凌晨 2:00。在春天,從凌晨 2:00 到凌晨 2:59 的時(shí)間不會(huì)發(fā)生,而在秋天,從凌晨 1:00 到凌晨 1:59 的時(shí)間會(huì)發(fā)生兩次!

      實(shí)際上,這些時(shí)區(qū)與 UTC 的偏移量全年都會(huì)發(fā)生變化。IANA 跟蹤這些更改并將它們編入您計(jì)算機(jī)已安裝的不同數(shù)據(jù)庫(kù)文件中。使用像 一樣的庫(kù)dateutil,它在底層使用 IANA 數(shù)據(jù)庫(kù),是確保您的代碼隨著時(shí)間正確處理算術(shù)的好方法。

      注意:在 Python 中,naivedatetime實(shí)例和感知實(shí)例之間的區(qū)別是由tzinfo屬性決定的。感知datetime實(shí)例具有tzinfo與datetime.tzinfo抽象基類的子類相等的屬性。

      Python的3.8及以下提供的一個(gè)具體實(shí)施tzinfo所謂的timezone。但是,timezone僅限于表示與 UTC 的固定偏移量,該偏移量不能全年更改,因此當(dāng)您需要考慮夏令時(shí)等更改時(shí),它不是很有用。

      Python 3.9包含一個(gè)名為的新模塊zoneinfo,該模塊提供tzinfo跟蹤 IANA 數(shù)據(jù)庫(kù)的具體實(shí)現(xiàn),因此它包括夏令時(shí)等更改。然而,在 Python 3.9 被廣泛使用之前,dateutil如果您需要支持多個(gè) Python 版本,依賴它可能是有意義的。

      dateutil還提供了您之前使用tzinfo的tz模塊中的幾個(gè)具體實(shí)現(xiàn)。您可以查看dateutil.tz文檔以獲取更多信息。

      這并不意味著您總是需要使用感知datetime實(shí)例。但是,如果您要相互比較時(shí)間,則有意識(shí)的實(shí)例至關(guān)重要,尤其是在比較世界不同地區(qū)的時(shí)間時(shí)。

      改進(jìn)你的 PyCon 倒計(jì)時(shí)

      現(xiàn)在您知道如何向 Pythondatetime實(shí)例添加時(shí)區(qū)信息,您可以改進(jìn) PyCon 倒計(jì)時(shí)代碼。早些時(shí)候,您使用標(biāo)準(zhǔn)datetime構(gòu)造函數(shù)傳遞 PyCon 將啟動(dòng)的年、月、日和小時(shí)。您可以更新代碼以使用該dateutil.parser模塊,該模塊為創(chuàng)建datetime實(shí)例提供了更自然的界面:

      # pyconcd.py from dateutil import parser, tz from datetime import datetime PYCON_DATE = parser.parse("May 12, 2021 8:00 AM") PYCON_DATE = PYCON_DATE.replace(tzinfo=tz.gettz("America/New_York")) now = datetime.now(tz=tz.tzlocal()) countdown = PYCON_DATE - now print(f"Countdown to PyCon US 2021: {countdown}")

      在此代碼中,您導(dǎo)入?parser和tz來(lái)自dateutil和datetime來(lái)自datetime。接下來(lái),您使用parser.parse()從字符串中讀取下一個(gè) PyCon US 的日期。這比普通的datetime構(gòu)造函數(shù)更具可讀性。

      parser.parse()返回一個(gè)天真的datetime實(shí)例,讓你用.replace()改變tzinfo的America/New_York時(shí)區(qū)。PyCon US 2021 將在位于美國(guó)東部時(shí)區(qū)的賓夕法尼亞州匹茲堡舉行。該時(shí)區(qū)的規(guī)范名稱是America/New_York因?yàn)榧~約市是該時(shí)區(qū)中最大的城市。

      PYCON_DATE是datetime時(shí)區(qū)設(shè)置為美國(guó)東部時(shí)間的感知實(shí)例。由于 5 月 12 日是夏令時(shí)生效后,時(shí)區(qū)名稱為'EDT', 或'Eastern Daylight Time'。

      接下來(lái),您創(chuàng)建now代表當(dāng)前時(shí)刻并為其指定本地時(shí)區(qū)。最后,找到andtimedelta之間的值并打印結(jié)果。如果您所在的地區(qū)不針對(duì)夏令時(shí)調(diào)整時(shí)鐘,那么您可能會(huì)看到 PyCon 更改一個(gè)小時(shí)之前的剩余小時(shí)數(shù)。PYCON_DATEnow

      用 Python 進(jìn)行算術(shù)運(yùn)算?datetime

      Pythondatetime實(shí)例支持多種類型的算術(shù)。正如您之前看到的,這依賴于使用timedelta實(shí)例來(lái)表示時(shí)間間隔。timedelta非常有用,因?yàn)樗鼉?nèi)置于 Python 標(biāo)準(zhǔn)庫(kù)中。以下是如何使用的示例timedelta:

      >>>

      >>> from datetime import datetime, timedelta >>> now = datetime.now() >>> now datetime.datetime(2020, 1, 26, 9, 37, 46, 380905) >>> tomorrow = timedelta(days=+1) >>> now + tomorrow datetime.datetime(2020, 1, 27, 9, 37, 46, 380905)

      在此代碼,您可以創(chuàng)建now,存儲(chǔ)當(dāng)前時(shí)間,并且tomorrow,這是一個(gè)timedelta的+1天。接下來(lái),您添加now并在未來(lái)的某一天tomorrow生成一個(gè)datetime實(shí)例。請(qǐng)注意,使用原始datetime實(shí)例,就像您在這里一樣,意味著增量的day屬性datetime增加一并且不考慮任何重復(fù)或跳過(guò)的時(shí)間間隔。

      timedelta?實(shí)例還支持負(fù)值作為參數(shù)的輸入:

      >>>

      >>> yesterday = timedelta(days=-1) >>> now + yesterday datetime.datetime(2020, 1, 25, 9, 37, 46, 380905)

      在此示例中,您將 提供-1為 的輸入timedelta,因此當(dāng)您添加now和 時(shí)yesterday,結(jié)果是days屬性減 1?。

      timedelta實(shí)例支持所有參數(shù)的加法和減法以及正整數(shù)和負(fù)整數(shù)。您甚至可以提供正面和負(fù)面參數(shù)的混合。例如,您可能想要添加三天并減去四小時(shí):

      >>>

      >>> delta = timedelta(days=+3, hours=-4) >>> now + delta datetime.datetime(2020, 1, 29, 5, 37, 46, 380905)

      在此示例中,您添加了三天并減去了四小時(shí),因此新的時(shí)間datetime是 1 月 29 日凌晨 5:37。timedelta在這種方式下非常有用,但它有一定的局限性,因?yàn)樗荒芴砑踊驕p去大于一天的間隔,例如一個(gè)月或一年。幸運(yùn)的是,dateutil提供了一個(gè)更強(qiáng)大的替代品,稱為relativedelta.

      的基本語(yǔ)法relativedelta與timedelta.?您可以提供關(guān)鍵字參數(shù)來(lái)產(chǎn)生任意數(shù)量的年、月、日、小時(shí)、秒或微秒的變化。您可以timedelta使用以下代碼重現(xiàn)第一個(gè)示例:

      >>>

      >>> from dateutil.relativedelta import relativedelta >>> tomorrow = relativedelta(days=+1) >>> now + tomorrow datetime.datetime(2020, 1, 27, 9, 37, 46, 380905)

      在本例中,您使用relativedelta代替timedelta來(lái)查找datetime與明天相對(duì)應(yīng)的。現(xiàn)在,您可以嘗試now在減去四小時(shí)三十分鐘的同時(shí)加上五年、一個(gè)月和三天:

      >>>

      >>> delta = relativedelta(years=+5, months=+1, days=+3, hours=-4, minutes=-30) >>> now + delta datetime.datetime(2025, 3, 1, 5, 7, 46, 380905)

      請(qǐng)注意,在此示例中,日期以 2025 年 3 月 1 日結(jié)束。這是因?yàn)閷?3 天添加到now1 月 29 日,將一個(gè)月添加到 2 月 29 日,這僅存在于閏年。由于 2025 年不是閏年,因此日期會(huì)滾動(dòng)到下個(gè)月。

      您還可以使用relativedelta來(lái)計(jì)算兩個(gè)datetime實(shí)例之間的差異。早些時(shí)候,您使用減法運(yùn)算符來(lái)查找兩個(gè) Pythondatetime實(shí)例之間的差異,PYCON_DATE并且now.?使用relativedelta, 而不是使用減法運(yùn)算符,您需要將兩個(gè)datetime實(shí)例作為參數(shù)傳遞:

      >>>

      >>> now datetime.datetime(2020, 1, 26, 9, 37, 46, 380905) >>> tomorrow = datetime(2020, 1, 27, 9, 37, 46, 380905) >>> relativedelta(now, tomorrow) relativedelta(days=-1)

      在此示例中,您通過(guò)將字段增加 1datetime來(lái)創(chuàng)建一個(gè)新實(shí)例。然后,您使用和傳遞和作為兩個(gè)參數(shù)。然后取這兩個(gè)實(shí)例之間的差異并將結(jié)果作為實(shí)例返回。在這種情況下,差異是天,因?yàn)榘l(fā)生在 之前。tomorrowdaysrelativedeltanowtomorrowdateutildatetimerelativedelta-1nowtomorrow

      dateutil.relativedelta對(duì)象還有無(wú)數(shù)其他用途。您可以使用它們來(lái)查找復(fù)雜的日歷信息,例如下一年的 10 月 13 日是星期五或當(dāng)月最后一個(gè)星期五的日期。您甚至可以使用它們來(lái)替換datetime實(shí)例的屬性并創(chuàng)建,例如,datetime未來(lái)一周的上午 10:00。您可以在dateutil?文檔中閱讀所有關(guān)于這些其他用途的信息。

      完成你的 PyCon 倒計(jì)時(shí)

      你現(xiàn)在有足夠的工具來(lái)完成你的 PyCon 2021 倒計(jì)時(shí)時(shí)鐘,并提供一個(gè)很好的界面來(lái)使用。在本節(jié)中,您將使用relativedelta計(jì)算 PyCon 之前的剩余時(shí)間,開(kāi)發(fā)一個(gè)函數(shù)以漂亮的格式打印剩余時(shí)間,并向用戶顯示 PyCon 的日期。

      使用relativedelta在你的PYCON倒計(jì)時(shí)

      首先,用 替換普通減法運(yùn)算符relativedelta。使用減法運(yùn)算符,您的timedelta對(duì)象無(wú)法計(jì)算大于一天的時(shí)間間隔。但是,relativedelta允許您顯示剩余的年、月和日:

      1# pyconcd.py 2 3from dateutil import parser, tz 4from dateutil.relativedelta import relativedelta 5from datetime import datetime 6 7PYCON_DATE = parser.parse("May 12, 2021 8:00 AM") 8PYCON_DATE = PYCON_DATE.replace(tzinfo=tz.gettz("America/New_York")) 9now = datetime.now(tz=tz.tzlocal()) 10 11countdown = relativedelta(PYCON_DATE, now) 12print(f"Countdown to PyCon US 2021: {countdown}")

      您在此代碼中所做的唯一更改是將第 11 行替換為countdown = relativedelta(PYCON_DATE, now).?此腳本的輸出應(yīng)告訴您 PyCon US 2021 將在大約一年零一個(gè)月后舉行,具體取決于您運(yùn)行腳本的時(shí)間。

      但是,該輸出不是很漂亮,因?yàn)樗雌饋?lái)像relativedelta().?你可以通過(guò)用下面的代碼替換前面代碼中的第 11 行來(lái)構(gòu)建一些更漂亮的輸出:

      11def time_amount(time_unit: str, countdown: relativedelta) -> str: 12 t = getattr(countdown, time_unit) 13 return f"{t} {time_unit}" if t != 0 else "" 14 15countdown = relativedelta(PYCON_DATE, now) 16time_units = ["years", "months", "days", "hours", "minutes", "seconds"] 17output = (t for tu in time_units if (t := time_amount(tu, countdown))) 18print("Countdown to PyCon US 2021:", ", ".join(output))

      此代碼需要 Python 3.8,因?yàn)樗褂昧诵碌膚alrus operator。通過(guò)使用傳統(tǒng)for循環(huán)代替第 17 行,您可以使該腳本在舊版本的 Python上運(yùn)行。

      在此代碼中,您定義了time_amount(),它接受兩個(gè)參數(shù),relativedelta時(shí)間單位和應(yīng)從中檢索時(shí)間單位的實(shí)例。如果時(shí)間量不為零,則time_amount()返回一個(gè)包含時(shí)間量和時(shí)間單位的字符串。否則,它返回一個(gè)空字符串。

      您可以使用time_amount()在理解上線17。該行創(chuàng)建了一個(gè)生成器,用于存儲(chǔ)從 返回的非空字符串time_amount()。它采用海象運(yùn)營(yíng)商分配的返回值time_amount(),以t包括t只有當(dāng)它是True。

      最后,第 18 行使用.join()on生成器打印最終輸出。接下來(lái),您將查看在腳本的輸出中包含 PyCon 日期。

      在 PyCon 倒計(jì)時(shí)中顯示 PyCon 日期

      早些時(shí)候,您學(xué)習(xí)了datetime使用.strptime().?此方法使用 Python 中的特殊迷你語(yǔ)言來(lái)指定日期字符串的格式。

      Pythondatetime有一個(gè)額外的方法被調(diào)用.strftime(),它允許你將一個(gè)datetime實(shí)例格式化為一個(gè)字符串。從某種意義上說(shuō),它是解析 using 的逆操作.strptime()。您可以通過(guò)記住pin.strptime()代表parse和fin.strftime()代表format來(lái)區(qū)分這兩種方法。

      在您的 PyCon 倒計(jì)時(shí)中,您可以使用.strftime()打印輸出讓用戶知道 PyCon US 的開(kāi)始日期。請(qǐng)記住,您可以在strftime.org上找到要使用的格式代碼。現(xiàn)在在PyCon 倒計(jì)時(shí)腳本的第 18 行添加此代碼:

      18pycon_date_str = PYCON_DATE.strftime("%A, %B %d, %Y at %H:%M %p %Z") 19print(f"PyCon US 2021 will start on:", pycon_date_str) 20print("Countdown to PyCon US 2021:", ", ".join(output))

      在這段代碼中,第18層的用途.strftime(),以創(chuàng)建代表PYCON美國(guó)的起始日期2021的輸出包括一個(gè)字符串的工作日,月,日,年,小時(shí),分鐘,上午或下午,和時(shí)區(qū):

      Wednesday, May 12, 2021 at 08:00 AM EDT

      在第 19 行,您打印此字符串以供用戶查看并帶有一些解釋性文本。最后一行打印到 PyCon 開(kāi)始日期的剩余時(shí)間。接下來(lái),您將完成您的腳本,以便其他人可以更輕松地重復(fù)使用。

      完成你的 PyCon 倒計(jì)時(shí)

      您需要采取的最后一步是遵循 Python最佳實(shí)踐,并將產(chǎn)生輸出的代碼放入一個(gè)main()函數(shù)中。應(yīng)用所有這些更改后,您可以查看完整的最終代碼:

      1# pyconcd.py 2 3from dateutil import parser, tz 4from dateutil.relativedelta import relativedelta 5from datetime import datetime 6 7PYCON_DATE = parser.parse("May 12, 2021 8:00 AM") 8PYCON_DATE = PYCON_DATE.replace(tzinfo=tz.gettz("America/New_York")) 9 10def time_amount(time_unit: str, countdown: relativedelta) -> str: 11 t = getattr(countdown, time_unit) 12 return f"{t} {time_unit}" if t != 0 else "" 13 14def main(): 15 now = datetime.now(tz=tz.tzlocal()) 16 countdown = relativedelta(PYCON_DATE, now) 17 time_units = ["years", "months", "days", "hours", "minutes", "seconds"] 18 output = (t for tu in time_units if (t := time_amount(tu, countdown))) 19 pycon_date_str = PYCON_DATE.strftime("%A, %B %d, %Y at %H:%M %p %Z") 20 print(f"PyCon US 2021 will start on:", pycon_date_str) 21 print("Countdown to PyCon US 2021:", ", ".join(output)) 22 23if __name__ == "__main__": 24 main()

      在此代碼中,您將print()用于生成器的代碼移動(dòng)到main().?在第 23 行,您使用guard 子句來(lái)確保main()僅在此文件作為腳本執(zhí)行時(shí)才運(yùn)行。這允許其他人導(dǎo)入您的代碼并重用PYCON_DATE,例如,如果他們?cè)敢獾脑挕?/p>

      現(xiàn)在,您可以根據(jù)需要隨意修改此腳本。一件巧妙的事情可能是允許用戶now通過(guò)傳遞命令行參數(shù)來(lái)更改與之關(guān)聯(lián)的時(shí)區(qū)。您還可以將其更改PYCON_DATE為離家更近的東西,例如PyCon Africa或EuroPython。

      要對(duì) PyCon 更加興奮,請(qǐng)查看PyCon US 2019 上的 Real Python以及如何充分利用 PyCon!

      Python 的替代品datetime和dateutil

      當(dāng)您處理日期和時(shí)間時(shí),Pythondatetime和dateutil庫(kù)的強(qiáng)大組合。dateutil甚至在 Python 文檔中也推薦使用。但是,還有許多其他庫(kù)可用于在 Python 中處理日期和時(shí)間。其中一些依賴于datetimeand?dateutil,而另一些則是完全獨(dú)立的替代品:

      pytz提供類似于dateutil.?它使用的界面與標(biāo)準(zhǔn)有所不同datetime.tzinfo,因此如果您決定使用它,請(qǐng)注意潛在的問(wèn)題。

      Arrow為datetime.?它的靈感來(lái)自moment.js,所以如果您來(lái)自 Web 開(kāi)發(fā),那么這可能是一個(gè)更熟悉的界面。

      Pendulum為datetime.?它包括一個(gè)時(shí)區(qū)接口和一個(gè)改進(jìn)的timedelta實(shí)現(xiàn)。

      Maya提供了與datetime.?它依賴 Pendulum 來(lái)解析庫(kù)的部分內(nèi)容。

      dateparser提供了一個(gè)接口來(lái)datetime從人類可讀的文本生成實(shí)例。它很靈活,支持多種語(yǔ)言。

      此外,如果您大量使用NumPy、Pandas或其他數(shù)據(jù)科學(xué)包,那么有幾個(gè)選項(xiàng)可能對(duì)您有用:

      NumPy提供了與內(nèi)置 Pythondatetime庫(kù)類似的 API,但 NumPy 版本可以在數(shù)組中使用。

      Pandas通過(guò)使用 NumPy模塊為DataFrames 中的時(shí)間序列數(shù)據(jù)提供支持,通常是基于時(shí)間的事件的順序值datetime。

      cftime支持除公歷之外的其他日歷以及符合氣候和預(yù)測(cè) (CF) 公約的其他時(shí)間單位。xarray包使用它來(lái)提供時(shí)間序列支持。

      進(jìn)一步閱讀

      由于隨時(shí)間編程可能非常復(fù)雜,因此網(wǎng)絡(luò)上有許多資源可以幫助您了解更多相關(guān)信息。幸運(yùn)的是,這是許多使用每種編程語(yǔ)言的人都考慮過(guò)的問(wèn)題,因此您通常可以找到信息或工具來(lái)幫助解決您可能遇到的任何問(wèn)題。以下是我發(fā)現(xiàn)對(duì)編寫(xiě)本教程很有幫助的精選文章和視頻列表:

      Daylight saving time and time zone best practices

      Storing UTC is not a Silver Bullet

      How to save datetimes for future events

      Coding Best Practices Using DateTime in the .NET Framework

      Computerphile: The Problem with Time & Timezones

      The Complexity of Time Data Programming

      此外,Paul Ganssle 是 CPython 的核心貢獻(xiàn)者和dateutil.?他的文章和視頻是 Python 用戶的絕佳資源:

      Working with Time Zones: Everything You Wish You Didn’t Need to Know?(PyCon 2019)

      pytz: The Fastest Footgun in the West

      Stop using utcnow and utcfromtimestamp

      A curious case of non-transitive datetime comparison

      結(jié)論

      在本教程中,您了解了使用日期和時(shí)間進(jìn)行編程以及為什么它經(jīng)常導(dǎo)致錯(cuò)誤和混亂。您還了解了 Pythondatetime和dateutil模塊以及如何在代碼中使用時(shí)區(qū)。

      現(xiàn)在你可以:

      在您的程序中以一種面向未來(lái)的良好格式存儲(chǔ)日期

      創(chuàng)建datetime帶有格式化字符串的Python實(shí)例

      將時(shí)區(qū)信息添加到datetime實(shí)例中dateutil

      使用datetime實(shí)例執(zhí)行算術(shù)運(yùn)算relativedelta

      最后,您創(chuàng)建了一個(gè)腳本,它可以倒計(jì)時(shí)到下一次 PyCon US 的剩余時(shí)間,這樣您就可以為最大的 Python 聚會(huì)感到興奮。日期和時(shí)間可能很棘手,但是使用您的武器庫(kù)中的這些 Python 工具,您已準(zhǔn)備好解決最棘手的問(wèn)題!

      Python 大數(shù)據(jù)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:寫(xiě)給大忙人看的如何優(yōu)雅設(shè)置線程池的大小
      下一篇:apaas的產(chǎn)品有哪些(apaas和ipaas)
      相關(guān)文章
      亚洲人成无码www久久久| 日本亚洲成高清一区二区三区| 亚洲AV无码专区亚洲AV伊甸园 | 亚洲欧洲久久av| 亚洲色成人WWW永久在线观看| 亚洲一级毛片免费看| 亚洲一区二区影视| 亚洲天堂2016| 亚洲色偷精品一区二区三区| 亚洲精品动漫免费二区| 国产亚洲一卡2卡3卡4卡新区| 久久久久亚洲精品无码网址色欲 | 亚洲人成网站影音先锋播放| 亚洲va在线va天堂va四虎| 亚洲成AV人片在WWW色猫咪| 亚洲国产女人aaa毛片在线| 91亚洲国产在人线播放午夜| 亚洲国产福利精品一区二区| 狠狠色香婷婷久久亚洲精品| 亚洲乱码中文字幕在线| 色欲aⅴ亚洲情无码AV| 亚洲精品无码激情AV| 国产亚洲精品激情都市| 日本亚洲欧洲免费天堂午夜看片女人员 | 亚洲精品国产suv一区88| 国产成人+综合亚洲+天堂| 亚洲成片观看四虎永久| 久久久久亚洲AV成人网人人软件| 国产精品亚洲一区二区三区在线| 亚洲国产精品无码AAA片| 91精品国产亚洲爽啪在线影院| 亚洲制服丝袜在线播放| 亚洲欧美成人综合久久久| 午夜亚洲福利在线老司机| 亚洲中文字幕无码不卡电影 | 亚洲国产精品第一区二区| 亚洲国产日产无码精品| 亚洲成a人片在线不卡一二三区| 欧美亚洲精品一区二区| 国产精品亚洲二区在线观看| 久久精品国产亚洲av四虎|