嗨我有一个长度为几百万的字符向量(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"
如果在整套数据上进行上述操作需要很长时间......因此,任何速度提升都会受到重视。感谢。
答案 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有时间前进一小时的情况。