Skip to content
AgileLogics
5 min read

Dates and Times: lubridate

Prerequisites: Data types, dplyr: mutate, summarise, and group_by

Dates are stored as special types in R: Date for calendar days and POSIXct for date-times. The lubridate package makes them easy to parse and work with.

Parsing

lubridate's parsing functions are named after the order of the parts in your data — y, m, d (and h, m, s for times):

library(lubridate, warn.conflicts = FALSE)

ymd("2025-01-15")
dmy("15/01/2025")
mdy("January 15, 2025")
ymd_hms("2025-01-15 09:30:00", tz = "UTC")
class(ymd("2025-01-15"))
[1] "2025-01-15"
[1] "2025-01-15"
[1] "2025-01-15"
[1] "2025-01-15 09:30:00 UTC"
[1] "Date"

All three formats became the same Date. Parsing dates stored as text is one of the first cleaning steps for most datasets.

Extracting parts and doing arithmetic

library(lubridate, warn.conflicts = FALSE)

d <- ymd("2025-01-31")
year(d)
month(d, label = TRUE)
wday(d, label = TRUE)
d + days(30)
d %m+% months(1)
as.numeric(ymd("2025-12-25") - d)
floor_date(ymd("2025-03-17"), "month")
[1] 2025
[1] Jan
12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < ... < Dec
[1] Fri
Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat
[1] "2025-03-02"
[1] "2025-02-28"
[1] 328
[1] "2025-03-01"
  • month(d, label = TRUE) returns an ordered factor, so charts show months in calendar order, not alphabetically.
  • %m+% months(1) adds a calendar month, rolling back to the last valid day — 31 January becomes 28 February.
  • floor_date(x, "month") rounds down to the start of the month — the standard way to group data by month.

Monthly totals

library(dplyr, warn.conflicts = FALSE)
library(lubridate, warn.conflicts = FALSE)

sales <- tibble(
  date = ymd(c("2025-01-05", "2025-01-20", "2025-02-03")),
  amount = c(100, 250, 80)
)

sales |>
  mutate(month = floor_date(date, "month")) |>
  summarise(total = sum(amount), .by = month)
# A tibble: 2 × 2
  month      total
  <date>     <dbl>
1 2025-01-01   350
2 2025-02-01    80

Common mistakes

  • Ambiguous formats: 01/02/2025 is 1 February in most of the world and 2 January in the US. Know your data's convention and use dmy or mdy accordingly.
  • Ignoring time zones for date-times. Store them in UTC, and set tz explicitly when parsing.