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.