修改POSIXct对象的时区而不改变显示



我有一个POSIXct对象,并想改变它的tz属性没有R来解释它(解释它意味着改变日期时间如何显示在屏幕上)。

一些背景:我正在使用s.u urbanek的fasttime包,它可以很快地将字符串转换为POSIXct。问题是字符串应该在"GMT"中表示日期时间,而不是my data的情况。

我最终与tz=GMTPOSIXct对象,在现实中它是tz=GMT+1,如果我改变时区与

attr(datetime, "tzone") <- "Europe/Paris";
datetime  <- .POSIXct(datetime,tz="Europe/Paris"); 

则它将被"显示"为GMT+2(底层值永远不会改变)。

编辑:这里是一个例子

datetime=as.POSIXct("2011-01-01 12:32:23.234",tz="GMT")
attributes(datetime)
#$tzone
#[1] "GMT"
datetime
#[1] "2011-01-01 12:32:23.233 GMT"

我怎么能改变这个属性没有R来解释它又怎么能改变tzone和仍然有日期时间显示为"2011-01-01 12:32:23.233" ?

编辑/解决方案,@GSee的解决方案相当快,润滑脂::force_tz非常慢

datetime=rep(as.POSIXct("2011-01-01 12:32:23.234",tz="GMT"),1e5)
f <- function(x,tz) return(as.POSIXct(as.numeric(x), origin="1970-01-01", tz=tz))
> system.time(datetime2 <- f(datetime,"Europe/Paris"))
   user  system elapsed 
   0.01    0.00    0.02 
> system.time(datetime3 <- force_tz(datetime,"Europe/Paris"))
   user  system elapsed 
   5.94    0.02    5.98 
identical(datetime2,datetime3)
[1] TRUE

要更改POSIXct变量的tz属性,将其转换为字符或数字然后再返回POSIXct并不是最佳实践。相反,您可以使用lubridate包的force_tz函数

library(lubridate)
datetime2 <- force_tz(datetime, tzone = "CET")
datetime2
attributes(datetime2)

edit:

我以前的解决方案是传递一个字符值给origin(即origin="1970-01-01")。这只在这里工作,因为一个错误(#PR14973),现在已经在R-devel修复。

origin使用as.POSIXct调用的tz参数被强制到POSIXct,而不是文档中描述的"GMT"。该行为已被更改为与文档匹配,在这种情况下,这意味着您必须为originas.POSIXct调用指定您的时区。

datetime
#[1] "2011-01-01 12:32:23.233 GMT"
as.POSIXct(as.numeric(datetime), origin=as.POSIXct("1970-01-01", tz="Europe/Paris"),
           tz="Europe/Paris")
#[1] "2011-01-01 12:32:23.233 CET"

lubridate包的另一种选择是通过与字符类型之间的转换:

recastTimezone.POSIXct <- function(x, tz) return(
  as.POSIXct(as.character(x), origin = as.POSIXct("1970-01-01"), tz = tz))

(改编自GSee的回答)

不知道这是否有效,但它可以在夏令时区域工作。

测试代码:

x <- as.POSIXct('2003-01-03 14:00:00', tz = 'Etc/UTC')
x
recastTimezone.POSIXct(x, tz = 'Australia/Melbourne')
输出:

[1] "2003-01-03 14:00:00 UTC"
[1] "2003-01-03 14:00:00 AEDT" # Nothing is changed apart from the time zone.

如果我用as.numeric()替换as.character()的输出(如GSee所做的):

[1] "2003-01-03 14:00:00 UTC"
[1] "2003-01-03 15:00:00 AEDT" # An hour is added.

相关内容

  • 没有找到相关文章

最新更新