todos - Modificar la zona horaria de un objeto POSIXct sin cambiar la pantalla
zona horaria mas adelantada (3)
Para cambiar el atributo tz
de una variable POSIXct
, no es recomendable convertir a carácter o numérico y luego volver a POSIXct
. En cambio, podría usar la función lubridate
paquete lubridate
library(lubridate)
datetime2 <- force_tz(datetime, tzone = "CET")
datetime2
attributes(datetime2)
Tengo un objeto POSIXct
y me gustaría cambiar su atributo tz
SIN R para interpretarlo (interpretarlo significaría cambiar cómo se muestra la fecha y hora en la pantalla).
Algunos antecedentes: estoy usando el paquete fasttime
de S.Urbanek, que toma cadenas y lo POSIXct
a POSIXct
muy rápidamente. El problema es que la cadena debe representar una fecha y hora en "GMT" y no es el caso de mis datos.
POSIXct
con un objeto POSIXct
con tz=GMT
, en realidad es tz=GMT+1
, si cambio la zona horaria con
attr(datetime, "tzone") <- "Europe/Paris";
datetime <- .POSIXct(datetime,tz="Europe/Paris");
luego se "mostrará" como GMT+2
(el valor subyacente nunca cambia).
EDITAR: Aquí hay un ejemplo
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"
¿Cómo puedo cambiar este atributo sin R para interpretarlo, también conocido como ¿cómo puedo cambiar tzone y aún tener fecha y hora como "2011-01-01 12:32:23.233"
?
EDIT / SOLUTION, @ La solución de GSee es razonablemente rápida, lubridate :: force_tz muy lenta
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
EDITADO:
Mi solución anterior estaba pasando un valor de carácter a origin
(es decir, origin="1970-01-01"
). Eso solo funcionó aquí debido a un error ( # PR14973 ) que ahora se ha corregido en R-devel.
origin
fue forzado a POSIXct
utilizando el argumento tz
de la llamada as.POSIXct
, y no a "GMT"
como estaba documentado hacerlo. El comportamiento se ha cambiado para que coincida con la documentación que, en este caso, significa que debe especificar su zona horaria para el origin
y la llamada 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"
Esto también funcionará en versiones anteriores de R.
Una alternativa al paquete lubridate
es mediante la conversión lubridate
desde el tipo de carácter:
recastTimezone.POSIXct <- function(x, tz) return(
as.POSIXct(as.character(x), origin = as.POSIXct("1970-01-01"), tz = tz))
(Adaptado de la respuesta de GSee)
No sé si esto es eficiente, pero funcionaría para zonas horarias con horario de verano.
Código de prueba:
x <- as.POSIXct(''2003-01-03 14:00:00'', tz = ''Etc/UTC'')
x
recastTimezone.POSIXct(x, tz = ''Australia/Melbourne'')
Salida:
[1] "2003-01-03 14:00:00 UTC"
[1] "2003-01-03 14:00:00 AEDT" # Nothing is changed apart from the time zone.
Salida si reemplacé as.character()
por as.numeric()
(como lo había hecho GSee):
[1] "2003-01-03 14:00:00 UTC"
[1] "2003-01-03 15:00:00 AEDT" # An hour is added.