Skip to main content
v2026.11,858 entries · CC-BY 4.0

lubridate (R Package): Parse Dates, Time Zones, Durations and Intervals

lubridate R package guide: install, parse dates, convert time zones, and tell durations, periods and intervals apart, with documented outputs.

Written and maintained by CASRAI Editorial Board

Last updated

lubridate is an R package for parsing, extracting, converting and doing arithmetic on dates and times. If you searched for “lubridate r” or “lubridate r package”: it is R-only (there is no Python port), it is MIT-licensed, and the current release on CRAN is 1.9.5 (published 2026-02-04). This page covers what it is for, how to install it, the core functions with exact outputs from its documentation, and the three-way distinction (durations, periods, intervals) that causes most date-arithmetic mistakes in research analysis.

What lubridate is used for in research

Research datasets are full of dates written in inconsistent ways: enrolment dates, sample collection times, instrument timestamps, follow-up windows. lubridate turns such text into proper date-time objects, pulls out components (year, month, weekday, hour), handles time zones, and computes elapsed time. Its documentation groups the functionality into parsing (ymd(), dmy(), mdy(), ymd_hms(), dmy_hms()), components (year(), month(), mday(), hour(), minute(), second(), wday()) and time zones (with_tz(), force_tz()).

For day-counting tasks specifically (adding, subtracting and counting days between two dates), see the task-focused guide R Days: Add, Subtract and Count Days Between Dates. This page is the package reference.

Install or access (official source only)

lubridate is distributed on CRAN, with its documentation site at lubridate.tidyverse.org. The package page lists R (>= 3.2) as a dependency and imports generics and timechange (>= 0.4.0). The official site gives these install routes:

  1. install.packages("tidyverse") installs lubridate along with the other tidyverse packages.
  2. install.packages("lubridate") installs lubridate alone.
  3. devtools::install_github("tidyverse/lubridate") installs the development version from GitHub.

Then load it with library(lubridate). Call library(lubridate) explicitly in analysis scripts so the dependency is visible. Pinning the package version in your project record supports computational reproducibility.

Step-by-step: parse, extract and convert

1. Parse text into dates

Choose the function whose letters match the order of year (y), month (m) and day (d) in your data. Add h, m, s to the name for date-times.

library(lubridate)
ymd(20101215)          # "2010-12-15"
mdy("4/1/17")          # "2017-04-01"
bday <- dmy("14/10/1979")
time <- ymd_hms("2010-12-13 15:30:30")

2. Extract components

month(bday)                 # 10
wday(bday, label = TRUE)    # Sun

3. Convert or fix time zones

with_tz() and force_tz() look similar but do opposite things. From the lubridate documentation:

with_tz(time, "America/Chicago")    # "2010-12-13 09:30:30 CST"  (same instant, different display)
force_tz(time, "America/Chicago")   # "2010-12-13 15:30:30 CST"  (clock time kept, instant changed)

Use force_tz() when a timestamp was recorded in the wrong zone (for example an instrument logging local time but read as UTC). Use with_tz() when the instant is right and you only want it displayed in another zone.

4. Round to a unit

According to the reference page, round_date() rounds to the nearest unit (halfway values round up), floor_date() rounds down to the unit boundary, and ceiling_date() rounds up. Valid base units include second, minute, hour, day, week, month, bimonth, quarter, season, halfyear and year. Flooring to "month" is a common way to bin observations for monthly counts.

Output and how to read it: durations, periods and intervals

lubridate has three ways to represent a span of time, and they give different answers around daylight-saving changes and month lengths.

Class Meaning Example from the vignette
Duration Exact number of seconds; the documentation says it “will always supply mathematically precise results” dminutes(2) prints 120s (~2 minutes)
Period Calendar units (months, days); length varies with the calendar minutes(2) prints 2M 0S
Interval A span tied to a specific start and end interval(ymd(20110720, tz="Pacific/Auckland"), ymd(20110831, tz="Pacific/Auckland")) prints 2011-07-20 NZST--2011-08-31 NZST

Intervals can be tested against dates: %within% returns a logical vector (for example whether meeting times fall inside a conference interval), and int_overlaps() returns TRUE when two intervals overlap. In a study context, an interval is the natural object for “was this visit inside the protocol window?”

The month-end trap

Adding a plain months() period to 31 January can produce an invalid date (NA), because not every month has a 31st. The vignette’s fix is the %m+% operator, which rolls back to the last valid day: jan31 %m+% months(0:11) yields 2013-02-28, 2013-04-30 and so on. Use it for follow-up schedules such as “monthly for 12 months from enrolment”.

Troubleshooting

  • Result is NA after parsing. The text does not match the order implied by the function name, or the date is invalid (for example 31 April). Try the function with the matching y/m/d order for that column.
  • Result is NA after adding months. The month-end trap above; switch to %m+%.
  • Hours look shifted. Check whether you meant with_tz() (display change) or force_tz() (relabel the clock time), and whether the parse step was given the correct tz argument, as in ymd_hms("2011-06-04 12:00:00", tz = "Pacific/Auckland").
  • Elapsed time differs from a calendar expectation. You are probably mixing durations (exact seconds) and periods (calendar units); decide which one your protocol means.

Free alternatives

Option Language Relationship to lubridate
Base R (as.Date(), strptime(), as.POSIXct()) R Ships with R, so needs no installation; parsing uses format strings rather than y/m/d function names.
clock R A separate R package for working with dates and times.
pandas (pandas.to_datetime) Python Python option, since lubridate is R-only.

For a wider comparison of R with point-and-click statistics software, see SPSS vs R; for an applied R example see ANCOVA in R.

FAQ

Is lubridate part of the tidyverse?

Its documentation lives on the tidyverse site, and install.packages("tidyverse") installs it. You can also install it on its own with install.packages("lubridate").

Does lubridate exist for Python?

No. It is an R package. Python users typically use pandas or the standard library’s datetime module.

What is the difference between with_tz() and force_tz()?

with_tz() keeps the same instant and changes how it is displayed; force_tz() keeps the displayed clock time and changes the instant. See step 3 above for outputs.

Why do I get NA when I parse or add dates?

Either the text does not match the function’s y/m/d order, the date is not a real calendar date, or you added months to a month-end date. See Troubleshooting.

Which R and package versions does it need?

As listed on CRAN on 2026-11-08: version 1.9.5, R (>= 3.2), and the timechange package (>= 0.4.0) among its imports.

Sources (official documentation)

  • lubridate documentation site, https://lubridate.tidyverse.org/ (read 2026-11-08)
  • lubridate vignette, https://lubridate.tidyverse.org/articles/lubridate.html (read 2026-11-08)
  • round_date reference, https://lubridate.tidyverse.org/reference/round_date.html (read 2026-11-08)
  • CRAN package page, https://cran.r-project.org/package=lubridate (read 2026-11-08)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about lubridate (R Package): Parse Dates, Time Zones, Durations and Intervals

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →