首页 文章

从多个时区读取R中的时间戳数据

提问于
浏览
6

我有一列字符格式的时间戳,如下所示:

2015-09-24 06:00:00 UTC

2015-09-24 05:00:00 UTC

dateTimeZone <- c("2015-09-24 06:00:00 UTC","2015-09-24 05:00:00 UTC")

我想使用POSIXct将此字符数据转换为时间数据,如果我知道所有时间戳都是UTC,我会这样做:

dateTimeZone <- asPOSIXct(dateTimeZone, tz="UTC")

但是,我不一定知道所有时间戳都是UTC,所以我试过了

dateTimeZone <- asPOSIXct(dateTimeZodateTimeZone, format = "%Y-%m-%d %H:%M:%S %Z")

但是,因为strptime仅支持%Z输出,所以返回以下错误:

strptime中的错误(x,format,tz = tz):不支持使用%Z作为输入

我检查了lubridate包的文档,我看不出它处理这个问题与POSIXct有什么不同 .

我唯一的选择是检查每一行的时区,然后使用适当的时区,如下所示?

temp[grepl("UTC",datetimezone)] <- as.POSIXct(datetimezone, tz="UTC")
temp[grepl("PDT",datetimezone)] <- as.POSIXct(datetimezone, tz="America/Los_Angeles")

2 回答

  • 4

    一个data.table解决方案:

    library(data.table)
    
    data <- data.table(dateTimeZone=c("2015-09-24 06:00:00 UTC",
                                      "2015-09-24 05:00:00 America/Los_Angeles"))
    data[, timezone:=tstrsplit(dateTimeZone, split=" ")[[3]]]
    data[, datetime.local:=as.POSIXct(dateTimeZone, tz=timezone), by=timezone]
    data[, datetime.utc:=format(datetime.local, tz="UTC")]
    

    关键是在时区字段上拆分数据,这样你就可以将每组时区分别提供给 as.POSIXct (我真的不确定为什么 as.POSIXct 不会让你给它一个时区矢量,实际上) . 在这里,我使用 data.table 的高效split-apply-combine语法,但您可以使用基本R或使用 dplyr 应用相同的一般概念 .

  • 1

    您可以通过检查每一行并相应地进行处理,然后将所有内容重新置于一致的UTC时间来实现 . (#edited现在包括将时区缩写与完整的时区规范相匹配)

    dates <- c(
      "2015-09-24 06:00:00 UTC",
      "2015-09-24 05:00:00 PDT"
    )
    
    #extract timezone from dates
    datestz <- vapply(strsplit(dates," "), tail, 1, FUN.VALUE="")
    
    ## Make a master list of abbreviation to 
    ## full timezone names. Used an arbitrary summer
    ## and winter date to try to catch daylight savings timezones.
    
    tzabbrev <- vapply(
      OlsonNames(),
      function(x) c(
        format(as.POSIXct("2000-01-01",tz=x),"%Z"),
        format(as.POSIXct("2000-07-01",tz=x),"%Z")
      ),
      FUN.VALUE=character(2)
    )
    tmp <- data.frame(Olson=OlsonNames(), t(tzabbrev), stringsAsFactors=FALSE)
    final <- unique(data.frame(tmp[1], abbrev=unlist(tmp[-1])))
    
    ## Do the matching:
    out <- Map(as.POSIXct, dates, tz=final$Olson[match(datestz,final$abbrev)])
    as.POSIXct(unlist(out), origin="1970-01-01", tz="UTC")
    #  2015-09-24 06:00:00 UTC   2015-09-24 05:00:00 PDT 
    #"2015-09-24 06:00:00 GMT" "2015-09-24 12:00:00 GMT"
    

相关问题