我有一个POSIXct
对象,想要更改它的tz
属性WITHOUT R来解释它(解释它意味着改变日期时间在屏幕上的显示方式)。
一些背景知识:我正在使用来自S.Urbanek的fasttime
包,它将字符串转换为POSIXct
非常快。问题是该字符串应代表“GMT”中的日期时间,而不是我的数据。
我最终得到一个POSIXct
对象tz=GMT
,实际上它是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"
?
EDIT / SOLUTION,@ GSee的解决方案相当快,lubridate :: 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
答案 0 :(得分:10)
我之前的解决方案是将字符值传递给origin
(即origin="1970-01-01"
)。这只能在这里工作,因为在R-devel中现在有#PR14973的错误(been fixed)。
origin
使用POSIXct
调用的tz
参数被强制转移到as.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"
这也适用于旧版本的R。
答案 1 :(得分:8)
要更改tz
变量的POSIXct
属性,最好不要将其转换为字符或数字,然后再转换回POSIXct
。相反,您可以使用force_tz
包
lubridate
功能
library(lubridate)
datetime2 <- force_tz(datetime, tzone = "CET")
datetime2
attributes(datetime2)
答案 2 :(得分:2)
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.character()
替换为as.numeric()
(如GSee所做的那样),则输出:
[1] "2003-01-03 14:00:00 UTC"
[1] "2003-01-03 15:00:00 AEDT" # An hour is added.