Datetime Cookbook


Document overview

This document is a copy of my personal cookbook of R date and time recipes for tasks I have had to repeatedly look up. Most recipes use the tidyverse lubridate packages.

Each example subsection includes the package versions and R version used at the time of writing.

This document will be updated periodically.

Last updated: 2020-11-12

Table of Contents

Click to expand table of contents



Converting between datetime formats

Convert from a string to a datetime object

There are many ways to transform a string to different datetime object. A few useful methods are collected below. Packages used: lubridate, hms, and zoo.

Datetime String Function
"4/8/2019" as.Date(dtime, format = "frmstr") (base R) where "frmstr" is a format string, e.g. "%m/%d/%Y", that specifies the format of the input string.
"6:30 AM" lubridate::hm(dtime)
"12:34" hms::parse_hm(dtime)
"2019-07-17T15:19:32.811Z" lubridate::parse_date_time(dtime,"ymd hms")
"2019-07-17T15:19:32.811Z" lubridate::ymd_hms(dtime). Library lubridate has different conversion functions---ymd_hms(), ymd_hm(), ymd_h(), dym_hm(), dym_h() and many more---depending on the format of the input string.
"Jan 2019" zoo::as.yearmon(dtime)

⇧ Back to TOCR: 4.0.2 ◊ lubridate: 1.7.9 ◊ hms: 0.5.3 ◊ zoo: 1.8.8

Convert from a ts to tsibble object

Base ts objects have limitations, such as an inability to handle:

  • Days, hours, minutes, or smaller periods between observations
  • Irregular intervals between observations
  • Longitudinal data, i.e. more than one measurement per observation

There are several timeseries objects that can overcome one or more of these limitations, e.g. zoo, xts, and tsibble.

tsibble objects are recommended because they address all three ts limitations and adhere to the tidy data principles. Of course, each timeseries analysis tool has their own requirements for the input timeseries object.

require(tsibble)

# tsobj is a 'ts' object
tsobj %>% tsibble::as_tsibble()

⇧ Back to TOCR: 4.0.2 ◊ dplyr: 1.0.1 ◊ tsibble: 0.2.0

Group dataframes by month, week, day

Group data by week

require(dplyr)

# 'Date' is the date variable.
dframe <- dframe %>% group_by(Date = cut(Date,"week"))

⇧ Back to TOCR: 4.0.2 ◊ dplyr: 1.0.1


Time mathematics: addition, subtraction, difference, etc.

Here, we let:

  • dstart: Earlier date
  • dend: Later date

Find the difference between two datetimes in hours

# 'difftime' is base R
difftime(time1, time2, "America/New_York", units="hours")

⇧ Back to TOCR: 4.0.2

Find the difference between two dates in days

Method 1: Using standard R functions

difftime(dend, start, units = "weeks")

Method 2: Using the lubridate package

require(lubridate)

span <- dstart %--% dend
as.period(span, unit = 'days')

⇧ Back to TOCR: 4.0.2 ◊ dplyr: 1.0.1 ◊ lubridate: 1.7.9

Find the difference between two dates in weeks

Method 1: Using standard R functions

difftime(dend, dstart, units = "weeks")

This will return a difftime object. To just get the number, use as.numeric().

Method 2: Using the lubridate library

Use lubridate intervals. Intervals are defined using the %--% operator. Because it's an interval, not a difference, the earlier date goes on the left side of the operator, the later date goes on the right side of the operator

require(lubridate)

span <- date1 %--% date2

Normally, we could so something like

as.period(span, unit = 'year')

but periods do not accept weeks as units. Convert durations to weeks using

as.duration(span) / dweeks(1)

⇧ Back to TOCR: 4.0.2 ◊ lubridate: 1.7.9

Add X months to a date

Method 1: Use the lubridate package with the %m+% operator (add and subtract months to a date without exceeding the last day of the new month)

require(lubridate)

as.Date("2014-12-31") %m+% months(6)

Method 2: Add a fractional year to the current yearmon

require(zoo)

zoo::as.yearmon("Aug 2019") + 0.5

⇧ Back to TOCR: 4.0.2 ◊ dplyr: 1.0.1 ◊ lubridate: 1.7.9 ◊ zoo: 1.8-8