第七章 日期和时间
7.1日期和时间类
R 中自带有三个日期和时间类:POSIXct、POSIXlt 和 Date。
函数 | 功能 |
---|---|
Sys.Date | 返回系统当前的日期。 |
Sys.time | 返回系统当前的日期和时间。 |
date | 返回系统当前的日期和时间(返回的值为字符串)。 |
as.Date | 将字符串形式的日期值转换为日期变量。 |
as.POSIXlt | 将字符串转化为包含时间及时区的日期变量。 |
strptime | 将字符型变量转化为包含时间的日期变量。 |
strftime | 将日期变量转换成指定格式的字符型变量。 |
format | 将日期变量转换成指定格式的字符串。 |
as.difftime | 把字符转换成difftime 对象 |
unlist | 列表化输出的时间 |
符号 | 含义 | 示例 |
---|---|---|
%d | 数字表示的日期(00~31) | 01~31 |
%a | 缩写的星期名 | Mon |
%A | 非缩写的星期名 | Monday |
%w | 数字表示的星期天数 | 0-6,周日为0 |
%m | 数字表示的月份(00~12) | 00~12 |
%b | 缩写的月份 | Jan |
%B | 非缩写的月份 | January |
%y | 二位数的年份 | 16 |
%Y | 四位数的年份 | 2016 |
%H | 24小时制小时 | 00-23 |
%I | 12小时制小时 | 01-12 |
%p | AM/PM指示 | AM/PM |
%M | 十进制的分钟 | 00-60 |
%S | 十进制的秒 | 00-60 |
7.1.1POSIX日期和时间
R 中的两个标准的日期-时间类是 POSIXct 和 POSIXlt。POSIXct 类记录了以世界标准时(UTC)时区 为准的从 1970 年开始计时的秒数计数 2。POSIXlt 将日期存储为一个列表,其中包括秒、 分钟、小时和月份等。POSIXct 最适用于存储和计算时间,而 POSIXlt 最适用于提取日期中的某个特定部分。
函数 Sys.time 将以 POSIXct 的形式返回当前的日期和时间:
> (now_ct <- Sys.time())
[1] "2020-04-25 14:32:12 CST"
now_ct 类有两个元素:一个是 POSIXct 变量,还有 POSIXct 继承自类 POSIXt:
> class(now_ct)
[1] "POSIXct" "POSIXt"
当日期被打印出来时,你只看到它格式化后的版本,因而不确定日期是如何被存储的。通 过使用 unclass,我们发现它只是一个数字:
> unclass(now_ct)
[1] 1587796333
POSIxlt日期看上去几乎都一样,但他们的底层存储机制是非常不同的:
> (now_lt <- as.POSIXlt(now_ct))
[1] "2020-04-25 14:32:12 CST"
> class(now_lt)
[1] "POSIXlt" "POSIXt"
> unclass(now_lt)
$sec
[1] 12.87409
$min
[1] 32
$hour
[1] 14
$mday
[1] 25
$mon
[1] 3
$year
[1] 120
$wday
[1] 6
$yday
[1] 115
$isdst
[1] 0
$zone
[1] "CST"
$gmtoff
[1] 28800
attr(,"tzone")
[1] "" "CST" "CDT"
使用列表索引来单独访问 POSIXlt 日期的每个部分:
> now_lt$sec
[1] 12.87409
7.1.2Date类
Date 类最适用于当你不在乎一天中的某个时刻时。
> (now_date <- as.Date(now_ct))
[1] "2020-04-25"
> class(now_date)
[1] "Date"
> unclass(now_date)
[1] 18377
7.1.3其他日期类
其他日期类来自于各种插件包的日期时间类包括 date、dates、chron、yearmon、yearqtr、timeDate、 ti 和 jul。
7.1.4提取时间
weekdays | 求出所给定时间的星期信息 |
---|---|
months | 求出所给定时间的月份信息 |
quarters | 求出所给定时间的季度信息 |
format | 自定义提取日期的部分信息 |
cut | 作为分组标准将日期信息进行分类,breaks可为year和month |
hour | 求出所给定时间的小时信息 |
minute | 求出所给定时间的分钟信息 |
second | 求出所给定时间的秒信息 |
day | 求出所给定时间的天信息 |
mouth | 求出所给定时间的月份信息 |
year | 求出所给定时间的年份信息 |
yday | 求出当前是一年中的第多少天 |
week | 求出当前是一年中的第几个星期 |
days_in_month | 求出当前月的最大天数 |
7.1.5解析时间
lubridate包处理日期和时间的功能极其强大,精确解析出给定的日期或者时间,并以标准形式输出
y
代表年,m
代表月,d
代表日,h代表时,m代表分,s代表秒
对于日期信息的解析,我们可以任意地变换ymd
中三个字母的顺序,来适应需要解析的日期格式,hms
不能随意变换,只能按照hms
这一固定顺序,但是其中的时间分隔符可以随意定义,支持多种分隔符形式,比如图中的,
.
/
等等。
7.1.6修改时间
round_date | 对所输入的时间进行四舍五入取整,unit可分别为second、minute、hour |
---|---|
floor_date | 对所输入的时间进行向下取整,unit可分别为second、minute、hour |
ceiling_date | 对所输入的时间进行向上取整,unit可分别为second、minute、hour |
7.2日期与字符串的相互转换
7.2.1解析日期
当我们从文本或电子表格文件读取日期时,它们通常被存储为一个字符向量或因子。为 了把它们转换为日期,我们需要解析这些字符串。
strptime()函数(string parse time 的简称),它将返回 POSIXlt 日期,日期的格式使 用带有百分比符号和字母的字符串来指定。
%H 是小时( 24 小时制),%M 是分钟,%S 是秒,%m 是月数,%d(如前所述)是 当月的第几天,还有 %Y 为四位数的年份。
> moon_landings_str <- c(
+ "20:17:40 20/07/1969",
+ "06:54:35 19/11/1969"
+ )
> (moon_landings_lt <- strptime(
+ moon_landings_str,
+ "%H:%M:%S %d/%m/%Y",
+ tz = "UTC"
+ ))
[1] "1969-07-20 20:17:40 UTC"
[2] "1969-11-19 06:54:35 UTC"
如果字符串不匹配格式字符串中的格式,那么它就取 NA 值。例如,如果给出的是破折号 而不是斜线,将使得解析失败:
> strptime(
+ moon_landings_str,
+ "%H:%M:%S %d-%m-%Y",
+ tz = "UTC"
+ )
[1] NA NA
7.2.2格式化日期
与解析相反的问题是如何把日期变量转换为字符串,即格式化。现在调用 strftime(字符串格式的时间)来反转解 析操作。也可以使用 format 函数来轻松地完成日期的格式化。
%I 表示小时(12 小时制),%p 是 AM/PM 指示,%A 是星期几的全名,而 %B 是 月的全名。
> strftime(now_ct, "It's %I:%M%p on %A %d %B, %Y.")
[1] "It's 02:32下午 on 星期六 25 四月, 2020."
7.3时区
在解析日期字符串时(使用 strptime),你可以指定一个时区;当你格式化它时(使用strftime),可以再次改变它。在解析过程中,如果不指定时区(默认为“”),R 会给日期 以默认时区。你 可以使用 Sys.getlocale("LC_TIME") 来查看操作系统的日期时间设定。
> strftime(now_ct, tz = "America/Los_Angeles")
[1] "2020-04-24 23:32:12"
> strftime(now_ct, tz = "Africa/Brazzaville")
[1] "2020-04-25 07:32:12"
使 用 file.path(R.home("share"), "zoneinfo", "zone.tab") 能 查 找 出 R 中 所 有 可 能 的 Olson 时区列表(这是名为 zone.tab 的文件位于 zoneinfo 文件夹中,此文件夹就在你安装 R 的共享目录内)。
另一个可靠的方法是给 UTC 手动添加一个偏移量,格式为 "UTC"+n" 或 "UTC"-n"。负的时 间在 UTC 的东边,正的在西边。
> strftime(now_ct, tz = "UTC-5")
[1] "2020-04-25 11:32:12"
Warning message:
In as.POSIXlt.POSIXct(x, tz = tz) : unknown timezone 'UTC-5'
> strftime(now_ct, tz = "GMT-5")
[1] "2020-04-25 11:32:12"
Warning message:
In as.POSIXlt.POSIXct(x, tz = tz) : unknown timezone 'GMT-5'
> strftime(now_ct, tz = "-5")
[1] "2020-04-25 11:32:12"
Warning message:
In as.POSIXlt.POSIXct(x, tz = tz) : unknown timezone '-5'
指定时区的第三个方法是使用缩写,可以是三个字母或三个字母加一个数字再加三个字母 的方式。这种方法不到最后不要使用,原因有三个:首先,缩写难以阅读,更容易出错; 其次,正如前面提到的,它们不是唯一的,所以给出的时区可能不是你所要的;最后,不 同的操作系统支持不同的缩写集。尤其对于 Windows 操作系统来说,它对时区缩写的处理 比较别扭:
> strftime(now_ct, tz = "EST")
[1] "2020-04-25 01:32:12"
> strftime(now_ct, tz = "PST8PDT")
[1] "2020-04-24 23:32:12"
7.4日期和时间的算术运算
R 支持三个日期与时间基类的算术运算。将数字与 POSIX 日期相加,会以秒为单位增加时 间。将数字与 Date 相加会以天数为单位:
> now_ct + 86400
[1] "2020-04-26 14:32:12 CST"
> now_lt + 86400
[1] "2020-04-26 14:32:12 CST"
> now_date + 1
[1] "2020-04-26"
把两个日期加起来其实没有多大意义,而且会抛出一个错误。但减法操作是支持的,这会 计算两个日期之间的差值。这种行为对于所有三种日期的类型都一样。
> the_start_of_time <- as.Date("1970-01-01")
> the_end_of_time <- as.Date("2012-12-21")
> (all_time <- the_end_of_time - the_start_of_time)
Time difference of 15695 days
使用 difftime 函数来计算出日期和时间之间的差值,它以数字的形式存储并以天为单位。 由于时间之间的差别,天数被自动选择为“最敏感的”单位。差别短于一天的时间以小 时、分钟或秒来表示。
> difftime(the_end_of_time, the_start_of_time, units = "secs")
Time difference of 1356048000 secs
> difftime(the_end_of_time, the_start_of_time, units = "weeks")
Time difference of 2242.143 weeks
seq 函数也适用于日期。这在创建人工生成的日期(artificial date)的测试数 据集时尤其有用。在 by 参数中,单位的选择对于 POSIX 和 date 类型是有所不同的。
> seq(the_start_of_time, the_end_of_time, by = "1 year")
[1] "1970-01-01" "1971-01-01" "1972-01-01"
[4] "1973-01-01" "1974-01-01" "1975-01-01"
[7] "1976-01-01" "1977-01-01" "1978-01-01"
[10] "1979-01-01" "1980-01-01" "1981-01-01"
[13] "1982-01-01" "1983-01-01" "1984-01-01"
[16] "1985-01-01" "1986-01-01" "1987-01-01"
[19] "1988-01-01" "1989-01-01" "1990-01-01"
[22] "1991-01-01" "1992-01-01" "1993-01-01"
[25] "1994-01-01" "1995-01-01" "1996-01-01"
[28] "1997-01-01" "1998-01-01" "1999-01-01"
[31] "2000-01-01" "2001-01-01" "2002-01-01"
[34] "2003-01-01" "2004-01-01" "2005-01-01"
[37] "2006-01-01" "2007-01-01" "2008-01-01"
[40] "2009-01-01" "2010-01-01" "2011-01-01"
[43] "2012-01-01"
> seq(the_start_of_time, the_end_of_time, by = "500 days")
[1] "1970-01-01" "1971-05-16" "1972-09-27"
[4] "1974-02-09" "1975-06-24" "1976-11-05"
[7] "1978-03-20" "1979-08-02" "1980-12-14"
[10] "1982-04-28" "1983-09-10" "1985-01-22"
[13] "1986-06-06" "1987-10-19" "1989-03-02"
[16] "1990-07-15" "1991-11-27" "1993-04-10"
[19] "1994-08-23" "1996-01-05" "1997-05-19"
[22] "1998-10-01" "2000-02-13" "2001-06-27"
[25] "2002-11-09" "2004-03-23" "2005-08-05"
[28] "2006-12-18" "2008-05-01" "2009-09-13"
[31] "2011-01-26" "2012-06-09"
7.5lubridate
lubridate 有多种使用了预设格式的解析函数。ymd 接受年、月、日的 日期形式。
> library(lubridate)
> john_harrison_birth_date <- c(
"1693-03 24",
"1693/03\\24",
"Tuesday+1693.03*24"
)
> ymd(john_harrison_birth_date)
lubridate 还提供的其他函数(ydm、mdy、myd、dmy 和 dym)。
lubridate 中的所有解析函数都会返回 POSIXct 日期,默认都使用 UTC 时区。警告:这些 行为与 R 中的基本函数 strptime 不同。
lubridate 提供了 stamp 函数来格式化日期,使你以更可读的方式指定格式。
> date_format_function <- stamp("A moon landing occurred on Monday 01 January 1900 at 18:00:00.")
> date_format_function(moon_landings_lt)
lubridate 有三种不同类型的变量可用于时间范围的处理。“持续时间”(Duration)指定 的时间跨度为秒的倍数,
> (duration_one_to_ten_years <- dyears(1:10))
> today() + duration_one_to_ten_years
“周期” (period)根据时钟上的时间来指定时间跨度。这意味着,在把它们添加到一个瞬 间之前,它们确切的时间跨度是看不出来的。
> (period_one_to_ten_years <- years(1:10))
> today() + period_one_to_ten_years
“间隔” (interval)定义为某段具有开始和结束的时间。它们本身用处不大,最常用于指定 持续时间和周期,当你已知开始和结束日期(而非持续的时间)时 。它们也可用于持续时 间和周期之间的转换。
> a_year <- dyears(1)
> as.period(a_year)
当起始(或结束)时间的日期已知时,我们可以使用 interval 和一个媒介把持续时间转换 为周期.
>start_date <- ymd("2016-02-28")
>(interval_over_leap_year <- new_interval( start_date,
start_date + a_year
))
as.period(interval_over_leap_year)
对于时区的处理,with_tz 允许你改变日期的时区而无须把它打印出来(这与 strftime 不 同)。它还能够正确地处理 POSIXlt 日期(这也与 strftime 不同):
> with_tz(now_lt, tz = "America/Los_Angeles")
7.6intervals
间隔intervals是指特定的时间跨度。一个interval是两个特定时刻之间的时间
date1 <- interval(start1,end1)
time_length(date1,'year')自定义时间单位来输出间隔所包含的时间总量,支持的时间单位包括second day month year等
int_overlaps(date1,date2)来判断两个间隔之间是否有重复
当我们已知具体时间间隔后,如何求出其起始时间、终止时间等信息,通过调用函数int_start() int_end()便可以求出给定间隔的起始时间与终止时间。
int_flip()即可实现起始时间与终止时间的互换
7.7duration
duration是一个绝对的时间跨度,不受时间起始和终止的限制,对于duration
时间跨度我们是固定用秒来作为时间单位
时间跨度duration的生成方法主要的方法有两种:
第一种是直接调用函数duration()
第二种方法是调用函数dyears ddays等来进行duration时间跨度的生成
注:月份有28天,有30天,有31天,还有29天,没有办法一致衡量的,所以不考虑mouth,时间跨度duration不考虑闰年
将间隔interval转换为时间跨度duration,需要调用函数as.duration()
不仅可以大小判断,还可以直接使用命令+或者-进行加减运算
7.8period
周期period以较长的时钟周期来计算时段长度,并且考虑了闰年和闰秒。
创建周期period可用:years(),days(),hours(),minutes(),seconds()
转换为period:as.period()
period类型时段之间可用加法、减法和除法运算
标签:01,tz,日期,时间,第七章,date,now From: https://www.cnblogs.com/simpleness/p/17626117.html