Skip to content

Instantly share code, notes, and snippets.

@mpettis
Last active September 8, 2016 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpettis/0e0249f92c97ce59965f4cb2b9361e2d to your computer and use it in GitHub Desktop.
Save mpettis/0e0249f92c97ce59965f4cb2b9361e2d to your computer and use it in GitHub Desktop.
#!/usr/bin/env Rscript
#library(plyr)
library(dplyr)
library(lubridate)
## Datetimes, 15min increments, that span DST breaks
dt_str <- c(
# Spring forward
"2015-03-08 00:00:00"
, "2015-03-08 00:15:00"
, "2015-03-08 00:30:00"
, "2015-03-08 00:45:00"
, "2015-03-08 01:00:00"
, "2015-03-08 01:15:00"
, "2015-03-08 01:30:00"
, "2015-03-08 01:45:00"
, "2015-03-08 03:00:00"
, "2015-03-08 03:15:00"
, "2015-03-08 03:30:00"
, "2015-03-08 03:45:00"
, "2015-03-08 04:00:00"
# Fall back
, "2015-11-01 00:00:00"
, "2015-11-01 00:15:00"
, "2015-11-01 00:30:00"
, "2015-11-01 00:45:00"
, "2015-11-01 01:00:00"
, "2015-11-01 01:15:00"
, "2015-11-01 01:30:00"
, "2015-11-01 01:45:00"
, "2015-11-01 01:00:00"
, "2015-11-01 01:15:00"
, "2015-11-01 01:30:00"
, "2015-11-01 01:45:00"
, "2015-11-01 02:00:00"
, "2015-11-01 02:15:00"
)
## Put into data.frame
dat <- data.frame(dt_str) %>%
## http://stackoverflow.com/questions/15230446/cumulative-sequence-of-occurrences-of-values
## Add a sequence number, make sure we keep track of row order
mutate(rownum = sequence(n()))
## To convert:
## https://cran.r-project.org/web/packages/lubridate/vignettes/lubridate.html
dat <- dat %>%
## Convert to timezone
mutate(dt_etz = dt_str %>% ymd_hms(tz="America/New_York")) %>%
## Calculate whether or not timestamp is thought to be in DST
mutate(is_dst = dst(dt_etz)) %>%
## For fall back, timestamps duplicated. Keep track of occurrence of timestamp
## http://stackoverflow.com/questions/15230446/cumulative-sequence-of-occurrences-of-values
## Added 'rev()' call to ID the first pass in DST 'fall back' time with
## different identifier as used when there are not duplicate times.
group_by(dt_etz) %>%
mutate(count = n() %>% sequence() %>% rev()) %>%
ungroup() %>%
## Convert to UTC, adjust fall back rows that occurred second
mutate(dt_utc = ifelse(count != 1, with_tz(dt_etz, "UTC") - hours(1), with_tz(dt_etz, "UTC")) %>% as.POSIXct(origin="1970-01-01", tz="UTC"))
dat %>% print.data.frame()
## Check what happens when we cast back UTC time to that repeated hour in fall back DST:
## Both of these map to the 1am hour that gets repeated.
ymd_hms("2015-11-01 05:00:00", tz="UTC") %>% with_tz("America/New_York")
ymd_hms("2015-11-01 06:00:00", tz="UTC") %>% with_tz("America/New_York")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment