【问题标题】:Read character datetimes without timezones读取没有时区的字符日期时间
【发布时间】:2019-08-14 15:40:10
【问题描述】:

我正在尝试在 R 中导入一个包含日期时间的文本文件。时间以字符格式存储,没有时区信息,但我们知道它是法国时间(欧洲/巴黎)。

时区更改的日子出现问题:例如从2018-10-28 03:00:00 CEST2018-10-28 02:00:00 CET 有一个时间变化,因此我们的字符格式有重复,R 无法判断它是CEST 还是CET

考虑以下示例:

data_in <- "date,val
2018-10-28 01:30:00,25
2018-10-28 02:00:00,26
2018-10-28 02:30:00,27
2018-10-28 02:00:00,28
2018-10-28 02:30:00,29
2018-10-28 03:00:00,30"

library(readr)
data <- read_delim(data_in, ",", locale = locale(tz = "Europe/Paris"))

我们最终在我们的日期中有重复:

data$date
[1] "2018-10-28 01:30:00 CEST" "2018-10-28 02:00:00 CEST" "2018-10-28 02:30:00 CET"  "2018-10-28 02:00:00 CEST"
[5] "2018-10-28 02:30:00 CET"  "2018-10-28 03:00:00 CET" 

预期的输出是:

data$date
[1] "2018-10-28 01:30:00 CEST" "2018-10-28 02:00:00 CEST" "2018-10-28 02:30:00 CEST"  "2018-10-28 02:00:00 CET"
[5] "2018-10-28 02:30:00 CET"  "2018-10-28 03:00:00 CET" 

知道如何解决问题(除了告诉人们使用 UTC 或 ISO 格式)。我想唯一的方法是假设日期是排序的,所以我们可以知道第一个是CEST

【问题讨论】:

    标签: r timezone lubridate posixct readr


    【解决方案1】:

    如果您确定您的时间总是在增加,那么您可以寻找明显的减少(一天中的时间)并手动将 TZ 偏移量插入到字符串中,然后照常解析。我添加了一些逻辑来仅在凌晨 2 点到 3 点左右寻找这种减少,这样如果您有多天的数据跨越午夜,您就不会收到误报。

    data <- read.csv(text = data_in)
    fakedate <- as.POSIXct(gsub("^[-0-9]+ ", "2000-01-01 ", data$date))
    decreases <- cumany(grepl(" 0[23]:", data$date) & c(FALSE, diff(fakedate) < 0))
    data$date <- paste(data$date, ifelse(decreases, "+0100", "+0200"))
    data
    #                        date val
    # 1 2018-10-28 01:30:00 +0200  25
    # 2 2018-10-28 02:00:00 +0200  26
    # 3 2018-10-28 02:30:00 +0200  27
    # 4 2018-10-28 02:00:00 +0100  28
    # 5 2018-10-28 02:30:00 +0100  29
    # 6 2018-10-28 03:00:00 +0100  30
    
    as.POSIXct(data$date, format="%Y-%m-%d %H:%M:%S %z", tz="Europe/Paris")
    # [1] "2018-10-28 01:30:00 CEST" "2018-10-28 02:00:00 CEST" "2018-10-28 02:30:00 CEST"
    # [4] "2018-10-28 02:00:00 CET"  "2018-10-28 02:30:00 CET"  "2018-10-28 03:00:00 CET" 
    

    我对@9​​87654322@ 的使用只是某个非夏令时日,因此我们可以将时间戳解析为POSIXt 并计算其差异。 (如果我们没有插入日期,我们仍然可以使用带有格式的 as.POSIXct,但是如果您曾经在 DST 的两个日期之一运行它,您可能会得到不同的结果,因为 as.POSIXct("01:02:03", format="%H:%M:%S") 总是假定“今天”。

    它的假设显然有点脆弱,但也许它足以满足您的需要。

    【讨论】:

      猜你喜欢
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 2014-10-22
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      相关资源
      最近更新 更多