2013-08-30 21 views
1

您好,我有一个长度为几百万的字符向量(rr),它以澳大利亚/悉尼记录的格式%Y-%m-%d %H:%M:%S表示时间和日期戳。fastPOSIXct等效于将非UTC转换为UTC

如何获得一个代表这个的POSIXct对象(快速)。

我发现fastPOSIXctfasttime包,但对于本是准确的,它需要原始字符串是在GMT/UTC(其矿是不是),然后使用tz转换回正确的时区arguement ...

> 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" 

上面一行需要年龄,如果这样做的全套资料...所以任何速度的提高,将不胜感激。谢谢。

+1

由于POSIXct日期时间只是一个基础数值向量,因此可以使用'fastPOSIXct',然后添加所需的偏移量以将GMT从AEST转换为AEST。 –

+0

您将如何制作偏移对象? –

+1

目前这个问题没有详细说明。这些时间是否有“夏令时”? –

回答

1

下面是一个方法:

ⅰ)骗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 

三)offset值应用到你的数据 - 这是一个快速增加的POSIXct真的是一个数字式带(分数)秒(自纪元)为单位。

+0

正如@Ben Bolker的评论所述,只有当记录的时区不符合夏令时时,这种方法才有效, GMT/UTC始终是恒定的...我也不太确定'd2'对象是你的代码的第三行... –

+0

我们通常在一天之内处理几个100k的数据,因此跨越TZ是通常不是一个问题 - 正如本指出的那样,一个常见的选择是解析所有时间字符串,这是昂贵的。 'd2'是一个错字,应该也是'd1' - 固定的。 –

1

德克的回答这个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美国/纽约,在那里到目前为止,似乎工作正常。我不知道它是否适用于其他时区;只是dst有一个小时的情况。