# 时间处理 {#datetime}
时间处理看起来是一件简单的事情,因为我们每天都在使用,但事实上是一件复杂的事情。闰年导致每年的天数并不一致,每天也并不是24小时。可以自行搜索“夏令时”,“为什么一天是24小时”或"Why do we have 24 hours in a day"等问题了解关于时间的概念。
但是我们做数据分析,可能仅需要简单的计算时间,并不是必须了解“时间”。我们大部分时候能处理同环比,间隔天数等常规问题即可。
由于能力有限以及处理的日期数据类型有限,本章节仅就常规商业数据分析中时间处理提供一种解决办法。
本章主要分为三大部分:
- Base R中时间处理函数
- lubridate包提供的日期时间处理方法
- 常规运用以及和Excel的时间系统对比
## base R {#datetime:base-R}
R中内置Date,POSIXct和POSIXlt三个关于日期和时间的类[^类]。
[^类]:类是面向对象编程的一个术语,一个对象通常有0个1个或多个类。在R中用`class()`函数查看所属对象的类。
### Date {#the-date-class}
如果我们的数据结构中只有日期,没有时间,我们仅需要使用Date类。
```{r}
class(Sys.Date())
```
1.创建日期
```{r}
date1 tm1
```
加减计算,默认单位秒
```{r}
tm1 + 300
tm2 - 300
```
```{r}
tm2 - tm1
```
### POSIXlt {#the-POSIXlt-class}
通过此类,我们可以很便捷提取时间中的特定成分。其中"ct"代表日历时间,"it"代表本地时间,该类对象是list(列表)。
创建时间
```{r}
t1 曾经我在使用阿里云的RDS数据库时没注意时区差异,导致我清洗出来的时间数据错误。
```{r}
ymd_hms(.POSIXct(1591709615),tz = 'Asia/Shanghai')
```
### 提取日期时间成分 {#extracting-datetime-information}
```{r}
#获取年
year(now())
#获取月
month(now())
# 当前时间所在年份天数
yday(now())
# 当前时间所在月天数
mday(now())
# 周几
wday(now(),label = TRUE,week_start = 1)
# 所在时刻
hour(now())
# 所在时刻
minute(now())
# 所在时刻
second(now())
```
### 处理时区 {#time-zones}
数据时区与本地R环境一致时,数据中的时区没必要处理,但是当数据是跨时区的或者不同生产系统的时区不一致,我们需要将数据时区处理一致。
1.时区查看
时区和所用系统设置相关
```{r}
Sys.timezone()
# windows 系统默认的时区 中国台北
# linux 上是"Asia/Shanghai"
# mac 上是"Asia/Shanghai"
```
这里还有一个奇怪的点,Windows系统下时区设置为`(UTC+08:00)北京,重庆,香港特别行政区,乌鲁木齐`,但是R返回的时区是`Asia/Taipei`。
```{r}
now()
```
`now()`输出结果中,CST是时区概念。
CST可以同时代表四个时间
- Central Standard Time (USA) UT-6:00
- Central Standard Time (Australia) UT+9:30
- China Standard Time UT+8:00
- Cuba Standard Time UT-4:00
2.时区调整
lubridate中用`with_tz()`,`force_tz()`处理时区问题
```{r}
time
```{r}
lubridate::now() # now函数调用系统默认时区
as_datetime(now()) #as_datetime默认是UTC
as_datetime(now(),tz = 'asia/shanghai')
```
### 时间间隔{#interveal}
`lubridate`中将时间间隔保存为`interveal`类对象。
```{r}
arrive % mutate( 类型 = case_when(between(bill_date,current_start_date,date) ~ "当前",
between(bill_date,last_start_date,last_end_date) ~ "同期",
TRUE ~ "其他")) %>%
filter(类型 != "其他") %>%
group_by(...) %>%
summarise(金额 = sum(money,na.rm = TRUE)) %>%
ungroup()
#%>% pivot_wider(names_from = '类型',values_from = '金额')
}
```
```{r}
y_to_y(dt,date = '20201001',n = 1,area,类型) %>%
tidyr::pivot_wider(id_cols = 'area',names_from = '类型',values_from = '金额') %>%
mutate(增长率 = 当前 / 同期)
y_to_y(dt,date = '20201001',n = 1,area,类型,category) %>%
tidyr::pivot_wider(id_cols = c('area','category'),names_from = '类型',values_from = '金额') %>%
mutate(增长率 = 当前 / 同期)
```
### 清洗不同类型日期格式
如将`c('2001/2/13 10:33','1/24/13 11:16')`转换为相同格式的日期格式;
通过一个简单自定义函数解决,本质是区分不同类型日期后采用不同函数去解析日期格式
```{r message=FALSE}
library(lubridate)
library(tidyverse)
date1 % `[[`(1) %>% `[[`(1)
if(str_length(n)==4){
res[i] % which.min() #本处不对,应该判断res大于0的部分中谁最小
kong y]
res % which.min()
kong y]
res % which.min()
kong
2. date and time
3. dax时间函数
4. Excel日期系统
*
* pdf 下载