lubridate yyyy-MM-dd'T'HH:mm:ssX转换意外。错误?

时间:2017-04-20 14:17:56

标签: r lubridate

解析“yyyy-MM-dd'T'HH:mm:ssX”-string(ISO 8601)时非常意外的行为

> as_datetime("2017-03-22T15:48:00.000Z")
[1] "2017-03-21 23:00:00 UTC"

> packageDescription("lubridate")$Version 
[1] "1.6.0"

有人可以解释一下这个理由吗?

编辑:看起来像个错误,请参阅issue #536

2 个答案:

答案 0 :(得分:4)

更新:已在lubridate提交here(2017年5月)中解决。适用于lubridate 1.7.4,也可能是某些早期版本。

没有挖掘as_datetime的内心, 我认为这可能是(1)as_datetime的组合 无法处理(即忽略)您格式的T; (2)从本地到UTC时区的转换。

dstr <- "2017-03-22T15:48:00.000Z"
library(lubridate)
as_datetime(dstr)
## [1] "2017-03-22 04:00:00 UTC"

如果as_datetime()忽略T之后的所有内容 这让我们在2017-03-22的午夜。但是,这是 在我当地时区的午夜,即GMT + 04, 所以产生的时间是04:00:00。大概是你当地的时间 是GMT-01。

如果您手动替换空格以使T更好地工作(您可以使用 stringr::str_replace如果您愿意的话)

as_datetime(sub("T"," ",dstr))
## [1] "2017-03-22 19:48:00 UTC"

或使用strptime

strptime(dstr,format="%Y-%m-%dT%H:%M:%S")
## [1] "2017-03-22 15:48:00 EDT"

(请注意strptime会自动丢弃尾随字符)

Dirk Eddelbuettel的anytime包处理这个案子是值得的:

 anytime(dstr)
 ## [1] "2017-03-22 15:48:00 EDT"

答案 1 :(得分:4)

如果您使用此处显示的格式导入数据并且想要使用lubridate将其转换为日期时间对象,我建议使用lubridate的ymd_hms函数。

在你的情况下,它看起来像这样:

ymd_hms("2017-03-22T15:48:00.000Z")
[1] "2017-03-22 15:48:00 UTC"