fastPOSIXct相当于将非UTC转换为UTC

时间:2013-08-30 15:55:26

标签: r posix posixct

嗨我有一个长度为几百万的字符向量(rr),它代表澳大利亚/悉尼记录的%Y-%m-%d %H:%M:%S格式的时间和日期标记。

如何获得代表此的POSIXct对象(快速)。

我在fastPOSIXct包中找到fasttime,但为了准确起见,它要求原始字符串为GMT / UTC(我的不是),然后转换回来使用tz争论进入正确的时区...

> head(rr)
[1] "2009-05-01 10:01:00" "2009-05-01 10:02:00" "2009-05-01 10:03:00" "2009-05-01 10:04:00"
[5] "2009-05-01 10:05:00" "2009-05-01 10:06:00"

> as.POSIXct(head(rr),tz="Australia/Sydney")
[1] "2009-05-01 10:01:00 EST" "2009-05-01 10:02:00 EST" "2009-05-01 10:03:00 EST"
[4] "2009-05-01 10:04:00 EST" "2009-05-01 10:05:00 EST" "2009-05-01 10:06:00 EST"

如果在整套数据上进行上述操作需要很长时间......因此,任何速度提升都会受到重视。感谢。

2 个答案:

答案 0 :(得分:1)

这是一种方法:

i)骗fasttime()并假装数据为UTC,用于将数据解析为向量x

ii)使用您的第一个数据点计算到UTC的偏移量:

R> d1 <- "2009-05-01 10:01:01"   ## or use `head(rr,1)`
R> t1 <- as.POSIXct(d1,tz="Australia/Sydney")
R> t2 <- as.POSIXct(d1,tz="UTC")
R> offset <- as.numeric(difftime(t2, t1, units="secs"))
R> offset
[1] 36000

iii)将offset值应用于您的数据 - 这是一个快速添加,因为POSIXct实际上是一个数字类型,其中(小数)秒(因为纪元)为单位。

答案 1 :(得分:1)

受到Dirk对这个qn的回答的启发,我制作了这个包装器来处理一年中的大量日期:

    fastPOSIXct_generic <- function(x, mytz = "America/New_York")
{
    # Caution, read: ?DateTimeClasses
    stopifnot(is.character(x))
    times_UTC <- fastPOSIXct(x, tz='UTC')
    num_times <- as.numeric(times_UTC)
    t1 <- as.POSIXct(x[1], tz = mytz)
    t2 <- as.POSIXct(x[1], tz = "UTC")
    offset <- as.numeric(difftime(t1, t2, units = "secs"))
    daylightoffset <- as.POSIXlt(t1)$isdst
    # For this first 'time' in t1 and t2, remove possible impact of losing one hour by setting clocks one hour forward during summer months:
    offset <- offset + daylightoffset * 3600
    num_times <- num_times + offset
    new_num_times <- as.POSIXct(num_times, tz = mytz, origin = '1970-01-01')
    new_num_times2 <- new_num_times - as.POSIXlt(new_num_times)$isdst * 3600
    return(new_num_times2)
}

# Test Sydney time

mm <- as.POSIXct(c("2015-03-15 15:00:00", "2015-4-10 15:00:00", "2014-10-01 15:00:00", "2015-10-15 15:00:00"), tz = "Australia/Sydney")
# "2015-03-15 15:00:00 AEDT" "2015-04-10 15:00:00 AEST" "2014-10-01 15:00:00 AEST" "2015-10-15 15:00:00 AEDT"
aus_stamps <- as.character(mm)
aus_back <- fastPOSIXct_generic(x = aus_stamps, mytz = "Australia/Sydney")
#"2015-03-15 15:00:00 AEDT" "2015-04-10 15:00:00 AEST" "2014-10-01 15:00:00 AEST" "2015-10-15 15:00:00 AEDT"
identical(mm, aus_back)
# TRUE

我的用例几乎总是UTC到America / New_York,到目前为止它似乎工作得很好。我不知道它是否适用于其他时区;只是dst有时间前进一小时的情况。

相关问题