lubridate:与时区的行为不一致

时间:2017-02-08 16:22:53

标签: r timezone dplyr lubridate

考虑以下示例

 library(lubridate)
 library(tidyverse)

> hour(ymd_hms('2008-01-04 00:00:00'))
[1] 0

现在,

dataframe <- data_frame(time = c(ymd_hms('2008-01-04 00:00:00'),
                                 ymd_hms('2008-01-04 00:01:00'),
                                 ymd_hms('2008-01-04 00:02:00'),
                                 ymd_hms('2008-01-04 00:03:00')),
                        value = c(1,2,3,4))

mutate(dataframe,hour = strftime(time, format="%H:%M:%S"),
hour2 = hour(time)) 

# A tibble: 4 × 4
                 time value     hour hour2
               <dttm> <dbl>    <chr> <int>
1 2008-01-03 19:00:00     1 19:00:00    19
2 2008-01-03 19:01:00     2 19:01:00    19
3 2008-01-03 19:02:00     3 19:02:00    19
4 2008-01-03 19:03:00     4 19:03:00    19

这里发生了什么?为什么日期转换成我当时不知道的当地时间?

1 个答案:

答案 0 :(得分:2)

这不是lubridate的问题,而是将POSIXct值组合成一个向量。

你有

> ymd_hms('2008-01-04 00:01:00')
[1] "2008-01-04 00:01:00 UTC"

但是当你合并到一个矢量中时,你得到了

> c(ymd_hms('2008-01-04 00:01:00'), ymd_hms('2008-01-04 00:01:00'))
[1] "2008-01-03 19:01:00 EST" "2008-01-03 19:01:00 EST"

原因是组合POSIXct值时tzone属性会丢失(请参阅c.POSIXct)。

> attributes(ymd_hms('2008-01-04 00:01:00'))
$tzone
[1] "UTC"

$class
[1] "POSIXct" "POSIXt"

但是

> attributes(c(ymd_hms('2008-01-04 00:01:00')))
$class
[1] "POSIXct" "POSIXt"

您可以使用的是

> ymd_hms(c('2008-01-04 00:01:00', '2008-01-04 00:01:00'))
[1] "2008-01-04 00:01:00 UTC" "2008-01-04 00:01:00 UTC"

将对所有参数使用默认的tz = "UTC"

您还需要将tz = "UTC"传递给strftime,因为它的默认值是您当前的时区(与默认为UTC的ymd_hms不同。)