No feedback found for this session
Dates and times with lubridate
Slides
Session content
Word of warning
- dates and times are hard everywhere
- R is no exception
- this session is a beginner’s guide to lubridate
- not the only way of dealing with dates
- not always the best
- on balance the most consistent, and least quirky tools for dates
This session
- beginner-friendly
- focus on core parsing, get/set, and rounding functions
- lots on dates, a bit of date-times, no times
Resources
library(lubridate)
R dates
- days since 1970-01-01
as_date(0)
[1] “1970-01-01”
R dates
as_date(19860)
[1] “2024-05-17”
as_date(1:5)
[1] “1970-01-02” “1970-01-03” “1970-01-04” “1970-01-05” “1970-01-06”
class(as_date(0))
[1] “Date”
R date-times
- seconds since 1970-01-01 00:00:00 UTC
as_datetime(0)
[1] “1970-01-01 UTC”
as_datetime(1715935369)
[1] “2024-05-17 08:42:49 UTC”
as_datetime(0:5)
[1] “1970-01-01 00:00:00 UTC” “1970-01-01 00:00:01 UTC” [3] “1970-01-01 00:00:02 UTC” “1970-01-01 00:00:03 UTC” [5] “1970-01-01 00:00:04 UTC” “1970-01-01 00:00:05 UTC”
class(as_datetime(0))
[1] “POSIXct” “POSIXt”
Famously…
as_datetime(2 ^ 31-1) # 32 bit signed int
[1] “2038-01-19 03:14:07 UTC”
Parsing dates is important
- most functions that accept dates (like ggplot) will mis-behave if you feed them date-shaped-words
- e.g. alphabetically-ordered dates
- we also want to be able to calculate with dates
Couple of fun intro functions
today()
[1] “2024-11-19”
date_decimal(2024.37534)
[1] “2024-05-17 08:59:11 UTC”
now()
[1] “2024-11-19 15:38:44 GMT”
now("Japan")
[1] “2024-11-20 00:38:44 JST”
<- sample(OlsonNames(), 1)
random_zone cat(paste("The date-time in", random_zone, "is", now(sample(OlsonNames(), 1))))
The date-time in Europe/Paris is 2024-11-19 12:38:44.314612
Parsing
as_date()
is fine assuming you have your date as a number of days- but usually, we’ll need to parse our dates
as_date(45429) # excel-format 1900 date
[1] “2094-05-19”
as_date(45429 - 25569) # dirty but effective
[1] “2024-05-17”
as_date(45429, origin = "1899-12-30") # better
[1] “2024-05-17”
Parsing
- more often, we’ll be taking human-readable dates and parsing them
- that’s a pain, because there are loads of inconsistent ways of representing dates
- worse, lots of dates are ambiguous (5/6/24 and 6/5/24 might refer to the same day)
<- c("17/5/24", "2024-05-17", "Friday 17th May 2024", "17*May*24", "5/17/2024" )
date_input
as_date(date_input) # as_date expects ISO-8601ish dates
[1] “2017-05-24” “2024-05-17” NA “2017-05-24” NA
# one correct, two silently incorrent, two NAs
parse_date_time
parse_date_time(date_input, orders = "ymd")
[1] “2017-05-24 UTC” “2024-05-17 UTC” NA “2017-05-24 UTC” [5] NA
parse_date_time(date_input, orders = c("dmy", "ymd", "dmy", "dmy", "mdy"))
[1] “2024-05-17 UTC” “2024-05-17 UTC” “2024-05-17 UTC” “2024-05-17 UTC” [5] “2024-05-17 UTC”
dmy and co
- you can also use the orders (like dmy) as standalone parsing functions:
dmy(date_input[c(1,3,4)])
[1] “2024-05-17” “2024-05-17” “2024-05-17”
ymd_hms("2024-05/17 9-05-01")
[1] “2024-05-17 09:05:01 UTC”
So you can make dates/date-times. So what?
date(now())
[1] “2024-11-19”
year(today())
[1] 2024
leap_year(today())
[1] TRUE
quarter(today())
[1] 4
semester(today())
[1] 2
semester(today(), with_year = T)
[1] 2024.2
Months and weeks
month(today())
[1] 11
month(today(), label = T)
[1] Nov 12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < … < Dec
week(today())
[1] 47
epiweek(today()) # special ways of counting weeks. See https://en.wikipedia.org/wiki/ISO_week_date and https://www.cmmcp.org/mosquito-surveillance-data/pages/epi-week-calendars-2008-2024
[1] 47
Days
day(today())
[1] 19
wday(today())
[1] 3
qday(today())
[1] 50
Hour and minute
hour(now())
[1] 15
minute(now())
[1] 38
am(now())
[1] FALSE
dst(now())
[1] FALSE
Set
update(now(), hour = 11, minute = 0, second = 0) # nominal finish time today
[1] “2024-11-19 11:00:00 GMT”
- or, more generally:
<- dmy("05/06/23")
test_date day(test_date)
[1] 5
day(test_date) <- 11
test_date
[1] “2023-06-11”
Round
floor_date(today(), unit = "week")
[1] “2024-11-17”
round_date(today(), unit = "week")
[1] “2024-11-17”
ceiling_date(today(), unit = "month")
[1] “2024-12-01”
rollback(today()) # last day of previous month
[1] “2024-10-31”