class: center, middle, title-slide .title[ # Dates and Times ] .author[ ### Luke Tierney ] .institute[ ### University of Iowa ] .date[ ### 2023-05-05 ] --- layout: true <link rel="stylesheet" href="stat4580.css" type="text/css" /> <style type="text/css"> .remark-code { font-size: 85%; } </style> ## Background --- Data are often associated with a point in time, a particular -- * year; -- * month; -- * day; -- * hour, minute, second, ... -- Some issues with points in time: -- * Leap years and leap seconds. -- * Daylight saving time. -- * Local time or [_Coordinated Universal Time (UTC)_](https://www.timeanddate.com/time/aboututc.html). -- * For historical data: changes in calendars. --- R has data types to represent -- * a particular date (`Date`); -- * a particular second (`POSIXct`, date-time). -- R stores dates as days since January 1, 1970, and date-times as the the number of seconds since midnight on that day in [_Coordinated Universal Time_ (UTC)](https://www.timeanddate.com/time/aboututc.html). -- Date objects are less complicated than data-time objects, so if you only need dates you should stick with date objects. -- Base R provides many facilities for dealing with dates and date-times. -- The `lubridate` package provides a useful interface. ```r library(lubridate) ``` -- The [_Dates and Times_ chapter](https://r4ds.had.co.nz/dates-and-times.html) of [_R for Data Science_](https://r4ds.had.co.nz/) provides more details. --- layout: true ## Creating Dates and Times --- ### Today and Now .pull-left.code-80[ The `lubridate` function `today()` returns today's date as a `Date` object: ```r today() ## [1] "2023-05-05" ``` {{content}} ] -- ```r class(today()) ## [1] "Date" ``` {{content}} -- The `lubridate` function `now()` returns the current date-time as a `POSIXct` object: ```r now() ## [1] "2023-05-05 15:52:56 CDT" ``` {{content}} -- ```r class(now()) ## [1] "POSIXct" "POSIXt" ``` -- .pull-right.code-80[ The printed representation follows the international standard for the representation of dates and times ([ISO8601](https://en.wikipedia.org/wiki/ISO_8601)). {{content}} ] -- Date and date-time objects can be used with addition and subtraction: {{content}} -- ```r now() + 3600 ## one hour from now ## [1] "2023-05-05 16:52:56 CDT" ``` {{content}} -- ```r today() - 7 ## one week ago ## [1] "2023-04-28" ``` --- ### Parsing Dates and Times From Strings .pull-left.code-80[ Some common date formats: ```r d1 <- "2023-04-16" d2 <- "April 16, 2023" d3 <- "16 April 2023" d4 <- "16 April 23" ``` ] -- .pull-right.code-80[ These can be decoded by the functions `ymd()`, `mdy()`, and `dmy()`: {{content}} ] -- ```r ymd(d1) ## [1] "2023-04-16" ``` {{content}} -- ```r mdy(d2) ## [1] "2023-04-16" ``` {{content}} -- ```r dmy(d3) ## [1] "2023-04-16" ``` {{content}} -- ```r dmy(d4) ## [1] "2023-04-16" ``` --- .pull-left.code-80[ By default, these functions use the current _locale_ settings for interpreting month names or abbreviations. {{content}} ] -- ```r Sys.getlocale("LC_TIME") ## [1] "en_US.UTF-8" ``` {{content}} -- If you need to parse a French date you might use ```r dmy("16 Avril, 2023", locale = "fr_FR.UTF-8") ## [1] "2023-04-16" ``` -- .pull-right.code-80[ Date-times can be decoded with functions like `mdy_hm`: ```r mdy_hm("April 16, 2023, 6:15 PM") ## [1] "2023-04-16 18:15:00 UTC" ``` {{content}} ] -- or ```r mdy_hms("April 16, 2023, 6:15:08 PM") ## [1] "2023-04-16 18:15:08 UTC" ``` {{content}} -- By default these assume the time is specified in the UTC time zone. --- .pull-left.code-80[ ### Creating Dates and Times from Components Dates can be created from year, month, and day by `make_date()`: {{content}} ] -- ```r make_date(2023, 4, 16) ## [1] "2023-04-16" ``` {{content}} -- Creating a `date` variable from the `year`, `month`, and `day` variables in the New York City `flights` table: ```r library(nycflights13) fl <- mutate(flights, date = make_date(year, month, day)) ``` {{content}} -- `ggplot` and other graphics systems know how to make useful axis labels for dates: -- .pull-right[ .hide-code[ ```r ggplot(count(fl, date)) + geom_line(aes(x = date, y = n)) ``` <img src="datetime_files/figure-html/unnamed-chunk-19-1.png" style="display: block; margin: auto;" /> ] {{content}} ] -- Weekday/weekend differenes are clearly visible. --- .pull-left.code-80[ Date-times can be created from year, month, day, hour, minute, and second using `make_datetime()`: {{content}} ] -- ```r make_datetime(2023, 4, 16, 18, 15) ## [1] "2023-04-16 18:15:00 UTC" ``` {{content}} -- An attempt to recreate the `time_hour` variable in the flights table: ```r fl <- mutate(fl, th = make_datetime(year, month, day, hour)) ``` {{content}} -- This does not quite re-create the `time_hour` variable: ```r identical(fl$th, fl$time_hour) ## [1] FALSE ``` -- .pull-right.code-80[ ```r fl$th[1] ## [1] "2013-01-01 05:00:00 UTC" fl$time_hour[1] ## [1] "2013-01-01 05:00:00 EST" ``` {{content}} ] -- By default, `make_datetime()` assumes the time points it is given are in UTC. {{content}} -- The `time_hour` variable is using local (eastern US) time. {{content}} -- We will look at time zones more [below](#time-zones). --- layout: true ## Date and Time Components --- Components of dates and date-times can be extracted with: * `year()`, `month()`, `day()`, `hour()`, `minute()`, `second()` * `yday()` -- day of the year * `mday()` -- day of the month, same as `day` * `wday()` -- day of the week -- By default, `wday()` returns an integer: .code-80[ ```r wday(today()) ## [1] 6 ``` ] -- But it can also return a label: .code-80[ ```r wday(today(), label = TRUE) ## [1] Fri ## Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat ``` ] .code-80[ ```r wday(today(), label = TRUE, abbr = FALSE) ## [1] Friday ## 7 Levels: Sunday < Monday < Tuesday < Wednesday < Thursday < ... < Saturday ``` ] --- Weekday names and abbreviations are obviously locale-specific, and you can specify an alternative to the default current locale: -- ```r wday(today(), label = TRUE, abbr = FALSE, locale = "de_DE.UTF-8") ## [1] Freitag ## 7 Levels: Sonntag < Montag < Dienstag < Mittwoch < Donnerstag < ... < Samstag ``` -- ```r wday(today(), label = TRUE, locale = "de_DE.UTF-8") ## [1] Fr ## Levels: So < Mo < Di < Mi < Do < Fr < Sa ``` -- Even the integer value can be tricky: -- * In the US, Canada, Japan the first day of the week is Sunday. -- * In Germany, France, and the ISO8601 standard the first day of the week is Monday. -- `wday()` can be asked to use a different first day, and a global default can be set. --- .pull-left.code-80[ Using `wday()` and the `date` variable we can look at the distribution of the number of flights by day of the week: {{content}} ] -- ```r ggplot(fl, aes(x = wday(date, label = TRUE))) + geom_bar(fill = "deepskyblue3") ``` -- .pull-right[ <img src="datetime_files/figure-html/flights-wday-1.png" style="display: block; margin: auto;" /> {{content}} ] -- There were substantially fewer flights on Saturdays but only slightly fewer flights on Sundays. --- layout: false ## Rounding .pull-left[ `floor_date()`, `round_date()`, and `ceiling_date()` can be used to round to a particular unit; the most useful are `week` and `quarter`. {{content}} ] -- Flights by week: <img src="datetime_files/figure-html/unnamed-chunk-29-1.png" style="display: block; margin: auto;" /> -- .pull-right[ The first and last weeks were incomplete: ```r as.character(wday(ymd("2013-01-01"), label = TRUE, abbr = FALSE)) ## [1] "Tuesday" ``` ```r as.character(wday(ymd("2013-12-31"), label = TRUE, abbr = FALSE)) ## [1] "Tuesday" ``` ] --- layout: true ## Time Spans --- Subtracting dates or date-times produces `difftime` objects: -- ```r now() - as_datetime(today()) ## Time difference of 20.88339 hours ``` -- ```r today() - ymd("2023-01-01") ## Time difference of 124 days ``` -- Working with different units can be awkward; `lubridate` provides _durations_, which always work in seconds: -- ```r as.duration(now() - as_datetime(today())) ## [1] "75180.1998090744s (~20.88 hours)" ``` -- ```r as.duration(today() - ymd("2023-01-01")) ## [1] "10713600s (~17.71 weeks)" ``` --- Durations can be created with `dyears()`, `ddays()`, `dweeks()`, etc.: -- ```r dyears(1) ## [1] "31557600s (~1 years)" ``` -- ```r ddays(1) ## [1] "86400s (~1 days)" ``` -- Durations can be added to a date or date-time object and can be multiplied by a number: -- .pull-left[ ```r today() ## [1] "2023-05-05" ``` {{content}} ] -- ```r today() + ddays(2) ## [1] "2023-05-07" ``` {{content}} -- ```r today() + 2 * ddays(1) ## [1] "2023-05-07" ``` -- .pull-right[ ```r (n1 <- now()) ## [1] "2023-05-05 15:53:00 CDT" ``` {{content}} ] -- ```r n1 + dminutes(3) ## [1] "2023-05-05 15:56:00 CDT" ``` --- Duations represent an exact number of seconds, which can lead to surprises when DST is involved. -- In 2023 the switch to DST happened in the US on March 12: -- ```r ymd_hm("2023-03-11 23:02", tz = "America/Chicago") + ddays(1) ## [1] "2023-03-13 00:02:00 CDT" ``` -- _Periods_ are an alternative that may work more intuitively. -- Periods are constructed with `years()`, `months()`, `days()`, etc: -- ```r ymd_hm("2023-03-11 23:02", tz = "America/Chicago") + days(1) ## [1] "2023-03-12 23:02:00 CDT" ``` --- layout: true ## Time Zones --- name: time-zones Date-time objects specify a point in time relative to second zero, minute zero, hour zero, on January 1, 1970 in [Coordinated Universal Time (UTC)](https://www.timeanddate.com/time/aboututc.html). -- Date-time objects can have a time zone associated with them that affects how they are printed. -- `now()` returns a date-time object with the time zone set as the local time zone of the computer. ```r now() ## [1] "2023-05-05 15:53:00 CDT" ``` -- Time zones are complex, they can change on a regular basis (DST) or as a result of politics. -- When a date-time object is created from components, by default it is given the UTC time zone. --- To create a point in time based on local time information, such as 10 AM on April 16, 2023, in Iowa City, a time zone for interpreting the local time needs to be specified. -- The short notations like CDT are not adequate for this: Both the US and Australia have EST, which are quite different. -- R uses the [_Internet Assigned Numbers Authority_ (IANA)](https://www.iana.org/time-zones) naming convention and data base. -- The local time zone is: ```r Sys.timezone() ## [1] "America/Chicago" ``` -- The time point 10:00:00 AM on April 16, 2023 in Iowa City can be specified as ```r (tm <- make_datetime(2023, 4, 16, 10, tz = "America/Chicago")) ## [1] "2023-04-16 10:00:00 CDT" ``` --- Time zones of date-time objects can be changed in two ways: -- * `with_tz` keeps the instant in time and changes the time zone used for display. -- * `force_tz` changes the instant in time; use this if the time zone is incorrectly specified but the clock time is correct. -- The available time zone specifications are contained in `OlsonNames`: .scroll-box-10[ ```r OlsonNames() ## [1] "Africa/Abidjan" "Africa/Accra" ## [3] "Africa/Addis_Ababa" "Africa/Algiers" ## [5] "Africa/Asmara" "Africa/Asmera" ## [7] "Africa/Bamako" "Africa/Bangui" ## [9] "Africa/Banjul" "Africa/Bissau" ## [11] "Africa/Blantyre" "Africa/Brazzaville" ## [13] "Africa/Bujumbura" "Africa/Cairo" ## [15] "Africa/Casablanca" "Africa/Ceuta" ## [17] "Africa/Conakry" "Africa/Dakar" ## [19] "Africa/Dar_es_Salaam" "Africa/Djibouti" ## [21] "Africa/Douala" "Africa/El_Aaiun" ## [23] "Africa/Freetown" "Africa/Gaborone" ## [25] "Africa/Harare" "Africa/Johannesburg" ## [27] "Africa/Juba" "Africa/Kampala" ## [29] "Africa/Khartoum" "Africa/Kigali" ## [31] "Africa/Kinshasa" "Africa/Lagos" ## [33] "Africa/Libreville" "Africa/Lome" ## [35] "Africa/Luanda" "Africa/Lubumbashi" ## [37] "Africa/Lusaka" "Africa/Malabo" ## [39] "Africa/Maputo" "Africa/Maseru" ## [41] "Africa/Mbabane" "Africa/Mogadishu" ## [43] "Africa/Monrovia" "Africa/Nairobi" ## [45] "Africa/Ndjamena" "Africa/Niamey" ## [47] "Africa/Nouakchott" "Africa/Ouagadougou" ## [49] "Africa/Porto-Novo" "Africa/Sao_Tome" ## [51] "Africa/Timbuktu" "Africa/Tripoli" ## [53] "Africa/Tunis" "Africa/Windhoek" ## [55] "America/Adak" "America/Anchorage" ## [57] "America/Anguilla" "America/Antigua" ## [59] "America/Araguaina" "America/Argentina/Buenos_Aires" ## [61] "America/Argentina/Catamarca" "America/Argentina/ComodRivadavia" ## [63] "America/Argentina/Cordoba" "America/Argentina/Jujuy" ## [65] "America/Argentina/La_Rioja" "America/Argentina/Mendoza" ## [67] "America/Argentina/Rio_Gallegos" "America/Argentina/Salta" ## [69] "America/Argentina/San_Juan" "America/Argentina/San_Luis" ## [71] "America/Argentina/Tucuman" "America/Argentina/Ushuaia" ## [73] "America/Aruba" "America/Asuncion" ## [75] "America/Atikokan" "America/Atka" ## [77] "America/Bahia" "America/Bahia_Banderas" ## [79] "America/Barbados" "America/Belem" ## [81] "America/Belize" "America/Blanc-Sablon" ## [83] "America/Boa_Vista" "America/Bogota" ## [85] "America/Boise" "America/Buenos_Aires" ## [87] "America/Cambridge_Bay" "America/Campo_Grande" ## [89] "America/Cancun" "America/Caracas" ## [91] "America/Catamarca" "America/Cayenne" ## [93] "America/Cayman" "America/Chicago" ## [95] "America/Chihuahua" "America/Ciudad_Juarez" ## [97] "America/Coral_Harbour" "America/Cordoba" ## [99] "America/Costa_Rica" "America/Creston" ## [101] "America/Cuiaba" "America/Curacao" ## [103] "America/Danmarkshavn" "America/Dawson" ## [105] "America/Dawson_Creek" "America/Denver" ## [107] "America/Detroit" "America/Dominica" ## [109] "America/Edmonton" "America/Eirunepe" ## [111] "America/El_Salvador" "America/Ensenada" ## [113] "America/Fort_Nelson" "America/Fort_Wayne" ## [115] "America/Fortaleza" "America/Glace_Bay" ## [117] "America/Godthab" "America/Goose_Bay" ## [119] "America/Grand_Turk" "America/Grenada" ## [121] "America/Guadeloupe" "America/Guatemala" ## [123] "America/Guayaquil" "America/Guyana" ## [125] "America/Halifax" "America/Havana" ## [127] "America/Hermosillo" "America/Indiana/Indianapolis" ## [129] "America/Indiana/Knox" "America/Indiana/Marengo" ## [131] "America/Indiana/Petersburg" "America/Indiana/Tell_City" ## [133] "America/Indiana/Vevay" "America/Indiana/Vincennes" ## [135] "America/Indiana/Winamac" "America/Indianapolis" ## [137] "America/Inuvik" "America/Iqaluit" ## [139] "America/Jamaica" "America/Jujuy" ## [141] "America/Juneau" "America/Kentucky/Louisville" ## [143] "America/Kentucky/Monticello" "America/Knox_IN" ## [145] "America/Kralendijk" "America/La_Paz" ## [147] "America/Lima" "America/Los_Angeles" ## [149] "America/Louisville" "America/Lower_Princes" ## [151] "America/Maceio" "America/Managua" ## [153] "America/Manaus" "America/Marigot" ## [155] "America/Martinique" "America/Matamoros" ## [157] "America/Mazatlan" "America/Mendoza" ## [159] "America/Menominee" "America/Merida" ## [161] "America/Metlakatla" "America/Mexico_City" ## [163] "America/Miquelon" "America/Moncton" ## [165] "America/Monterrey" "America/Montevideo" ## [167] "America/Montreal" "America/Montserrat" ## [169] "America/Nassau" "America/New_York" ## [171] "America/Nipigon" "America/Nome" ## [173] "America/Noronha" "America/North_Dakota/Beulah" ## [175] "America/North_Dakota/Center" "America/North_Dakota/New_Salem" ## [177] "America/Nuuk" "America/Ojinaga" ## [179] "America/Panama" "America/Pangnirtung" ## [181] "America/Paramaribo" "America/Phoenix" ## [183] "America/Port_of_Spain" "America/Port-au-Prince" ## [185] "America/Porto_Acre" "America/Porto_Velho" ## [187] "America/Puerto_Rico" "America/Punta_Arenas" ## [189] "America/Rainy_River" "America/Rankin_Inlet" ## [191] "America/Recife" "America/Regina" ## [193] "America/Resolute" "America/Rio_Branco" ## [195] "America/Rosario" "America/Santa_Isabel" ## [197] "America/Santarem" "America/Santiago" ## [199] "America/Santo_Domingo" "America/Sao_Paulo" ## [201] "America/Scoresbysund" "America/Shiprock" ## [203] "America/Sitka" "America/St_Barthelemy" ## [205] "America/St_Johns" "America/St_Kitts" ## [207] "America/St_Lucia" "America/St_Thomas" ## [209] "America/St_Vincent" "America/Swift_Current" ## [211] "America/Tegucigalpa" "America/Thule" ## [213] "America/Thunder_Bay" "America/Tijuana" ## [215] "America/Toronto" "America/Tortola" ## [217] "America/Vancouver" "America/Virgin" ## [219] "America/Whitehorse" "America/Winnipeg" ## [221] "America/Yakutat" "America/Yellowknife" ## [223] "Antarctica/Casey" "Antarctica/Davis" ## [225] "Antarctica/DumontDUrville" "Antarctica/Macquarie" ## [227] "Antarctica/Mawson" "Antarctica/McMurdo" ## [229] "Antarctica/Palmer" "Antarctica/Rothera" ## [231] "Antarctica/South_Pole" "Antarctica/Syowa" ## [233] "Antarctica/Troll" "Antarctica/Vostok" ## [235] "Arctic/Longyearbyen" "Asia/Aden" ## [237] "Asia/Almaty" "Asia/Amman" ## [239] "Asia/Anadyr" "Asia/Aqtau" ## [241] "Asia/Aqtobe" "Asia/Ashgabat" ## [243] "Asia/Ashkhabad" "Asia/Atyrau" ## [245] "Asia/Baghdad" "Asia/Bahrain" ## [247] "Asia/Baku" "Asia/Bangkok" ## [249] "Asia/Barnaul" "Asia/Beirut" ## [251] "Asia/Bishkek" "Asia/Brunei" ## [253] "Asia/Calcutta" "Asia/Chita" ## [255] "Asia/Choibalsan" "Asia/Chongqing" ## [257] "Asia/Chungking" "Asia/Colombo" ## [259] "Asia/Dacca" "Asia/Damascus" ## [261] "Asia/Dhaka" "Asia/Dili" ## [263] "Asia/Dubai" "Asia/Dushanbe" ## [265] "Asia/Famagusta" "Asia/Gaza" ## [267] "Asia/Hanoi" "Asia/Harbin" ## [269] "Asia/Hebron" "Asia/Ho_Chi_Minh" ## [271] "Asia/Hong_Kong" "Asia/Hovd" ## [273] "Asia/Irkutsk" "Asia/Istanbul" ## [275] "Asia/Jakarta" "Asia/Jayapura" ## [277] "Asia/Jerusalem" "Asia/Kabul" ## [279] "Asia/Kamchatka" "Asia/Karachi" ## [281] "Asia/Kashgar" "Asia/Kathmandu" ## [283] "Asia/Katmandu" "Asia/Khandyga" ## [285] "Asia/Kolkata" "Asia/Krasnoyarsk" ## [287] "Asia/Kuala_Lumpur" "Asia/Kuching" ## [289] "Asia/Kuwait" "Asia/Macao" ## [291] "Asia/Macau" "Asia/Magadan" ## [293] "Asia/Makassar" "Asia/Manila" ## [295] "Asia/Muscat" "Asia/Nicosia" ## [297] "Asia/Novokuznetsk" "Asia/Novosibirsk" ## [299] "Asia/Omsk" "Asia/Oral" ## [301] "Asia/Phnom_Penh" "Asia/Pontianak" ## [303] "Asia/Pyongyang" "Asia/Qatar" ## [305] "Asia/Qostanay" "Asia/Qyzylorda" ## [307] "Asia/Rangoon" "Asia/Riyadh" ## [309] "Asia/Saigon" "Asia/Sakhalin" ## [311] "Asia/Samarkand" "Asia/Seoul" ## [313] "Asia/Shanghai" "Asia/Singapore" ## [315] "Asia/Srednekolymsk" "Asia/Taipei" ## [317] "Asia/Tashkent" "Asia/Tbilisi" ## [319] "Asia/Tehran" "Asia/Tel_Aviv" ## [321] "Asia/Thimbu" "Asia/Thimphu" ## [323] "Asia/Tokyo" "Asia/Tomsk" ## [325] "Asia/Ujung_Pandang" "Asia/Ulaanbaatar" ## [327] "Asia/Ulan_Bator" "Asia/Urumqi" ## [329] "Asia/Ust-Nera" "Asia/Vientiane" ## [331] "Asia/Vladivostok" "Asia/Yakutsk" ## [333] "Asia/Yangon" "Asia/Yekaterinburg" ## [335] "Asia/Yerevan" "Atlantic/Azores" ## [337] "Atlantic/Bermuda" "Atlantic/Canary" ## [339] "Atlantic/Cape_Verde" "Atlantic/Faeroe" ## [341] "Atlantic/Faroe" "Atlantic/Jan_Mayen" ## [343] "Atlantic/Madeira" "Atlantic/Reykjavik" ## [345] "Atlantic/South_Georgia" "Atlantic/St_Helena" ## [347] "Atlantic/Stanley" "Australia/ACT" ## [349] "Australia/Adelaide" "Australia/Brisbane" ## [351] "Australia/Broken_Hill" "Australia/Canberra" ## [353] "Australia/Currie" "Australia/Darwin" ## [355] "Australia/Eucla" "Australia/Hobart" ## [357] "Australia/LHI" "Australia/Lindeman" ## [359] "Australia/Lord_Howe" "Australia/Melbourne" ## [361] "Australia/North" "Australia/NSW" ## [363] "Australia/Perth" "Australia/Queensland" ## [365] "Australia/South" "Australia/Sydney" ## [367] "Australia/Tasmania" "Australia/Victoria" ## [369] "Australia/West" "Australia/Yancowinna" ## [371] "Brazil/Acre" "Brazil/DeNoronha" ## [373] "Brazil/East" "Brazil/West" ## [375] "Canada/Atlantic" "Canada/Central" ## [377] "Canada/Eastern" "Canada/Mountain" ## [379] "Canada/Newfoundland" "Canada/Pacific" ## [381] "Canada/Saskatchewan" "Canada/Yukon" ## [383] "CET" "Chile/Continental" ## [385] "Chile/EasterIsland" "CST6CDT" ## [387] "Cuba" "EET" ## [389] "Egypt" "Eire" ## [391] "EST" "EST5EDT" ## [393] "Etc/GMT" "Etc/GMT-0" ## [395] "Etc/GMT-1" "Etc/GMT-10" ## [397] "Etc/GMT-11" "Etc/GMT-12" ## [399] "Etc/GMT-13" "Etc/GMT-14" ## [401] "Etc/GMT-2" "Etc/GMT-3" ## [403] "Etc/GMT-4" "Etc/GMT-5" ## [405] "Etc/GMT-6" "Etc/GMT-7" ## [407] "Etc/GMT-8" "Etc/GMT-9" ## [409] "Etc/GMT+0" "Etc/GMT+1" ## [411] "Etc/GMT+10" "Etc/GMT+11" ## [413] "Etc/GMT+12" "Etc/GMT+2" ## [415] "Etc/GMT+3" "Etc/GMT+4" ## [417] "Etc/GMT+5" "Etc/GMT+6" ## [419] "Etc/GMT+7" "Etc/GMT+8" ## [421] "Etc/GMT+9" "Etc/GMT0" ## [423] "Etc/Greenwich" "Etc/UCT" ## [425] "Etc/Universal" "Etc/UTC" ## [427] "Etc/Zulu" "Europe/Amsterdam" ## [429] "Europe/Andorra" "Europe/Astrakhan" ## [431] "Europe/Athens" "Europe/Belfast" ## [433] "Europe/Belgrade" "Europe/Berlin" ## [435] "Europe/Bratislava" "Europe/Brussels" ## [437] "Europe/Bucharest" "Europe/Budapest" ## [439] "Europe/Busingen" "Europe/Chisinau" ## [441] "Europe/Copenhagen" "Europe/Dublin" ## [443] "Europe/Gibraltar" "Europe/Guernsey" ## [445] "Europe/Helsinki" "Europe/Isle_of_Man" ## [447] "Europe/Istanbul" "Europe/Jersey" ## [449] "Europe/Kaliningrad" "Europe/Kiev" ## [451] "Europe/Kirov" "Europe/Kyiv" ## [453] "Europe/Lisbon" "Europe/Ljubljana" ## [455] "Europe/London" "Europe/Luxembourg" ## [457] "Europe/Madrid" "Europe/Malta" ## [459] "Europe/Mariehamn" "Europe/Minsk" ## [461] "Europe/Monaco" "Europe/Moscow" ## [463] "Europe/Nicosia" "Europe/Oslo" ## [465] "Europe/Paris" "Europe/Podgorica" ## [467] "Europe/Prague" "Europe/Riga" ## [469] "Europe/Rome" "Europe/Samara" ## [471] "Europe/San_Marino" "Europe/Sarajevo" ## [473] "Europe/Saratov" "Europe/Simferopol" ## [475] "Europe/Skopje" "Europe/Sofia" ## [477] "Europe/Stockholm" "Europe/Tallinn" ## [479] "Europe/Tirane" "Europe/Tiraspol" ## [481] "Europe/Ulyanovsk" "Europe/Uzhgorod" ## [483] "Europe/Vaduz" "Europe/Vatican" ## [485] "Europe/Vienna" "Europe/Vilnius" ## [487] "Europe/Volgograd" "Europe/Warsaw" ## [489] "Europe/Zagreb" "Europe/Zaporozhye" ## [491] "Europe/Zurich" "Factory" ## [493] "GB" "GB-Eire" ## [495] "GMT" "GMT-0" ## [497] "GMT+0" "GMT0" ## [499] "Greenwich" "Hongkong" ## [501] "HST" "Iceland" ## [503] "Indian/Antananarivo" "Indian/Chagos" ## [505] "Indian/Christmas" "Indian/Cocos" ## [507] "Indian/Comoro" "Indian/Kerguelen" ## [509] "Indian/Mahe" "Indian/Maldives" ## [511] "Indian/Mauritius" "Indian/Mayotte" ## [513] "Indian/Reunion" "Iran" ## [515] "Israel" "Jamaica" ## [517] "Japan" "Kwajalein" ## [519] "Libya" "MET" ## [521] "Mexico/BajaNorte" "Mexico/BajaSur" ## [523] "Mexico/General" "MST" ## [525] "MST7MDT" "Navajo" ## [527] "NZ" "NZ-CHAT" ## [529] "Pacific/Apia" "Pacific/Auckland" ## [531] "Pacific/Bougainville" "Pacific/Chatham" ## [533] "Pacific/Chuuk" "Pacific/Easter" ## [535] "Pacific/Efate" "Pacific/Enderbury" ## [537] "Pacific/Fakaofo" "Pacific/Fiji" ## [539] "Pacific/Funafuti" "Pacific/Galapagos" ## [541] "Pacific/Gambier" "Pacific/Guadalcanal" ## [543] "Pacific/Guam" "Pacific/Honolulu" ## [545] "Pacific/Johnston" "Pacific/Kanton" ## [547] "Pacific/Kiritimati" "Pacific/Kosrae" ## [549] "Pacific/Kwajalein" "Pacific/Majuro" ## [551] "Pacific/Marquesas" "Pacific/Midway" ## [553] "Pacific/Nauru" "Pacific/Niue" ## [555] "Pacific/Norfolk" "Pacific/Noumea" ## [557] "Pacific/Pago_Pago" "Pacific/Palau" ## [559] "Pacific/Pitcairn" "Pacific/Pohnpei" ## [561] "Pacific/Ponape" "Pacific/Port_Moresby" ## [563] "Pacific/Rarotonga" "Pacific/Saipan" ## [565] "Pacific/Samoa" "Pacific/Tahiti" ## [567] "Pacific/Tarawa" "Pacific/Tongatapu" ## [569] "Pacific/Truk" "Pacific/Wake" ## [571] "Pacific/Wallis" "Pacific/Yap" ## [573] "Poland" "Portugal" ## [575] "PRC" "PST8PDT" ## [577] "ROC" "ROK" ## [579] "Singapore" "Turkey" ## [581] "UCT" "Universal" ## [583] "US/Alaska" "US/Aleutian" ## [585] "US/Arizona" "US/Central" ## [587] "US/East-Indiana" "US/Eastern" ## [589] "US/Hawaii" "US/Indiana-Starke" ## [591] "US/Michigan" "US/Mountain" ## [593] "US/Pacific" "US/Samoa" ## [595] "UTC" "W-SU" ## [597] "WET" "Zulu" ## attr(,"Version") ## [1] "2023c" ``` ] --- The instant `tm` in some other time zones: -- .pull-left[ ```r with_tz(tm, tz = "UTC") ## [1] "2023-04-16 15:00:00 UTC" ``` {{content}} ] -- ```r with_tz(tm, tz = "America/New_York") ## [1] "2023-04-16 11:00:00 EDT" ``` {{content}} -- ```r with_tz(tm, tz = "Asia/Shanghai") ## [1] "2023-04-16 23:00:00 CST" ``` {{content}} -- ```r with_tz(tm, tz = "Pacific/Auckland") ## [1] "2023-04-17 03:00:00 NZST" ``` -- .pull-right[ ```r with_tz(tm, tz = "Asia/Kolkata") ## [1] "2023-04-16 20:30:00 IST" ``` {{content}} ] -- ```r with_tz(tm, tz = "Canada/Newfoundland") ## [1] "2023-04-16 12:30:00 NDT" ``` {{content}} -- ```r with_tz(tm, tz = "Asia/Katmandu") ## [1] "2023-04-16 20:45:00 +0545" ``` --- Some more examples: .pull-left.small-code.scroll-box-20[ ```r ## All offsets that are not a full hour: get_offset <- function(z) abs(minute(with_tz(tm, tz = z)) - minute(tm)) offsets <- data.frame(zone = OlsonNames()) %>% mutate(offset = sapply(zone, get_offset)) %>% arrange(offset) filter(offsets, offset != 0) ## zone offset ## 1 America/St_Johns 30 ## 2 Asia/Calcutta 30 ## 3 Asia/Colombo 30 ## 4 Asia/Kabul 30 ## 5 Asia/Kolkata 30 ## 6 Asia/Rangoon 30 ## 7 Asia/Tehran 30 ## 8 Asia/Yangon 30 ## 9 Australia/Adelaide 30 ## 10 Australia/Broken_Hill 30 ## 11 Australia/Darwin 30 ## 12 Australia/LHI 30 ## 13 Australia/Lord_Howe 30 ## 14 Australia/North 30 ## 15 Australia/South 30 ## 16 Australia/Yancowinna 30 ## 17 Canada/Newfoundland 30 ## 18 Indian/Cocos 30 ## 19 Iran 30 ## 20 Pacific/Marquesas 30 ## 21 Asia/Kathmandu 45 ## 22 Asia/Katmandu 45 ## 23 Australia/Eucla 45 ## 24 NZ-CHAT 45 ## 25 Pacific/Chatham 45 ``` ] .pull-right.small-code.scroll-box-20[ ```r ## Offsets for Australia: filter(offsets, grepl("Australia", zone)) ## zone offset ## 1 Australia/ACT 0 ## 2 Australia/Brisbane 0 ## 3 Australia/Canberra 0 ## 4 Australia/Currie 0 ## 5 Australia/Hobart 0 ## 6 Australia/Lindeman 0 ## 7 Australia/Melbourne 0 ## 8 Australia/NSW 0 ## 9 Australia/Perth 0 ## 10 Australia/Queensland 0 ## 11 Australia/Sydney 0 ## 12 Australia/Tasmania 0 ## 13 Australia/Victoria 0 ## 14 Australia/West 0 ## 15 Australia/Adelaide 30 ## 16 Australia/Broken_Hill 30 ## 17 Australia/Darwin 30 ## 18 Australia/LHI 30 ## 19 Australia/Lord_Howe 30 ## 20 Australia/North 30 ## 21 Australia/South 30 ## 22 Australia/Yancowinna 30 ## 23 Australia/Eucla 45 ``` ] --- If we create the `th` variable for the flights data as ```r fl <- mutate(flights, th = make_datetime(year, month, day, hour, tz = "America/New_York")) ``` -- then the result matches the `date_time` variable: ```r identical(fl$th, fl$time_hour) ## [1] TRUE ``` --- The `time_hour` variable in the `weather` table reflects actual points in time and, together with `origin`, can serve as a primary key: ```r filter(count(weather, origin, time_hour), n > 1) ## # A tibble: 0 × 3 ## # ℹ 3 variables: origin <chr>, time_hour <dttm>, n <int> ``` -- The `month`, `day`, `hour` variables are confused by the time change. -- .pull-left.code-80[ In November there is a repeat: ```r count(weather, origin, month, day, hour) %>% filter(n > 1) ## # A tibble: 3 × 5 ## origin month day hour n ## <chr> <int> <int> <int> <int> ## 1 EWR 11 3 1 2 ## 2 JFK 11 3 1 2 ## 3 LGA 11 3 1 2 ``` ] -- .pull-right.code-80[ and there is a missing hour in March: ```r select(weather, origin, month, day, hour) %>% filter(origin == "EWR", month == 3, day == 10, hour <= 3) ## # A tibble: 3 × 4 ## origin month day hour ## <chr> <int> <int> <int> ## 1 EWR 3 10 0 ## 2 EWR 3 10 1 ## 3 EWR 3 10 3 ``` ] --- layout: false ## Things to Look Out For For dates: -- * Language used for months and weekdays, and their abbreviations. -- * Ambiguous numerical conventions like 4/11/2023: is this April 11 or November 4? -- * Day 2 of the week: is this Monday or Tuesday? -- * For historical data, what calendar is being used? (The _October Revolution_ happened on November 6/7, 1917 by the current Gregorian calendar; October 24/25 by the Julian calendar Russia was still using.) -- For date-times -- * All of the above. -- * Daylight saving time. -- * Time zones. <!-- Locale stuff may fail on some systems (on Ubuntu may need to use locale-gen --> <!-- library(lubridate) flights <- mutate(flights, th = make_datetime(year, month, day, hour, tz = "America/New_York")) weather <- mutate(weather, th = make_datetime(year, month, day, hour, tz = "UTC")) fl0 <- select(filter(flights, origin == "LGA"), dep_time, time_hour, th) w0 <- select(filter(weather, origin == "LGA")[-(1 : 9),], time_hour, th, temp) fl1 <- left_join(fl0, select(w0, -th), "time_hour") fl2 <- left_join(fl0, select(w0, -time_hour), "th") --> --- layout: false ## Reading Chapter [_Dates and Times_](https://r4ds.had.co.nz/dates-and-times.html) in [_R for Data Science_](https://r4ds.had.co.nz/). --- layout: true ## Exercises --- 1) Using the NYC flights data, how many flights were there on Saturdays from Newark (EWR) to Cicago O'Hare (ORD) in 2013? * a. 413 * b. 522 * c. 601 * d. 733 --- 2) What day of the week will July 4, 2030, fall on? * a. Monday * b. Wednesday * d. Thursday * c. Saturday
//adapted from Emi Tanaka's gist at //https://gist.github.com/emitanaka/eaa258bb8471c041797ff377704c8505