Search code examples
rdatetimeposixct

How to automatically recognise timezone when converting from a datetime saved as character to POSIXct in R?


I'm trying to save a POSIXct datetime as a string with timezone, then convert it back to the original POSIXct datetime with the correct timezone. In the back-conversion, I'm wanting the timezone to be recognised from the string rather than having to specify it manually.

Seems straightforward but I haven't been able to work out a way to do this: I seem to have to either manually specify the timezone (see top example below) or the back-conversion fails (see bottom example).

Any advice much appreciated.

# This works, but I'm manually specifying the timezone on the third line. I want to do this automatically.
dt = as.POSIXct('2021-01-01 00:00:00', tz = 'Pacific/Auckland') #"2021-01-01 NZDT"
char = format(dt, '%Y%m%dT%H%M%OS%z') #20210101T000000+1300 (+1300 = NZDT)
as.POSIXct(char, format = '%Y%m%dT%H%M%OS', tz = 'Pacific/Auckland') #2021-01-01 NZDT. Note manually specifying timezone, which I dont want to do.

# Now trying to automatically specify timezone via '%Z' on the third line. This returns NA.  
dt = as.POSIXct('2021-01-01 00:00:00', tz = 'Pacific/Auckland')
char = format(dt, '%Y%m%dT%H%M%OS%z') #"20210101T000000+1300"
as.POSIXct(char, format = '%Y%m%dT%H%M%OS%z') #NA. Note I'm trying to automatically specify timezone via '%Z' 

Solution

  • What if you force the original timezone into your char string? E.g.:

    dt <- as.POSIXct('2021-01-01 00:00:00', tz = 'Pacific/Auckland')
    dt
    #[1] "2021-01-01 NZDT"
    
    char <- format(dt, paste("%Y%m%dT%H%M%OS", attr(dt, "tzone")) )
    char
    #[1] "20210101T000000 Pacific/Auckland"
    

    Then you can get it back by extracting the datetime part and the timezone part by separating at the first space:

    as.POSIXct(
      sub("\\s.+$", "", char),
      format = "%Y%m%dT%H%M%OS",
      tz     = sub("^.+\\s", "", char[1])
    )
    #[1] "2021-01-01 NZDT"