R Date and Time — Temporal Data Mastery
Learning Objectives
By the end of this tutorial, you will be able to:
- Create date and datetime objects in R
- Extract components (year, month, day, hour, minute)
- Perform date arithmetic and calculate differences
- Format dates for display and parsing
- Use the lubridate package for intuitive date operations
Date and Time Classes
| Class | Description | Example |
|---|---|---|
Date | Calendar date | "2024-01-15" |
POSIXct | Datetime (seconds since 1970) | "2024-01-15 10:30:00" |
POSIXlt | Datetime (list structure) | "2024-01-15 10:30:00" |
character | Text representation | "2024-01-15" |
# Current date and time
Sys.Date() # [1] "2024-01-15"
Sys.time() # [1] "2024-01-15 10:30:00 UTC"
Creating Dates
From Strings
# as.Date() — standard format (YYYY-MM-DD)
as.Date("2024-01-15")
# [1] "2024-01-15"
# Custom format
as.Date("15/01/2024", format = "%d/%m/%Y")
# [1] "2024-01-15"
as.Date("Jan 15, 2024", format = "%b %d, %Y")
# [1] "2024-01-15"
Common Format Codes
| Code | Meaning | Example |
|---|---|---|
%Y | 4-digit year | 2024 |
%y | 2-digit year | 24 |
%m | Month (01-12) | 01 |
%B | Full month name | January |
%b | Abbreviated month | Jan |
%d | Day (01-31) | 15 |
%A | Full weekday | Monday |
%a | Abbreviated weekday | Mon |
%H | Hour (00-23) | 10 |
%M | Minute (00-59) | 30 |
%S | Second (00-59) | 45 |
From Individual Components
# as.Date() with components
as.Date("2024", "01", "15")
# [1] "2024-01-15"
# From numeric (days since 1970-01-01)
as.Date(19736)
# [1] "2024-01-15"
Creating Datetimes
as.POSIXct()
# From string
as.POSIXct("2024-01-15 10:30:00")
# [1] "2024-01-15 10:30:00"
# With timezone
as.POSIXct("2024-01-15 10:30:00", tz = "US/Eastern")
# [1] "2024-01-15 10:30:00 EST"
# Custom format
as.POSIXct("15/01/2024 10:30", format = "%d/%m/%Y %H:%M")
# [1] "2024-01-15 10:30:00"
Sys.time() and Sys.time()
now <- Sys.time()
now
# [1] "2024-01-15 10:30:45 UTC"
class(now) # [1] "POSIXct" "POSIXt"
Extracting Components
date <- as.POSIXct("2024-06-15 14:30:45")
# Extract components
format(date, "%Y") # "2024"
format(date, "%m") # "06"
format(date, "%d") # "15"
format(date, "%H") # "14"
format(date, "%M") # "30"
format(date, "%S") # "45"
# lubridate functions
library(lubridate)
year(date) # [1] 2024
month(date) # [1] 6
day(date) # [1] 15
hour(date) # [1] 14
minute(date) # [1] 30
second(date) # [1] 45
# Day of week
wday(date) # 7 (Sunday)
wday(date, label = TRUE) # Sun
# Day of year
yday(date) # [1] 167
# Week
week(date) # [1] 24
Date Arithmetic
# Add/subtract days
today <- as.Date("2024-01-15")
today + 7 # [1] "2024-01-22"
today - 3 # [1] "2024-01-12"
# Difference between dates
date1 <- as.Date("2024-01-15")
date2 <- as.Date("2024-06-15")
date2 - date1 # Time difference of 152 days
as.numeric(date2 - date1) # [1] 152
# Datetime arithmetic
now <- Sys.time()
now + 3600 # +1 hour (in seconds)
now + 7*24*3600 # +1 week
lubridate Arithmetic
library(lubridate)
# Intuitive additions
now <- ymd_hms("2024-01-15 10:30:00")
now + days(7)
now + weeks(1)
now + months(3)
now + years(1)
now + hours(2) + minutes(30)
# Intervals
start <- ymd("2024-01-01")
end <- ymd("2024-12-31")
interval <- start %--% end
interval / days(1) # 365 days
Formatting Dates
# format() — date to string
date <- as.Date("2024-01-15")
format(date, "%B %d, %Y") # "January 15, 2024"
format(date, "%d/%m/%Y") # "15/01/2024"
format(date, "%a, %b %d") # "Mon, Jan 15"
# strftime — same as format
strftime(date, "%Y-%m-%d")
# paste for custom formats
paste(month(date, label = TRUE), day(date), year(date))
# [1] "Jan 15 2024"
Parsing with lubridate
library(lubridate)
# Flexible parsing functions
ymd("2024-01-15") # [1] "2024-01-15"
mdy("01/15/2024") # [1] "2024-01-15"
dmy("15/01/2024") # [1] "2024-01-15"
# With time
ymd_hms("2024-01-15 10:30:00")
# [1] "2024-01-15 10:30:00 UTC"
# Partial parsing
ymd("2024-01")
# [1] "2024-01-01"
# Numeric input
ymd(20240115)
# [1] "2024-01-15"
Time Zones
library(lubridate)
# Current time in different zones
now <- now()
with_tz(now, "US/Eastern")
with_tz(now, "Europe/London")
with_tz(now, "Asia/Tokyo")
# Change timezone (doesn't change the time, just the label)
x <- ymd_hms("2024-01-15 10:30:00", tz = "UTC")
force_tz(x, tz = "US/Eastern")
Practical Examples
Example 1: Age Calculator
calculate_age <- function(birth_date) {
today <- Sys.Date()
age <- as.integer(format(today, "%Y")) - as.integer(format(birth_date, "%Y"))
if (format(today, "%m%d") < format(birth_date, "%m%d")) {
age <- age - 1
}
age
}
calculate_age(as.Date("1990-05-20"))
Example 2: Business Days
library(bizdays)
# Create calendar
cal <- create.calendar("Brazil/ANBIMA", holidays = holidaysANBIM)
# Business days between dates
bizdays(as.Date("2024-01-01"), as.Date("2024-12-31"), cal)
Example 3: Date Ranges
library(lubridate)
# Generate sequence of dates
seq(ymd("2024-01-01"), ymd("2024-01-10"), by = "day")
seq(ymd("2024-01-01"), ymd("2024-12-31"), by = "month")
seq(ymd("2024-01-01"), ymd("2024-12-31"), by = "quarter")
Practice Exercises
Exercise 1: Date Parser
Write a function that parses dates in multiple formats (YYYY-MM-DD, DD/MM/YYYY, MM-DD-YYYY).
Solution
library(lubridate)
parse_date <- function(date_str) {
# Try different formats
result <- tryCatch(
ymd(date_str),
error = function(e) tryCatch(
mdy(date_str),
error = function(e) tryCatch(
dmy(date_str),
error = function(e) NA
)
)
)
result
}
parse_date("2024-01-15")
parse_date("01/15/2024")
parse_date("15/01/2024")
Key Takeaways
- Use
as.Date()for dates,as.POSIXct()for datetimes lubridatemakes date operations intuitive —ymd(),mdy(),dmy()- Format codes control parsing and display —
%Y,%m,%d,%H,%M - Date arithmetic works automatically — add/subtract days, months, years
Sys.Date()andSys.time()get current date/timewday(),yday(),week()extract temporal components- Always specify timezones when working with datetimes
Next: Learn about R File Handling — reading and writing files.