我有一个POSIXct
对象,并想改变它的tz
属性没有R来解释它(解释它意味着改变日期时间如何显示在屏幕上)。
一些背景:我正在使用s.u urbanek的fasttime
包,它可以很快地将字符串转换为POSIXct
。问题是字符串应该在"GMT"中表示日期时间,而不是my data的情况。
我最终与tz=GMT
的POSIXct
对象,在现实中它是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"
。该行为已被更改为与文档匹配,在这种情况下,这意味着您必须为origin
和as.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.