rlubridateposixctposixlt

Issue with converting a date-time string with timezone offset to local time in R


I'm facing difficulties converting a date-time string with a timezone offset to local time in R. The date-time string I have is in the following format: "2021-01-05T09:00:00+01:00". I want to convert it to the local time in the timezone specified by the offset (+01:00), which corresponds to Paris time (Europe/Paris) during the winter (CET - Central European Time).

I've tried using various methods, including lubridate and as.POSIXct() with the %z format. However, these attempts did not produce the correct result. For example, when using lubridate, the output is "2021-01-05 08:00:00 CET" instead of "2021-01-05 09:00:00 CET". I also attempted using strptime() with the same format, but the result remains incorrect.

Here's the R code I've tried so far:

moment <- "2021-01-05T09:00:00+01:00"
date_obj <- ymd_hms(moment) %>% force_tz(tzone = "Europe/Paris")
print(date_obj)  # Output: "2021-01-05 08:00:00 CET"

moment <- "2021-01-05T09:00:00+01:00"
date_obj <- ymd_hms(moment) %>% with_tz(tzone = "Europe/Paris")
print(date_obj)  # Output: "2021-01-05 09:00:00 CET"

# Using as.POSIXct()
moment <- "2021-01-05T09:00:00+01:00"
date_obj <- as.POSIXct(moment, format = "%Y-%m-%dT%H:%M:%S%z")
print(date_obj)  # Output: NA

# Using strptime()
moment <- "2021-01-05T09:00:00+01:00"
date_obj <- strptime(moment, format = "%Y-%m-%dT%H:%M:%S%z")
print(date_obj)  # Output: NA

Could someone please provide a clear and accurate solution to convert this date-time string to the local time in Paris (CET) with the specified timezone offset? Any help or suggestions would be greatly appreciated.

Thank you!


Solution

  • Specify the format up to seconds and separately specify the time zone. No packages are used.

    moment <- "2021-01-05T09:00:00+01:00"
    
    as.POSIXct(moment, format = "%Y-%m-%dT%H:%M:%S", tz = "Europe/Paris")
    ## [1] "2021-01-05 09:00:00 CET"
    

    or

    as.POSIXct(moment, format = "%Y-%m-%dT%H:%M:%S", tz = "CET")
    ## [1] "2021-01-05 09:00:00 CET"
    

    or extract +01:00 and transform it to Etc/GMT-1 (note sign flip):

    as.POSIXct(moment, format = "%Y-%m-%dT%H:%M:%S",
      tz = chartr("+-", "-+", sub(".*([+-])0?(.*):..$", "Etc/GMT\\1\\2", moment)))
    ## [1] "2021-01-05 09:00:00 +01"