17

I have a problem converting POSIXct to character and back in POSIXct in R. I run the following code:

time_seq_01 <- seq(as.POSIXct("2012-10-28 02:00:00"), by = 900, length.out = 10)
time_seq_02 <- as.character(time_seq_01)
time_seq_03 <- as.POSIXct(time_seq_02)

or equivalent:

time_seq_01 <- seq(as.POSIXct("2012-10-28 02:00:00"), by = 900, length.out = 10)
time_seq_02 <- format(time_seq_01,usetz = TRUE)
time_seq_03 <- as.POSIXct(time_seq_02)

This are the timestamps in 2012 when the daylight saving transition from Central European Summer Time (CEST) to Central European Time (CET) occurs (Last Sunday in October 02:00 - 03:00).

When I call these elements I get

time_seq_01
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CEST"
[5] "2012-10-28 02:00:00 CET"  "2012-10-28 02:15:00 CET" 
[7] "2012-10-28 02:30:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 
time_seq_02
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CEST"
[5] "2012-10-28 02:00:00 CET"  "2012-10-28 02:15:00 CET" 
[7] "2012-10-28 02:30:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 
time_seq_03
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CET" 
[5] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[7] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 

The creation of a POSIXct sequence does work correctly (time_seq_01) the transition to character also (time_seq_02). However the transition back from character back to POSIXct produces wrong timezone (CET/CEST) values (time_seq_03). This can be clearly seen when those elements are sorted:

sort(time_seq_01)
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CEST"
[5] "2012-10-28 02:00:00 CET"  "2012-10-28 02:15:00 CET" 
[7] "2012-10-28 02:30:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 
sort(time_seq_03)
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:00:00 CEST"
[3] "2012-10-28 02:15:00 CEST" "2012-10-28 02:15:00 CEST"
[5] "2012-10-28 02:30:00 CEST" "2012-10-28 02:30:00 CEST"
[7] "2012-10-28 02:45:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 

This causes a number of problems for instance when merging objects by those timestamps. Is there a way to overcome this problem?

The system I use:

Windows 7 64bit
R version 2.15.1 (2012-06-22)
Platform: x86_64-pc-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=German_Austria.1252  LC_CTYPE=German_Austria.1252   
[3] LC_MONETARY=German_Austria.1252 LC_NUMERIC=C                   
[5] LC_TIME=German_Austria.1252    
attached base packages:
[1] tools     stats     graphics  grDevices utils     datasets  methods 
[8] base     
other attached packages:
[1] pkgtools_0.1-3 roxygen2_2.2.2 digest_0.5.2   rj_1.1.0-4    
loaded via a namespace (and not attached):
[1] brew_1.0-6    plyr_1.7.1    rj.gd_1.1.0-1 stringr_0.6.1
kajo
  • 181
  • 1
  • 6
  • 2
    What's your `sessionInfo()`? Have you read the *Warning* section of `?POSIXct`? – Joshua Ulrich Oct 31 '12 at 11:34
  • I have added my session info in the question above – kajo Oct 31 '12 at 12:12
  • 1
    Are you prohibited from using the `tz` argument in `as.POSIXct`? This can be set, allowing for you to control the timezone. – Marc in the box Oct 31 '12 at 13:15
  • 1
    In addition to the warning section @JoshuaUlrich mentioned, there is also the Details section of `?as.POSIXct`, which addresses pretty much exactly this issue. – BenBarnes Oct 31 '12 at 13:19
  • 1
    As suggested I looked at the recommended section of ´?POSIXct´ and set the ´TZ´variable with ´Sys.setenv´. This did not change anything. I also constructed this problem on a linux machine getting similar results. – kajo Oct 31 '12 at 13:24

1 Answers1

11

Here's a work around that goes from POSIXct to character back to POSIXct preserving the original daylight savings time status.

Sys.setenv(TZ='Europe/Berlin') # to reproduce OP's example
time_seq_01 <- seq(as.POSIXct("2012-10-28 02:00:00"), by = 900, length.out = 10)
time_seq_02 <- format(time_seq_01,usetz = TRUE)

time_seq_02_lt <- as.POSIXlt(time_seq_02)
time_seq_02_lt$isdst <- as.POSIXlt(time_seq_01)$isdst
time_seq_03 <- as.POSIXct(time_seq_02_lt)

As far as I can tell, R's support for string-to-datetime doesn't include DST flags specified within the strings.

Matthew Plourde
  • 43,932
  • 7
  • 96
  • 113
  • 2
    Thanks for this hint! A problem that remained was that in practice I do not have the basic POSIXct sequence available and I have to start with the character sequence (`time_seq_02`). So I changed `time_seq_02_lt$isdst <- as.POSIXlt(time_seq_01)$isdst` to `time_seq_02_lt$isdst <- grepl("CEST", time_seq_02)` This did the trick. The basic problem in my opinion is as you said that DST flags are not supported in character to POSIXct conversions. That would make it a lot easier. – kajo Oct 31 '12 at 15:11