**# Dates and Times
Date
Date Object
用numeric (double)儲存從1970-01-01到當時的日數。
> x <- as.Date("1970-01-09") #利用uncalss查看物件底層儲存的資料結構 > unclass(x) #可以看到01-01到01-09隔了8天,8用numeric儲存 [1] 8 > typeof(x) [1] "double"
Time
POSIXct object
以numeric的資料型態儲存1970-01-01到目標時間的總秒數,適合用來儲存時間的資料到檔案中。
POSIXlt object
被命名的vector list,好處在於對愚蠢的藍星動物來說比較直觀易讀。
POSIXlt內部的list結構被隱藏起來,所以用str()、print()、length等函氏無法取得正確的資料,需要經過unclass()後才看得到,像:str(unclass(POSIXlt_oject))。
以下列出常用的屬性。
| Attribute | Value | Description |
|---|---|---|
| sec | 0-61 | - |
| min | 0-59 | - |
| hour | 0-23 | - |
| mday | 1-31 | day of the month |
| mon | 0-11 | month |
| year | Current - 1970 (C.E.) | - |
| wday | 0-6 | start on Sunday (= 0) |
| yday | 0-365 | - |
| zone | Time zone abbreviation | |
| gmtoff(optional) | Integer (seconds) | ex: GMT+8就是8*3600=28800 |
#用Sys.time()取得當下系統時間
> x <- Sys.time()
> x
[1] "2017-03-05 00:32:04 CST"
> class(x)
[1] "POSIXct" "POSIXt"
#POSIXt是一個虛擬類別,POSTct和POSTlt繼承其介面,實現相互操作的可能性。
#例如直接將POSTct和POSTlt進行加/減運算,就是透過POSIXt的介面。
#以上是筆記,新手看不懂可以直接無視POSIXt的部分,記得POSTct和POSTlt可以直接加減就好。
#POSIXct的本質是numeric (double)
> typeof(x)
[1] "double"
> unclass(x)
[1] 1488645124
#POSIXct可以用str()直接拆解
> str(unclass(x))
num 1.49e+09
#現在把x變成POSIXlt
> x <- as.POSIXlt(x)
> class(x)
[1] "POSIXlt" "POSIXt"
#可以觀察到POSIlt同時也是POSIXt類別
#可以看到POSIXlt的本質是list
> typeof(x)
[1] "list"
> x
[1] "2017-03-05 00:32:04 CST"
#因為POSIXlt內的list被隱藏起來,所以無法用str()直接取得底層資訊。
> str(x)
POSIXlt[1:1], format: "2017-03-05 00:32:04"
#先unclass之後再取得list內的資訊。
> str(unclass(x))
List of 11
$ sec : num 4.41
$ min : int 32
$ hour : int 0
$ mday : int 5
$ mon : int 2
$ year : int 117
$ wday : int 0
$ yday : int 63
$ isdst : int 0
$ zone : chr "CST"
$ gmtoff: int 28800
- attr(*, "tzone")= chr [1:3] "" "CST" "CDT"
#下面演示POSIXct與POSIXlt的可相互操作
#再取一個較晚的系統時間給y
> y <- Sys.time()
> y
[1] "2017-03-05 00:46:32 CST"
#x與y不同時間,分別屬於POSIXlt、POSIXct兩個class
#但是同時又擁有POSIXt的操作介面
> class(x)
[1] "POSIXlt" "POSIXt"
> class(y)
[1] "POSIXct" "POSIXt"
#R的底層可用POSIXt的介面對兩個類別進行操作
> y - x
Time difference of 14.46741 mins
| Characteristic\Class | POSIXct | POSIXlt |
|---|---|---|
| Class | POSIXct, POSIXt |
POSIXlt, POSIXt |
| Type | numeric (double) | list |
| Remarks | return type of Sys.time() | hidden list structure |
| Usage | storage of data frame files | for human readable |
Mutual conversion (Date-time classes <=> character)
strptime()可以定義一個字串內日期與時間的文字表達格式,然後回傳一個POSIXlt,也可以進行vectorized operation。
R是依照I18N標準撰寫的語言,所以會去獲取系統的locale設定,會影響到strptime()對"日期時間格式"與"字串"之間的轉換,因此執行strptime()前必須先設定LC_TIME="C"把時間格式設定為ASCII (有興趣可以參考連結)。
#設定locale
> Sys.setlocale("LC_TIME", "C")
> x <- strptime("Sat, 5 Mar 2017 01:27:00 +0800", "%a, %d %b %Y %H:%M:%S %z")
> x
[1] "2017-03-05 01:27:00"
> class(x)
[1] "POSIXlt" "POSIXt"
> str(unclass(x))
List of 11
$ sec : num 0
$ min : int 27
$ hour : int 1
$ mday : int 5
$ mon : int 2
$ year : int 117
$ wday : int 0
$ yday : int 63
$ isdst : int 0
$ zone : chr ""
$ gmtoff: int 28800
#利用strptime2對vector進行轉換
> x <- c("Sat, 5 Mar 2017 01:27:00 +0800", "Mon, 6 Mar 2017 16:23:00 +0800")
> y <- strptime(x, "%a, %d %b %Y %H:%M:%S %z")
> y
[1] "2017-03-05 01:27:00" "2017-03-06 16:23:00"
#這個vector存著POSIXlt
> class(y)
[1] "POSIXlt" "POSIXt"
只列出"常用"替代字元對照表:
| conversion specification | format | description |
|---|---|---|
| %a | Mon-Sun | abbreviated weekday name |
| %d | 01-31 | day of the month |
| %b | Jun-Dec | abbreviated month name |
| %Y | 2017 | year (C.E.) |
| %H | 00-23 | hour |
| %M | 00-59 | minute |
| %S | 00-61 | second |
| %z | +0800 | GMT time offset |
Reference
https://www.csie.ntu.edu.tw/~r95053/samples/collection/backup/locale2.html