Different parsing behaviour for the first day of April in R as.POSIXct and as.POSIXlt, is R april fooling me?

Viewed 60

I am unexperienced in working with data format in R, and I am struggling to understand the different behaviour with the first of April... is it an april fool?? :)

They have the same format, but it seems that the first day can't be parsed using as.POSIXct (when other dates show no issues) or it does not returns the time zone with as.POSIXlt?

(as.POSIXct("1/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # this doesn't work
(as.POSIXct("2/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # this works
(as.POSIXct("01/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # this doesn't
(as.POSIXct("02/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # this does...

(as.POSIXlt("1/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # This works, but does not returns a time zone
(as.POSIXlt("2/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # This works, and returns a time zone
(as.POSIXlt("01/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # This works, and does not returns a time zone
(as.POSIXlt("02/04/2012 02:58", format = "%d/%m/%Y %H:%M")) # This works, and returns a time zone 

Any direction as to why? Thanks!

2 Answers

This is almost certainly a daylight savings time issue. Not sure why POSIXct and POSIXlt behave differently though. From your profile, it looks like you're in Mexico.

From here:

most of Mexico, including capital Mexico City, will set the clocks 1 hour forward 3 weeks later, on Sunday, April 1, 2012.

So the problem is that 2:58 AM on 1 April 2012 did not exist in the time zone that is currently active in your locale.

Unless there is something specific having to do with the POSIXct/POSIXlt difference, this should probably be closed as a duplicate of e.g.:

And this r help question

If you want to deal with this e.g. by setting all times to UTC (i.e. ignoring your local time zone settings), I believe there are lots of suggestions on Stack Overflow (now that you know to search for "daylight savings time" it should be easy to find them).

obligatory xkcd

@Ben Bolker is correct that this is a daylight saving time issue. Specifically, this is what I call a nonexistent time issue. In Mexico City, on April 1st 2012, there was a DST gap of 1 hour where the clocks jumped from 01:59:59 AM straight to 03:00:00 AM, skipping the two o'clock hour entirely. So 02:58:00 AM is a nonexistent time on that day.

These problems can be really frustrating, so in the clock package I've made parsing issues like this an error by default, with many ways to get around them according to your needs.

For future visitors to this post, here is a reprex with the full output from as.POSIXc/lt() vs clock. The relevant clock function is date_time_parse().

library(clock)

x <- c("1/04/2012 02:58", "2/04/2012 02:58")
zone <- "America/Mexico_City"
format <- "%d/%m/%Y %H:%M"

# Nonexistent time - returns NA
as.POSIXct(x, tz = zone, format = format)
#> [1] NA                        "2012-04-02 02:58:00 CDT"

# Nonexistent time - can't determine zone
as.POSIXlt(x, tz = zone, format = format)
#> [1] "2012-04-01 02:58:00"     "2012-04-02 02:58:00 CDT"

# Errors on nonexistent time so you don't have surprising results
date_time_parse(x, zone = zone, format = format)
#> Error: Nonexistent time due to daylight saving time at location 1.
#> ℹ Resolve nonexistent time issues by specifying the `nonexistent` argument.

# Next valid time
date_time_parse(x, zone = zone, format = format, nonexistent = "roll-forward")
#> [1] "2012-04-01 03:00:00 CDT" "2012-04-02 02:58:00 CDT"

# Previous valid time
date_time_parse(x, zone = zone, format = format, nonexistent = "roll-backward")
#> [1] "2012-04-01 01:59:59 CST" "2012-04-02 02:58:00 CDT"

# Shift forward by the size of the gap (1 hour)
date_time_parse(x, zone = zone, format = format, nonexistent = "shift-forward")
#> [1] "2012-04-01 03:58:00 CDT" "2012-04-02 02:58:00 CDT"

# NA on nonexistent times
date_time_parse(x, zone = zone, format = format, nonexistent = "NA")
#> [1] NA                        "2012-04-02 02:58:00 CDT"
Related