Skip to content

Instantly share code, notes, and snippets.

@DavisVaughan
Created March 24, 2023 14:59
Show Gist options
  • Save DavisVaughan/95a3bdb6b11e8e8f00ac671384461c72 to your computer and use it in GitHub Desktop.
Save DavisVaughan/95a3bdb6b11e8e8f00ac671384461c72 to your computer and use it in GitHub Desktop.
zone-transitions
library(clock)
library(purrr)
library(vctrs)
library(tibble)
generate_transitions <- function(zone,
from = date_build(1900, 1, 1),
to = date_build(2030, 1, 1)) {
days <- date_seq(
from = from,
to = to,
by = 1
)
days <- as_sys_time(days)
info <- sys_time_info(days, zone = zone)
# Must choose a unified transition time zone to use for display
info$begin <- as_date_time(info$begin, zone = "UTC")
info$end <- as_date_time(info$end, zone = "UTC")
info$offset <- as.double(info$offset)
info <- vec_unique(info)
info
}
zones <- tzdb_names()
zones <- vec_set_names(zones, zones)
transitions <- map(zones, generate_transitions)
transitions <- list_rbind(transitions, names_to = "zone")
transitions <- as_tibble(transitions)
# All transitions (as long as more than one didn't happen within the same day)
transitions
#> # A tibble: 37,284 × 6
#> zone begin end offset dst abbre…¹
#> <chr> <dttm> <dttm> <dbl> <lgl> <chr>
#> 1 Africa/Abidjan -32767-01-01 00:00… 1912-01-01 00:16:08 -968 FALSE LMT
#> 2 Africa/Abidjan 1912-01-01 00:16:08 32767-12-31 00:00:… 0 FALSE GMT
#> 3 Africa/Accra -32767-01-01 00:00… 1912-01-01 00:16:08 -968 FALSE LMT
#> 4 Africa/Accra 1912-01-01 00:16:08 32767-12-31 00:00:… 0 FALSE GMT
#> 5 Africa/Addis_Ab… -32767-01-01 00:00… 1908-04-30 21:32:44 8836 FALSE LMT
#> 6 Africa/Addis_Ab… 1908-04-30 21:32:44 1928-06-30 21:30:00 9000 FALSE +0230
#> 7 Africa/Addis_Ab… 1928-06-30 21:30:00 1930-01-04 21:00:00 10800 FALSE EAT
#> 8 Africa/Addis_Ab… 1930-01-04 21:00:00 1936-12-31 21:30:00 9000 FALSE +0230
#> 9 Africa/Addis_Ab… 1936-12-31 21:30:00 1942-07-31 21:15:00 9900 FALSE +0245
#> 10 Africa/Addis_Ab… 1942-07-31 21:15:00 32767-12-31 00:00:… 10800 FALSE EAT
#> # … with 37,274 more rows, and abbreviated variable name ¹​abbreviation
# Look just at the east coast in 2023
ny <- vec_slice(transitions, transitions$zone == "America/New_York")
ny
#> # A tibble: 224 × 6
#> zone begin end offset dst abbre…¹
#> <chr> <dttm> <dttm> <dbl> <lgl> <chr>
#> 1 America/New_York 1883-11-18 17:00:00 1918-03-31 07:00:00 -18000 FALSE EST
#> 2 America/New_York 1918-03-31 07:00:00 1918-10-27 06:00:00 -14400 TRUE EDT
#> 3 America/New_York 1918-10-27 06:00:00 1919-03-30 07:00:00 -18000 FALSE EST
#> 4 America/New_York 1919-03-30 07:00:00 1919-10-26 06:00:00 -14400 TRUE EDT
#> 5 America/New_York 1919-10-26 06:00:00 1920-01-01 05:00:00 -18000 FALSE EST
#> 6 America/New_York 1920-01-01 05:00:00 1920-03-28 07:00:00 -18000 FALSE EST
#> 7 America/New_York 1920-03-28 07:00:00 1920-10-31 06:00:00 -14400 TRUE EDT
#> 8 America/New_York 1920-10-31 06:00:00 1921-04-24 07:00:00 -18000 FALSE EST
#> 9 America/New_York 1921-04-24 07:00:00 1921-09-25 06:00:00 -14400 TRUE EDT
#> 10 America/New_York 1921-09-25 06:00:00 1922-04-30 07:00:00 -18000 FALSE EST
#> # … with 214 more rows, and abbreviated variable name ¹​abbreviation
# Now that we just have America/New_York rows, we can localize them
ny$begin <- date_set_zone(ny$begin, "America/New_York")
ny$end <- date_set_zone(ny$end, "America/New_York")
# 2023-03-12 03:00:00 is the one that just occurred
vec_slice(ny, get_year(ny$begin) == 2023 | get_year(ny$end) == 2023)
#> # A tibble: 3 × 6
#> zone begin end offset dst abbrev…¹
#> <chr> <dttm> <dttm> <dbl> <lgl> <chr>
#> 1 America/New_York 2022-11-06 01:00:00 2023-03-12 03:00:00 -18000 FALSE EST
#> 2 America/New_York 2023-03-12 03:00:00 2023-11-05 01:00:00 -14400 TRUE EDT
#> 3 America/New_York 2023-11-05 01:00:00 2024-03-10 03:00:00 -18000 FALSE EST
#> # … with abbreviated variable name ¹​abbreviation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment