python中当地时间_R 与 Python 中与时间相关内容的梳理
約萬(wàn)字長(zhǎng)文預(yù)警,如果你沒時(shí)間,就不用看了,這就是一個(gè)梳理的文章,方便我后來(lái)找資料。
因?yàn)楣ぷ鞯年P(guān)系,近期需要梳理一些 Python 的知識(shí)(可能有小伙伴知道了,LI-6800 搞了個(gè)大動(dòng)作,支持 Python 編程了),首先要認(rèn)真系統(tǒng)的梳理的是關(guān)于時(shí)間和日期的處理,但本著一次也是做工作,兩次也是做工作,反正都同樣是知識(shí),二者也是密切相關(guān),所幸把 R 相關(guān)的知識(shí)也一并梳理了。
時(shí)間日期的基礎(chǔ)知識(shí)
先把經(jīng)常用到的一些時(shí)間的概念進(jìn)行一下整理。因?yàn)椴挥貌恢?#xff0c;一用嚇一跳,時(shí)間的標(biāo)準(zhǔn)、名詞、定義還真不少。
Gregorian calendar
格里高里歷,這個(gè)名字不熟悉,實(shí)際上就是標(biāo)準(zhǔn)的公立。
ISO 時(shí)間
對(duì)于我國(guó)人民來(lái)講,ISO 8601 這個(gè)標(biāo)準(zhǔn)雖然沒怎么聽過,但是實(shí)際我們一直在用,這就是我國(guó)使用的時(shí)間日期所采取的格式。年月日和時(shí)間的格式我們不再贅述,它可以作為下面項(xiàng)目的標(biāo)準(zhǔn)用法:
?日期?時(shí)間?世界調(diào)整時(shí)間(UTC)?與 UTC 有補(bǔ)償?shù)漠?dāng)期時(shí)間(如夏令時(shí))?時(shí)間和日期?時(shí)間間隔?循環(huán)的時(shí)間間隔
UT (世界時(shí))
以下是百度百科內(nèi)容
世界時(shí)UT即格林尼治平太陽(yáng)時(shí)間,是指格林尼治所在地的標(biāo)準(zhǔn)時(shí)間,也是表示地球自轉(zhuǎn)速率的一種形式。以地球自轉(zhuǎn)為基礎(chǔ)的時(shí)間計(jì)量系統(tǒng)。地球自轉(zhuǎn)的角度可用地方子午線相對(duì)于地球上的基本參考點(diǎn)的運(yùn)動(dòng)來(lái)度量。為了測(cè)量地球自轉(zhuǎn),人們?cè)诘厍蛏线x取了兩個(gè)基本參考點(diǎn):春分點(diǎn)(見分至點(diǎn))和平太陽(yáng)點(diǎn),由此確定的時(shí)間分別稱為恒星時(shí)和平太陽(yáng)時(shí)。
UTC 時(shí)間
UTC 是一個(gè)時(shí)間標(biāo)準(zhǔn),以下是百度百科內(nèi)容
國(guó)際原子時(shí)的準(zhǔn)確度為每日數(shù)納秒,而世界時(shí)的準(zhǔn)確度為每日數(shù)毫秒。許多應(yīng)用部門要求時(shí)間系統(tǒng)接近世界時(shí)UT,對(duì)于這種情況,一種稱為協(xié)調(diào)世界時(shí)的折衷時(shí)標(biāo)于1972年面世。為確保協(xié)調(diào)世界時(shí)與世界時(shí)相差不會(huì)超過0.9秒,在有需要的情況下會(huì)在協(xié)調(diào)世界時(shí)內(nèi)加上正或負(fù)閏秒。因此協(xié)調(diào)世界時(shí)與國(guó)際原子時(shí)之間會(huì)出現(xiàn)若干整數(shù)秒的差別,兩者之差逐年積累,便采用跳秒(閏秒)的方法使協(xié)調(diào)時(shí)與世界時(shí)的時(shí)刻相接近,其差不超過1s。它既保持時(shí)間尺度的均勻性,又能近似地反映地球自轉(zhuǎn)的變化。中國(guó)大陸、中國(guó)香港、中國(guó)澳門、中國(guó)臺(tái)灣、蒙古國(guó)、新加坡、馬來(lái)西亞、菲律賓、西澳大利亞州的時(shí)間與UTC的時(shí)差均為+8,也就是UTC+8。
也就是他的確定有兩大核心要素:
?International Atomic Time (TAI):簡(jiǎn)單了講就是用 400 個(gè)高精原子時(shí)鐘的輸出結(jié)果,作為我們使用時(shí)鐘追蹤的標(biāo)準(zhǔn)。?Universal Time (UT): 指的是地球自轉(zhuǎn)一周的時(shí)間。
unix time
unix 時(shí)間又被成為 Epoch 時(shí)間,POSIX 時(shí)間,特征十分明顯,記錄自1970年1月1日起已經(jīng)過多少秒 00:00:00 的協(xié)調(diào)世界時(shí)(UTC),減去閏秒(“閏秒,是指為保持協(xié)調(diào)世界時(shí)接近于世界時(shí)時(shí)刻,由國(guó)際計(jì)量局統(tǒng)一規(guī)定在年底或年中(也可能在季末)對(duì)協(xié)調(diào)世界時(shí)增加或減少1秒的調(diào)整。)。
每天被視為完全包含86 400秒,所以從紀(jì)元開始減去閏秒。所以我們看到 LI-6800 有一列時(shí)間很奇怪,現(xiàn)在看來(lái)那沒什么好奇怪的,因?yàn)榫嚯x 1970 年,換算成秒已經(jīng)很久遠(yuǎn)了,在手冊(cè)里也寫到了,這是 Epoch time,因?yàn)?LI-6800 基于 BSD。
至于為什么會(huì)用這么奇怪的時(shí)間格式,根本原因就是這玩意對(duì)計(jì)算機(jī)太友好了,不用為了不同的時(shí)間格式轉(zhuǎn)換來(lái)轉(zhuǎn)換去,匹配了才能計(jì)算時(shí)間,雖然對(duì)人類不太友好。但如果我們知道是 unix 時(shí)間,那么很多軟件轉(zhuǎn)換它也就是一行代碼而已。
夏令時(shí)
我直接復(fù)制百度百科的內(nèi)容:
夏令時(shí),表示為了節(jié)約能源,人為規(guī)定時(shí)間的意思。也叫夏時(shí)制,夏時(shí)令(Daylight Saving Time:DST),又稱“日光節(jié)約時(shí)制”和“夏令時(shí)間”,在這一制度實(shí)行期間所采用的統(tǒng)一時(shí)間稱為“夏令時(shí)間”。一般在天亮早的夏季人為將時(shí)間調(diào)快一小時(shí),可以使人早起早睡,減少照明量,以充分利用光照資源,從而節(jié)約照明用電。
我覺得這就是自欺欺人的玩意,你想節(jié)約能源,讓人早睡早起的話,直接下令早起一小時(shí)就好了,何必非得折騰時(shí)間呢?反正都是早睡早起,哪有這么多切換時(shí)間的麻煩,還好我國(guó)已經(jīng)廢止了。現(xiàn)在美帝還有這些事,我們應(yīng)該沒機(jī)會(huì)處理這堆爛事。
GMT 時(shí)間
GMT 也就是我們所熟悉的格林威治時(shí)間,在 1972 年以前,它是一個(gè)時(shí)間標(biāo)準(zhǔn),在那之后,他就僅僅指它所在的地方的時(shí)區(qū)。所以我們應(yīng)該幾乎不會(huì)再處理這種格式的數(shù)據(jù)了。
時(shí)區(qū)
這看上去是最好理解的概念,但實(shí)際上又不然,一幅圖可以展示所有時(shí)區(qū):
但我覺得需要注意的有下面幾點(diǎn):
1.當(dāng)?shù)貢r(shí)間與 UTC 有差異,比如我們常見到的我們這邊的時(shí)間 UTC+8,因?yàn)槲覀冊(cè)跂|八區(qū)嘛。2.如果嚴(yán)格的按照經(jīng)度 15° 來(lái)算,應(yīng)為 24 個(gè)時(shí)區(qū),但是人類世界從來(lái)不會(huì)這么簡(jiǎn)單的遵循科學(xué)的規(guī)律,我們要考慮政治邊界等因素,所以,數(shù)量要遠(yuǎn)高于 24.3.另一個(gè)是夏令時(shí),我覺得很虛偽的做法,遠(yuǎn)不如行政命令,簡(jiǎn)化時(shí)間算法來(lái)的直接。4.另一個(gè)是所在地區(qū)的時(shí)間未必與時(shí)區(qū)相同,這個(gè)也是無(wú)解的。例如,新疆應(yīng)該屬于東六區(qū),但就是習(xí)慣用東八區(qū)計(jì)時(shí)。
CST
CST 是很常見的一個(gè)縮寫,以下抄襲自百度百科:
CST可以為如下4個(gè)不同的時(shí)區(qū)的縮寫:
?美國(guó)中部時(shí)間:Central Standard Time (USA) UT-6:00?澳大利亞中部時(shí)間:Central Standard Time (Australia) UT+9:30?中國(guó)標(biāo)準(zhǔn)時(shí)間:China Standard Time UT+8:00?古巴標(biāo)準(zhǔn)時(shí)間:Cuba Standard Time UT-4:00
我們說(shuō)的自然是指? UTC+8 的時(shí)間。
R 日期與時(shí)間
從這里進(jìn)入正式的處理,這里梳理的目的不是做到面面俱到,只是期望有一個(gè)思路,有問題也方便查找。
日期
日期最常用的轉(zhuǎn)換就是文字轉(zhuǎn)換為日期,有幾種方法
as.Date
作為 base R 的基本函數(shù),as.Date?的作用就是將字符轉(zhuǎn)換為日期類。對(duì)于儀器類的時(shí)間日期,它其中非常有用的參數(shù)是?format,但它又牽扯到?strptime,我們通過例子查看:
# 前三行后面解釋lct Sys.getlocale("LC_TIME")Sys.setlocale("LC_TIME", lct)Sys.setlocale("LC_TIME", "C")# 這類儀器的時(shí)間日期還能接受x "1jan1960", "2jan1960", "31mar1960", "30jul1960")z as.Date(x, "%d%b%Y")z# 這類儀器的廠家簡(jiǎn)直就沒有國(guó)際視野x "02/27/19", "02/27/19", "01/14/19", "02/28/19", "02/01/19")z as.Date(x, "%m/%d/%y")z# 這不管公司大小,至少是有估計(jì)視野的# 如果需要日期計(jì)算,我們就將字符轉(zhuǎn)換文字就行y "2019-12-31", "2020-1-1", "2020-1-2")y## [1] "Chinese (Simplified)_China.936"## [1] "C"## [1] "1960-01-01" "1960-01-02" "1960-03-31" "1960-07-30"## [1] "2019-02-27" "2019-02-27" "2019-01-14" "2019-02-28" "2019-02-01"## [1] "2019-12-31" "2020-1-1" "2020-1-2"這個(gè)代碼本身非常簡(jiǎn)單,除了下面要解釋的兩點(diǎn)(其實(shí)本質(zhì)上就是?strptime?一點(diǎn)):
?format?參數(shù)中這些帶 % 號(hào)的字符來(lái)自于?POSIX?標(biāo)準(zhǔn),在 R 和 Python內(nèi)都是一樣的符號(hào),即使用 % + 字母,來(lái)規(guī)定時(shí)間與日期的格式,有需要查閱??strptime
?在?Sys.setlocale?中使用 "C",以及 "LC_TIME",幫助文檔有解釋:
Locale-specific conversions to and from character strings are used where appropriate and available. This affects the names of the days and months, the AM/PM indicator (if used) and the separators in output formats such as %x and %X, via the setting of the LC_TIME locale category. The ‘current locale’ of the descriptions might mean the locale in use at the start of the R session or when these functions are first used. (For input, the locale-specific conversions can be changed by calling Sys.setlocale with category LC_TIME (or LC_ALL). For output, what happens depends on the OS but usually works.)
也就是說(shuō)我們使用格式帶有某些字符,如上面的 Jan 等,以及與系統(tǒng)的區(qū)域語(yǔ)言設(shè)置相關(guān)的輸出格式,可以通過使用設(shè)置 LC_TIME,輸出的結(jié)果依賴于我們系統(tǒng)的設(shè)置。
有點(diǎn)拗口,直接的從結(jié)果上來(lái)將會(huì)比較容易,那就是代碼命名沒問題,結(jié)果輸出的結(jié)果是 NA,那就要考慮是不是沒有按照上面的區(qū)域時(shí)間日期的設(shè)置來(lái)更改。這是系統(tǒng)之間和不同地區(qū)之間最令人頭疼的區(qū)域語(yǔ)言設(shè)置問題。
另外設(shè)置為 C 則是關(guān)閉特定區(qū)域的順序,幫助文檔里也有:
Sys.setlocale("LC_TIME", "C") # turn off locale-specific sorting, # usually (but not on all platforms)所有的區(qū)域語(yǔ)言設(shè)置,目的均是為實(shí)現(xiàn)我們上面代碼輸出的不是 NA,如果不信邪,國(guó)內(nèi)多數(shù)人用的電腦應(yīng)該前兩個(gè)例子的代碼都為 NA。至于標(biāo)準(zhǔn)的 ISO 8601 數(shù)據(jù),至少對(duì)我們區(qū)域語(yǔ)言設(shè)置選擇中文的 Windows 電腦是非常友好的。
日期的差
在實(shí)際應(yīng)用過程中,時(shí)間的差值計(jì)算非常多,在 R base 中也有很多方法計(jì)算:
例如,你的小學(xué)數(shù)學(xué)沒學(xué)好,又想學(xué)偶像劇搞浪漫,要告訴女友在你們相戀的第 n 天的感受,那么你可以這樣做:
Sys.Date() - as.Date("2009-01-18")## Time difference of 4101 days更浪漫的精確到 s:
difftime(Sys.time(), strptime("2009-01-18 15:20:22", "%Y-%m-%d %H:%M:%S"), units = "secs")## Time difference of 354312449 secs當(dāng)然,第二條要求你要有驚人的記憶力,或者一個(gè)好筆頭,如果連天都精確不到,這說(shuō)明你沒什么求生欲,我也拯救不了你。
某個(gè)時(shí)間點(diǎn)以后第 n 天是哪一天:
as.Date(329, origin = "2019-12-01")## [1] "2020-10-25"日期與時(shí)間
上面的內(nèi)容是日期,相比來(lái)說(shuō),只處理日期的應(yīng)用情形比較少,因?yàn)槲覀兊膬x器的采集頻率都非常高,一般都是高于 1 Hz 的,所以多數(shù)據(jù)情況下我們都要日期和時(shí)間一起處理,下面我們看一下日期與時(shí)間(當(dāng)然為使得內(nèi)容不是那么的無(wú)聊,日期上我們稍微加了一個(gè)時(shí)間的內(nèi)容,實(shí)際上應(yīng)該讓單位?units = days?才符合上一節(jié)的標(biāo)題)。
日期與時(shí)間處理的軟件包
R base 中的?POSIXt,chron,lubridate?都是很多人常用的工具,data.table?中的?IDateTime?主要偏重于速度,而且處于實(shí)驗(yàn)版本,不做介紹。
POSIXt
POSIXt 是 R 的一個(gè)類,又分為 "POSIXlt" 和 "POSIXct"。與此相關(guān)的函數(shù)有:
?as.POSIXct?as.POSIXlt?strptime
這三個(gè)函數(shù)有令人很容易迷惑混淆的地方,但是 stackoverflow 總是個(gè)能讓人答疑解惑的地方:
First, there are two internal implementations of date/time: POSIXct, which stores seconds since UNIX epoch (+some other data), and POSIXlt, which stores a list of day, month, year, hour, minute, second, etc.
strptime?is a function to directly convert character vectors (of a variety of formats) to POSIXlt format.
as.POSIXlt?converts a variety of data types to POSIXlt. It tries to be intelligent and do the sensible thing - in the case of character, it acts as a wrapper to strptime.
as.POSIXct?converts a variety of data types to POSIXct. It also tries to be intelligent and do the sensible thing - in the case of character, it runs strptime first, then does the conversion from POSIXlt to POSIXct.
簡(jiǎn)單的說(shuō)就是?as.POSIXlt?中 lt 指的是 local time,存儲(chǔ)的是我們年月日星期等的屬性,as.POSIXct?中 ct 指的是 calendar time,存儲(chǔ)的是自 1970 年 1 月 1 日 0 時(shí)開始的秒數(shù)。
查看其屬性我們就能直觀的看到他們的差別:
x as.POSIXlt(Sys.time())y as.POSIXct(Sys.time())attributes(x)attributes(y)x$mday#y$mday## $names## [1] "sec" "min" "hour" "mday" "mon" "year" "wday" "yday"
## [9] "isdst" "zone" "gmtoff"
##
## $class
## [1] "POSIXlt" "POSIXt"
##
## $tzone
## [1] "" "CST" "CDT"## $class
## [1] "POSIXct" "POSIXt"
## [1] 11
## [1]?Error in y$mday : $ operator is invalid for atomic vectors
格式的問題
時(shí)間與日期格式的多變性是處理很多儀器數(shù)據(jù)時(shí)的麻煩事情,我覺得兩個(gè)很重要的函數(shù)能幫我們解決大部分問題。
?format
# 24h - 12 h 的轉(zhuǎn)換as.POSIXlt("2020-03-08 10:11:01 PM", format = "%Y-%m-%d %I:%M:%S %p")# 轉(zhuǎn)換格式format(as.POSIXlt("08/04/06 22:11:00", format = "%m/%d/%y %H:%M:%S"), "%Y-%m-%d %H:%M:%S")## [1] "2020-03-08 22:11:01 CST"
## [1] "2006-08-04 22:11:00"?strptime
strptime("08/04/06 22:11:00", format = "%m/%d/%y %H:%M:%S")## [1] "2006-08-04 22:11:00 CST"對(duì)于我們使用 ISO 8601 的國(guó)家來(lái)講,默認(rèn)的輸出不用更改就是我們喜歡的格式。
DST
夏令時(shí)是我討厭的東西,在我國(guó)的儀器也沒這玩意,所以不討論。我沒查怎么處理,我覺得最簡(jiǎn)單的方法就是把時(shí)間加 1 h 就可以了。
時(shí)區(qū)
時(shí)區(qū)問題在我們國(guó)內(nèi)基本也不會(huì)遇到,因?yàn)槲覀兌歼m用一個(gè)時(shí)區(qū)的時(shí)間,但如果使用 gps 時(shí)鐘,遇到了時(shí)區(qū)錯(cuò)誤的問題,也可以通過指定 tz 方便的解決,例如,我們?cè)?UTC +8,但是 GPS 時(shí)鐘把我們搞成了 UTC+3,我們可以直接加上 5 個(gè)小時(shí)就可以修正這個(gè)錯(cuò)誤了。
df "2020-3-8 18:12:12", "2020-3-8 18:13:12", "2020-3-8 18:14:12"))df$tz3 as.POSIXct(df$tz3)df$tz8 5*60*60df$tz8## [1] "2020-03-08 23:12:12 CST" "2020-03-08 23:13:12 CST"## [3] "2020-03-08 23:14:12 CST"
lubridate
lubridate?最大的優(yōu)勢(shì)是使得時(shí)間處理起來(lái)更容易了,函數(shù)名更容易記住:
例如將字符轉(zhuǎn)為時(shí)間日期不需要指定格式:
library(lubridate)ymd("20101215")mdy("4/1/17")ymd_hms("20200314 17:01:05")## [1] "2010-12-15"## [1] "2017-04-01"## [1] "2020-03-14 17:01:05 UTC"上文提到的時(shí)間錯(cuò)誤很容易直接更改時(shí)區(qū)解決,
df "2020-3-8 18:12:12", "2020-3-8 18:13:12", "2020-3-8 18:14:12"))df$tz3 "Antarctica/Syowa")df$tz3df$tz8 "Asia/Shanghai")df$tz8## [1] "2020-03-08 18:12:12 +03" "2020-03-08 18:13:12 +03"## [3] "2020-03-08 18:14:12 +03"## [1] "2020-03-08 23:12:12 CST" "2020-03-08 23:13:12 CST"
## [3] "2020-03-08 23:14:12 CST"
當(dāng)然,如果你不知道哪是 UTC +3,哪是 UTC +8,有一個(gè)很好的網(wǎng)站 (https://timezonedb.com/time-zones)[https://timezonedb.com/time-zones]。更多用法參考 (R for Data Science)[https://r4ds.had.co.nz/dates-and-times.html] 時(shí)間日期的章節(jié),不贅述
chron
chron?是 chronological 的縮寫,顧名思義是按時(shí)間發(fā)生順序排列的。
chron?函數(shù)
用于產(chǎn)生時(shí)間序列的對(duì)象:
library(chron)dts "2020/02/20", "2020/02/21", "2020/03/1","2020/03/2", "2020/03/10"), format="y/m/d")dtstms "23:03:20", "22:29:56", "01:03:30","18:21:03", "16:56:26"))tmsx xattributes(x)## [1] 02/20/20 02/21/20 03/01/20 03/02/20 03/10/20## [1] 23:03:20 22:29:56 01:03:30 18:21:03 16:56:26## [1] (02/20/20 23:03:20) (02/21/20 22:29:56) (03/01/20 01:03:30)## [4] (03/02/20 18:21:03) (03/10/20 16:56:26)## $format
## dates times
## "m/d/y" "h:m:s"
##
## $origin
## month day year
## 1 1 1970
##
## $class
## [1] "chron" "dates" "times"
生成了一個(gè)時(shí)間序列,不過日期的格式不那么讓人喜歡。不過他支持時(shí)間直接從 day 加減:
dts[1]+2dts[1]+33dts[1]-99diff(x)## [1] 02/22/20## [1] 03/24/20## [1] 11/13/19## Time in days:## [1] 0.9768056 8.1066435 1.7205208 7.9412384
結(jié)果也是以天來(lái)計(jì)算,有時(shí)候很方便。還可以直接按給定的標(biāo)簽返回日期的歸屬:
cut(dates("02/01/20") + 18:25, "weeks")dts "02/01/20")+ seq(5, 105, 15)dtscut(dts, "months")## [1] week 1 week 1 week 1 week 1 week 1 week 2 week 2 week 2## Levels: week 1 < week 2## [1] 02/06/20 02/21/20 03/07/20 03/22/20 04/06/20 04/21/20 05/06/20## [1] Feb 20 Feb 20 Mar 20 Mar 20 Apr 20 Apr 20 May 20
## Levels: Feb 20 < Mar 20 < Apr 20 < May 20
總而言之,恕我愚鈍,我感覺這個(gè)包沒太大用處。
python 時(shí)間日期
Python 的官方文檔寫的很好,歸納了掌握 Python 時(shí)間日期處理的四大殺器:datetime, calendar, time, dateutil。我們從牽扯到最開始基本知識(shí)的?time?開始,它提供了一系列的與時(shí)間處理相關(guān)的函數(shù),然后簡(jiǎn)單介紹一下?calendar,著重介紹一下?datetime?和?dateutil,因?yàn)楹髢烧卟攀俏覀冾l繁要用的,前面兩個(gè)也只是后面的基礎(chǔ)。另外,據(jù)說(shuō)?pytz?處理時(shí)區(qū)要比?datetime?自帶的好用多了。
time
time?比較特殊,有些函數(shù)是分系統(tǒng)的,并不是所有函數(shù)都一定在電腦上有效,他們的官方文檔里會(huì)專門標(biāo)注:avalability:unix 的字樣,以提醒我們 win 下用不了。簡(jiǎn)單看一下幾個(gè)常用的函數(shù):
?ctime?將 s 轉(zhuǎn)換為英語(yǔ)國(guó)家喜歡的時(shí)間日期(還是 1970.1.1 為基準(zhǔn)),如果不加參數(shù)返回當(dāng)前時(shí)間:
from time import*ctime(888888)ctime()## 'Sun Jan 11 14:54:48 1970'## 'Sat Apr 11 11:27:52 2020'?gmtime?將自基準(zhǔn)日期的 s 轉(zhuǎn)換為 UTC 時(shí)間。
gmtime(888888)## time.struct_time(tm_year=1970, tm_mon=1, tm_mday=11, tm_hour=6, tm_min=54, tm_sec=48, tm_wday=6, tm_yday=11, tm_isdst=0)?當(dāng)然,如果格式不滿意,time?也有?strptime strftime,和 R 一樣都遵循相同的標(biāo)準(zhǔn),這里摘抄一下官方文檔,就不再制作表格了:
%a | Locale’s abbreviated weekday name. | |
%A | Locale’s full weekday name. | |
%b | Locale’s abbreviated month name. | |
%B | Locale’s full month name. | |
%c | Locale’s appropriate date and time representation. | |
%d | Day of the month as a decimal number [01,31]. | |
%H | Hour (24-hour clock) as a decimal number [00,23]. | |
%I | Hour (12-hour clock) as a decimal number [01,12]. | |
%j | Day of the year as a decimal number [001,366]. | |
%m | Month as a decimal number [01,12]. | |
%M | Minute as a decimal number [00,59]. | |
%p | Locale’s equivalent of either AM or PM. | (1) |
%S | Second as a decimal number [00,61]. | (2) |
%U | Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. | (3) |
%w | Weekday as a decimal number [0(Sunday),6]. | |
%W | Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. | (3) |
%x | Locale’s appropriate date representation. | |
%X | Locale’s appropriate time representation. | |
%y | Year without century as a decimal number [00,99]. | |
%Y | Year with century as a decimal number. | |
%z | Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59]. | |
%Z | Time zone name (no characters if no time zone exists). | |
%% | A literal?‘%’?character. |
通過上面的例子我們已經(jīng)可以看出,time?所謂的 UTC 格式并不是那么友好,他們屬于?struct_time?類, 雖然我們能猜出其中的含義來(lái),但是這里也列一下,算作備忘:
0 | tm_year | (for example, 1993) |
1 | tm_mon | range [1, 12] |
2 | tm_mday | range [1, 31] |
3 | tm_hour | range [0, 23] |
4 | tm_min | range [0, 59] |
5 | tm_sec | range [0, 61]; see?(2)?in?strftime()?description |
6 | tm_wday | range [0, 6], Monday is 0 |
7 | tm_yday | range [1, 366] |
8 | tm_isdst | 0, 1 or -1; see below |
N/A | tm_zone | abbreviation of timezone name |
N/A | tm_gmtoff | offset east of UTC in seconds |
也有時(shí)區(qū)相關(guān)設(shè)置,我們放在后面的內(nèi)容內(nèi)。
calendar
calendar?提供給我們與日歷相關(guān)的模塊,例如星期,默認(rèn)是從周一開始作為,周日作為結(jié)束,當(dāng)然可以使用?setfirstweekday()?來(lái)修改。我覺得和我們儀器數(shù)據(jù)的處理相關(guān)不大,我們簡(jiǎn)單看一下其中的一個(gè)函數(shù),就明白了,它處理的內(nèi)容,一般儀器都不這么顯示:
from calendar import day_namefor i in day_name:print("today is ", i)## today is Monday## today is Tuesday
## today is Wednesday
## today is Thursday
## today is Friday
## today is Saturday
## today is Sunday
datetime
這應(yīng)該是 Python 中使用最廣泛的時(shí)間日期處理了,雖然感覺它處理的的方式有些別扭,但還是包含了我們所需要的常用的功能,datetime?有兩個(gè)名字挺奇怪的對(duì)象,按照我的理解(當(dāng)然不一定對(duì),我看官方文檔解釋的挺繁瑣的):
?aware,該類包含的信息很全,包括算法上的和政治時(shí)間上的調(diào)整,例如時(shí)區(qū)和 DST。也就是說(shuō)該類對(duì)象能夠這么應(yīng)用:我可以通過該類對(duì)象包含的時(shí)區(qū),換算為其他的時(shí)區(qū)的時(shí)間,也能夠換算稱準(zhǔn)確的 unix 時(shí)間的秒。?naive,也就是說(shuō)沒有包含相關(guān)的時(shí)間信息,僅僅是一個(gè)時(shí)間。類似于 1 后面可以是 mm,m 或者 km,完全取決于使用者。如果不牽扯到時(shí)間轉(zhuǎn)換,使用該類應(yīng)該是非常方便的。
我們用簡(jiǎn)單的例子來(lái)看一下它的基本用法:
from datetime import datetime# 將字符轉(zhuǎn)換為日期并提取信息str_today = "2020-3-21"today = datetime.strptime(str_today, "%Y-%m-%d")today.monthtoday.day## 3## 21對(duì)我們來(lái)講,提取月和日用到的不多,但是將 unix 時(shí)間和正常時(shí)間的互換用到的地方就多了。
# 當(dāng)前時(shí)間日期now = datetime.now()datetime.timestamp(now)dt_stamp = 1234354353.1999datetime.fromtimestamp(dt_stamp)## 1586575672.42083## datetime.datetime(2009, 2, 11, 20, 12, 33, 199900)需要經(jīng)常計(jì)算的時(shí)間差,例如上文時(shí)區(qū)給搞錯(cuò)的例子,我們可以使用 timedelta 搞定:
from datetime import timedeltautc3_time = datetime.strptime("2020-3-21 9:10:30", "%Y-%m-%d %H:%M:%S")utc8_time = utc3_time + timedelta(hours = 5)utc8_time## datetime.datetime(2020, 3, 21, 14, 10, 30)當(dāng)然?python?也可以浪漫的對(duì)紀(jì)念日直接計(jì)算
date_from = datetime(2009, 1, 18, 15, 20, 22)now = datetime.now()now - date_from## datetime.timedelta(4100, 72450, 475784)如果非要處理時(shí)區(qū),可以使用?pytz(這不是我說(shuō)的)。我們用它來(lái)添加更改時(shí)區(qū):
from pytz import timezoneutc8 = timezone("Asia/Shanghai")bj_time = utc8.localize(datetime(2020, 3, 21, 20, 45, 10))bj_time# 轉(zhuǎn)換為美國(guó)東部時(shí)間east_us = timezone("US/Eastern")bj_time.astimezone(east_us)## datetime.datetime(2020, 3, 21, 20, 45, 10, tzinfo=)dateutil
dateutil?將自己定義為?datetime?的擴(kuò)展,特別需要注意的是,他的安裝為
pip install python-dateutil# 或conda install python-dateutil而它處理起日期和時(shí)間來(lái)確實(shí)非常方便,我們只介紹比較重要的幾個(gè)模塊。
parser
parser?的目的在于直接處理一系列的雜亂的日期格式,而得到我們所需要的格式。也就是簡(jiǎn)化我們要操作的識(shí)別的步驟:
from dateutil.parser import*from dateutil.tz import*from datetime import*TZOFFSETS = {"CST": +28800}DEFAULT = datetime(2020, 4, 10)parse("Thu Apr 10 10:36:28 CST 2020", tzinfos=TZOFFSETS)parse("Thu Apr 10 10:36:28 CST 2020", tzinfos=TZOFFSETS)parse("2020 10:36:28 CST 25 Apr Thu", tzinfos=TZOFFSETS)# 當(dāng)然可以忽略時(shí)區(qū),多數(shù)情況下我們也不需要處理時(shí)區(qū)parse("Thu Apr 10 10:36:28 CST 2020", ignoretz=True)# 如果沒有年,我們可以提供一個(gè)默認(rèn)的選項(xiàng),這在處理# 只有時(shí)間的數(shù)據(jù)時(shí)非常有幫助,或者說(shuō)我們可以不用合并# 數(shù)據(jù)里的日期和時(shí)間,只用時(shí)間列,并給其設(shè)定一個(gè)默認(rèn)# 值即可parse("Thu Sep 25 10:36:28", default=DEFAULT)# 對(duì) ISO 格式的解析葉室毫無(wú)壓力parse("2019-09-25T10:49:41")parse("2019-09-25T10:49:41.5-03:00")## datetime.datetime(2020, 4, 10, 10, 36, 28, tzinfo=tzoffset('CST', 28800))## datetime.datetime(2020, 4, 10, 10, 36, 28, tzinfo=tzoffset('CST', 28800))## datetime.datetime(2020, 4, 25, 10, 36, 28, tzinfo=tzoffset('CST', 28800))## datetime.datetime(2020, 4, 10, 10, 36, 28)## datetime.datetime(2020, 9, 25, 10, 36, 28)## datetime.datetime(2019, 9, 25, 10, 49, 41)## datetime.datetime(2019, 9, 25, 10, 49, 41, 500000, tzinfo=tzoffset(None, -10800))parser?的形式為:parser.parse(parserinfo=None, **kwargs),上面的例子中使用了?**kwargs?的?tzinfos?選項(xiàng),可以提供一個(gè)時(shí)區(qū)名或別名,例如上面我們使用的 CST,在我們看來(lái)是中國(guó)標(biāo)準(zhǔn)時(shí)間,具體的時(shí)區(qū)名縮寫可參考: https://www.timeanddate.com/time/zones/,該參數(shù)還可以提供一個(gè)時(shí)區(qū)的 offsets(以秒計(jì)量的),這就是我們上面解析的前兩個(gè)日期的目的,轉(zhuǎn)換為標(biāo)準(zhǔn)的時(shí)區(qū)。
rrule
rrule?是名副其實(shí)的時(shí)間尺,可以生成一系列不同尺度的時(shí)間序列:
from dateutil.rrule import*from dateutil.parser import*from datetime import*import pprintimport syssys.displayhook = pprint.pprint# 從起始時(shí)間開始的 3 天的時(shí)間list(rrule(DAILY, count=3, dtstart=parse("20200401T090000")))# 有截止日期的時(shí)間序列l(wèi)ist(rrule(DAILY, dtstart=parse("20200401T090000"), until=parse("20200405T000000")))list(rrule(DAILY, interval=2, count=5, dtstart=parse("20200405T090000")))## [datetime.datetime(2020, 4, 1, 9, 0),## datetime.datetime(2020, 4, 2, 9, 0),
## datetime.datetime(2020, 4, 3, 9, 0)]## [datetime.datetime(2020, 4, 1, 9, 0),
## datetime.datetime(2020, 4, 2, 9, 0),
## datetime.datetime(2020, 4, 3, 9, 0),
## datetime.datetime(2020, 4, 4, 9, 0)]## [datetime.datetime(2020, 4, 5, 9, 0),
## datetime.datetime(2020, 4, 7, 9, 0),
## datetime.datetime(2020, 4, 9, 9, 0),
## datetime.datetime(2020, 4, 11, 9, 0),
## datetime.datetime(2020, 4, 13, 9, 0)]
relativedelta
relativedelta?的設(shè)計(jì)是用于替代已有的時(shí)間日期的特定組分或者表示時(shí)間的間隔:
from datetime import*from dateutil.relativedelta import*import calendarnow = datetime.now()today = date.today()nowdatetime(2019, 9, 17, 20, 54, 47, 282310)todaydate(2019, 9, 17)# 解決上文的 utc+3 和 utc+8 的問題now+relativedelta(hours=+5)# 可以指定月,軸,以及小時(shí),注意不是賦值的話必須有正負(fù)號(hào)today+relativedelta(months=+1, weeks=+1, hour=10)# 可以直接顯示日期差relativedelta(datetime(2009, 1, 18, 16, 0), today)## datetime.datetime(2020, 4, 11, 11, 27, 52, 774166)## datetime.datetime(2019, 9, 17, 20, 54, 47, 282310)## datetime.date(2020, 4, 11)## datetime.date(2019, 9, 17)## datetime.datetime(2020, 4, 11, 16, 27, 52, 774166)## datetime.datetime(2020, 5, 18, 10, 0)## relativedelta(years=-11, months=-2, days=-23, hours=-8)本文屬于整理相關(guān)有用的軟件包和基礎(chǔ)信息,并非學(xué)習(xí)使用,具體用法還請(qǐng)看各個(gè)軟件包的幫助文檔。關(guān)于 R 和 Python 的時(shí)間處理,常用的就是這些內(nèi)容。
參考資料
https://docs.python.org/3/library/datetime.htmlhttps://dateutil.readthedocs.io/en/latest/Grolemund, Garrett, and Hadley Wickham. 2011. “Dates and Times Made Easy with lubridate.”?Journal of Statistical Software?40 (3): 1–25.?http://www.jstatsoft.org/v40/i03/.James, David, and Kurt Hornik. 2020.?Chron: Chronological Objects Which Can Handle Dates and Times.?https://CRAN.R-project.org/package=chron.R Core Team. 2020.?R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing.?https://www.R-project.org/.總結(jié)
以上是生活随笔為你收集整理的python中当地时间_R 与 Python 中与时间相关内容的梳理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea 导出war包_使用IDEA实现
- 下一篇: java 短路判断_java中和的区别(