R語言的基礎包中提供了三種基本類型用於處理日期和時間,Date用於處理日期,它不包括時間和時區信息;POSIXct/POSIXlt用於處理日期和時間,其中包括了日期、時間和時區信息。R內部在存儲日期和時間時,使用不同的方式:
- Date類:存儲了從1970年1月1日以來開始計算的天數,更早的日期表示為負值,也就是說,Date類型是一個整數,以天為單位來計算日期,因此,Date適合用於計算日期。
- POSIXct類:記錄了以時間標准時間(UTC)時區位准的,從1970年1月1日開始計時的秒數,即,POSIXct類型是整數,以秒為單位來計算時間,因此,POSIXct最適合用於存儲和計算時間。
- POSIXlt類:把日期和時間存儲為一個列表,其中包括秒、分、時和月份等,POSIXlt是使用列表來表示日期和時間,因此,POSIXlt最適合用於提取日期中的特定部分。
一般來講,R語言中創建的時間數據是通過字符型轉化而來,字符串和時間類型無法隱式轉換,必須通過相應的函數來類解析文本。
一,系統當前的日期和時間
在編程中,為了獲得當前的日期和時間,有兩個常用的函數,這兩個函數以Sys開頭,返回的時間受到操作系統區域設置的影響,因此,返回的時間采用本地格式,符合本地的閱讀習慣:
> Sys.Date() [1] "2018-05-07" > Sys.time() [1] "2018-05-07 22:11:45 CST"
R還有一個函數date(),用於返回當前時間對應的文本,只不過格式比較奇葩:
> date() [1] "Tue May 08 11:32:52 2018"
二,把文本解析成日期和時間
日期值通常以文本的形式輸入到R中,然后轉化為以數值形式存儲的日期變量。而日期需要轉換為文本,才方便讀取。
1, as.Date() 把文本轉換為日期
函數 as.Date()用於把文本轉換為Date類型:
as.Date(x, format)
format參數用於指定輸入的格式,常用的日期格式符號是:
- %y:兩位數字表示的年份(00-99),不帶世紀,例如,數值是18,格式%y,表示2018年
- %Y:四位數字表示的年份(0000-9999)
- %m:兩位數字的月份,取值范圍是01-12,或1-12
- %d:月份中的天,取值范圍是01-31
- %e:月份中的天,取值范圍是1-31
- %b:縮寫的月份(Jan、Feb、Mar等)
- %B:英語月份全名(January、February 、March等)
- %a:縮寫的星期名(Mon、Tue、Wed、Thur、Fri、Sat、Sun)
- %A:星期全名
例如,把一個向量中的字符元素轉換為日期類型:
as.Date(c('2018-05-01','2018-05-05'),'%Y-%m-%d')
2,strptime() 解析日期
函數strptime(),是string parse time的簡稱,返回POSIXlt日期。在解析日期時,必須指定文本和日期對應的位置,日期的格式使用%+字母來指定。
format(x, format = "", tz = "")
參數tz是時區(time zone),默認值是空,在解析時,如果不指定時區,R會調用Sys.timezone
日期格式和format()函數相同,常用的時間格式符號是:
- %H:小時(24小時制)
- %I:小時(12小時制)
- %p:對於12小時制,指定上午(AM)或下午(PM)
- %M:分鍾
- %S:秒
例如,把date()函數返回的文本解析成時間類型:
> nowstr <- date() > nowtime <- strptime(nowstr,'%a %b %d %H:%M:%S %Y') > print(nowtime) [1] "2018-05-08 13:01:04 CST"
三,把日期和時間格式化為文本
把日期和時間格式化成文本,便於閱讀
1,format() 把日期轉換為文本
對日期進行格式化,轉換為可讀的文本,format()函數的定義是:
format(x, format = "", tz = "")
x是日期參數,format是輸出的格式,tz是時區,該函數按照指定的格式輸出文本:
today <- Sys.Date()
mydate <- format(today,format='%Y-%m-%d')
2,strftime()格式化日期
函數strftime(),是string formated time的簡稱,用於把時間轉換為字符串,
strptime(x, format, tz = "")
該函數和format()函數的功能和使用方式幾乎完全相同。
today <- Sys.Date() mydate <- strftime(today,format='%Y-%m-%d')
四,日期的比較
由於POSIXct類是以秒為單位來計算時間,Date類是以天為單位類計算日期,這意味着可以在日期值上執行比較運算和算術運算:
- 將數字和Date類相加,增加或減少相應的天數
- 將數字和POSIXct類相加,增加或減少相應的秒數
1,時間和數字相加
時間以秒為單位:
> time1 <- Sys.time() > print(time1) [1] "2018-05-08 13:16:36 CST" > print(time1+60*60) [1] "2018-05-08 14:16:36 CST"
日期以天為單位:
> date1 <- Sys.Date() > print(date1) [1] "2018-05-08" > print(date1+1) [1] "2018-05-09"
2,時間比較
由於Date類和POSIXct類實際上都是一個整數,可以直接比較大小
date1 <- as.Date('2018-01-01') date2 <- as.Date('2018-02-01') if (date2>date1) print ('gt')
五,lubridate包介紹
lubridate包使得日期和時間的處理更加規范,簡單和靈活。lubridate中所有解析函數都會返回POSIXct日期,默認都是用UTC時區。
lubridate包主要有兩類函數,一類是處理時點數據(time instants),另一類是處理時段數據(time spans)。
安裝和載入lubridate包:
install.packages("lubridate")
library(lubridate)
系統的當前時間now(),和Sys.time()函數返回的時間相同;系統的當前日期today(),和Sys.Date()函數返回的日期相同:
now(tzone = "") today(tzone = "")
1,從字符串轉換為日期類型
ymd() 函數用於從字符型數據解析時間,該函數會自動識別各種分隔符,函數的定義是:
ymd(..., quiet = FALSE, tz = NULL)
參數注釋:
- quiet:布爾值,當指定為TRUE時,移除文本中自定義的文本
- tz:時區,默認值是NULL
基本用法如下:
x <- ymd('2010-04-08')
而ymd代表文本的格式必須依次是:year、month、day,除了ymd之外,還有ydm、mdy、myd、dmy、dym。
2,從字符類型轉換為時間類型
ymd_hms()函數用於把文本解析為時間,該函數會自動識別各種分隔符
ymd_hms(..., quiet = FALSE, tz = "UTC")
3,抽取或設置時間的部分
- date:抽取或設置時間的日期
- year
- month
- day
- week
- hour
- minute
- second
例如,抽取當前時間的月份:
> month(t<-now()) [1] 5
例如,設置當前時間的月份為6月:
x< now() month(x) <- 6
4,時間間隔(Intervals)
時間間隔是由開始時間和結束時間構成的對象,本身用途不大,最常用於指定期間和周期:
auckland <- interval(arrive, leave) auckland #> [1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST auckland <- arrive %--% leave auckland #> [1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST
5,時間的運算
lubridata還能創建兩類對象:期間(Duration)和周期(Period),創建period的輔助函數是unit+s,創建duration的輔助函數是d+unit+s,unit是時間單位,常用的時間單位有:year、month、week、day、hour、minute和second。期間指定的時間跨度位秒的倍數,是固定的秒數。例如,一天的總時間是86 400秒(60 x 60 x 24),一年的總時間是86 400 x 365 (秒),期間類型把一年的天數固定位365天,沒有考慮閏年。周期period根據日歷來指定時間闊度,這意味着,在把周期添加到一個時間之前,period的確切的時間跨度是不固定的。例如,一年的周期可以是365天,也可以是366天,這取決於它是否是閏年。時間和日期的算術運算,跟期間和周期有關系,經常用到的是周期period類型。
常用的duration類的函數有:
duration(num = NULL, units = "seconds", ...) is.duration(x) dseconds(x = 1) dminutes(x = 1) dhours(x = 1) ddays(x = 1) dweeks(x = 1) dyears(x = 1)
常用的period類的函數有:
period(num = NULL, units = "second", ...) is.period(x) seconds(x = 1) minutes(x = 1) hours(x = 1) days(x = 1) weeks(x = 1) years(x = 1) months(x)
注意,duration類沒有dmonths()函數,可能是因為月份持續的天數十分不固定,無法指定一個固定的總時間(秒)。
例1,2分鍾的period和duration分別是:
minutes(2) ## period #> [1] "2M 0S" dminutes(2) ## duration #> [1] "120s (~2 minutes)"
例2,對時間加上期間和周期,返回的結果是不同的:
> ymd(20120101) + dyears(1) [1] "2012-12-31" > ymd(20120101) + years(1) [1] "2013-01-01"
例3,日期的下一個月:
ymd('2018-01-01')+months(1)
6,日期周期的開始和結束
使用以下兩個函數獲得日期的開始或結束時間:
floor_date(x, unit = "seconds", week_start = getOption("lubridate.week.start", 7)) ceiling_date(x, unit = "seconds", change_on_boundary = NULL, week_start = getOption("lubridate.week.start", 7))
例如,獲得YTD的開始和結束日期:
ytd_start <- floor_date(Sys.Date(),'year') ytd_end <- floor_date(Sys.Date(),'month')
參考文檔:
Make Dealing with Dates a Little Easier
