Dates and Times in R

R provides various options for dealing with date and time data. The builtin as.Date() function handles dates (without times).Dates are represented by the Date class and can be coerced from a character string using the as.Date() function. This is a common way create a Date object in R.

# create a date
x<-as.Date("2017-05-30")
# specify the format
y<-as.Date("05/30/2017", format = "%m/%d/%Y")
x
y

Output:

x
[1] "2017-05-30"
> y
[1] "2017-05-30" 

Check the following example for taking time difference .

# take a difference
Sys.Date() - as.Date("2017-05-30")

# alternate method with specified units
difftime(Sys.Date(), as.Date("2017-05-30"), units = "hours")

# see the internal integer representation
unclass(Sys.Date())

Output:

> Sys.Date() - as.Date("2017-05-30")
Time difference of 4 days
> difftime(Sys.Date(), as.Date("2017-05-30"), units = "hours")
Time difference of 96 hours
> unclass(Sys.Date())
[1] 17320

POSIXt Date-Time Class:

Dates are pretty simple and most of the operations that we could use for them will also apply to date-time variables. There are mainly three very good options for date-time data types: built-in POSIXt, chron package, lubridate package.

There are two POSIXt types, POSIXct and POSIXlt. ”ct” can stand for calendar time, it stores the number of seconds since the origin. ”lt”, or local time, keeps the date as a list of time attributes (such as ”hour” and ”mon”).

# current time as POSIXct
unclass(Sys.time())
# and as POSIXlt
unclass(as.POSIXlt(Sys.time()))

Output:

> unclass(Sys.time())
[1] 1496502787
> # and as POSIXlt
> unclass(as.POSIXlt(Sys.time()))
$sec
[1] 6.556977

$min
[1] 43

$hour
[1] 20

$mday
[1] 3

$mon
[1] 5

$year
[1] 117

$wday
[1] 6

$yday
[1] 153

$isdst
[1] 0

$zone
[1] “IST”

$gmtoff
[1] 19800

attr(,”tzone”)
[1] “” “IST” “+0630”

Create POSIXct Variables:

# create POSIXct variables
as.POSIXct("170531 20:11", format = "%y%m%d %H:%M")

as.POSIXct("2017-06-04 09:10:05 PM", format = "%Y-%m-%d %I:%M:%S %p")

as.POSIXct(“06/03/17 23:10:00”, format = “%m/%d/%y %H:%M:%S”)

# convert POSIXct variables to character strings
format(as.POSIXct(“170603 20:11”, format = “%y%m%d %H:%M”), “%m/%d/%Y %I:%M %p”)

as.character(as.POSIXct(“170603 20:25”, format = “%y%m%d %H:%M”), format = “%m-%d-%y %H:%M”)

Output:

> as.POSIXct("170531 20:11", format = "%y%m%d %H:%M")
[1] "2017-05-31 20:11:00 IST"
> as.POSIXct("2017-06-04 09:10:05 PM", format = "%Y-%m-%d %I:%M:%S %p")
[1] "2017-06-04 21:10:05 IST"
> as.POSIXct("06/03/17 23:10:00", format = "%m/%d/%y %H:%M:%S")
[1] "2017-06-03 23:10:00 IST"
> format(as.POSIXct("170603 20:11", format = "%y%m%d %H:%M"), "%m/%d/%Y %I:%M %p")
[1] "06/03/2017 08:11 PM"
> as.character(as.POSIXct("170603 20:25", format = "%y%m%d %H:%M"), format = "%m-%d-%y %H:%M")
[1] "06-03-17 20:25"

POSIXlt object in R:

POSIXlt stores a bunch of other useful information like the day of the week, day of the year, month, day of the month. This is useful when you want that kind of information.

There are few functions that are useful to extract pieces of dates and/or times from date object.
• weekdays: give the day of the week
• months: give the month name
• quarters: give the quarter number (“Q1”, “Q2”, “Q3”,“Q4”)

x <- Sys.time()
x
class(x)
unclass(x)
x$sec # You can't do this operation with 'POSIXct'!

p <- as.POSIXlt(x)
p$wday #it returns day of the week

Output:

> x
[1] "2017-06-03 22:03:41 IST"
> class(x)
[1] "POSIXct" "POSIXt"
> unclass(x)
[1] 1496507622
> x$sec # You can't do this operation with 'POSIXct'!
Error in x$sec : $ operator is invalid for atomic vectors
>
> p <- as.POSIXlt(x)
> p$wday #it returns day of the week
[1] 6

strptime() Function in R:

strptime() is a very useful function when your dates are written in a different format. strptime() takes a character vector that has dates and times and converts them into to a POSIXlt object.

d <- "June 03, 2017 10:40"
x <- strptime(d, "%B %d, %Y %H:%M")
x
class(x)

Output:

> x
[1] "2017-06-03 10:40:00 IST"
> class(x)
[1] "POSIXlt" "POSIXt"

Operations on Dates and Times:

You can also use mathematical operations on dates and times like + and -. You can do comparisons also (i.e. ==, <=)

x <- as.Date("2017-06-03")
y <- as.Date("1990-12-02")
x-y

a<- as.POSIXct(“2017-06-03 8:20:00”)
b <- as.POSIXct(“2017-06-03 8:20:00”, tz = “GMT”)
b-a

Output:

> x-y
Time difference of 9680 days
> b-a
Time difference of 5.5 hours

Chron Package in R:

Chron is a useful package for handling dates and times in R. As it is not a base package, so you’ll have to install it. Check the below examples to see how to use chron package.

install.packages("chron")
library(chron)

dts <- dates(c("02/27/17", "05/31/17", "06/03/17"))
tms<- times(c("23:03:20", "22:29:56", "01:03:30"))
x <- chron(dates = dts, times = tms)
x

Output:

[1] (02/27/17 23:03:20) (05/31/17 22:29:56) (06/03/17 01:03:30)

We can add or subtract scalars (representing days) to dates or chron objects:

c(dts[1], dts[1] + 10)

Output:

[1] 02/27/17 03/09/17

You can substract dates which results in a times object that represents days between the operands:

dts[2] – dts[1]

Output:

Time in days:
[1] 93

There is another useful function in chron called cut() function. Check the following example to use them.

cut(dts, "months")

Output:

[1] Feb 17 May 17 Jun 17
Levels: Feb 17 < Mar 17 < Apr 17 < May 17 < Jun 17

You can also extract the year, quarter, month, day (within the month) or weekday(days within the week) of the date it represents.

weekdays(dts)
months(dts)
years(dts)
quarters(dts)

Output:

> weekdays(dts)
[1] Mon Wed Sat
Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat
> months(dts)
[1] Feb May Jun
Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < Oct < Nov < Dec
> years(dts)
[1] 2017 2017 2017
Levels: 2017
> quarters(dts)
[1] 1Q 2Q 2Q
Levels: 1Q < 2Q < 3Q < 4Q

To know more details about Chron package click here.

Lubridate Package in R:

Lubridate is another useful package for working with dates and times in R. As it is also not a base package, you have to install it using install.packages() function. Check the following examples the usage of Lubridate package.

install.packages("lubridate")
library(Lubridate)

ymd_hms("2017-06-03 23:59:59")
ld <- mdy_hms("05/31/2017 23:59:59")
ld + seconds(1)
now()
ceiling_date(now(), unit = "month") - days(1)
# is it morning?
am(now())
ld - dyears(1)

Output:

> ymd_hms("2017-06-03 23:59:59")
[1] "2017-06-03 23:59:59 UTC"
> ld + seconds(1)
[1] "2017-06-01 UTC"
> now()
[1] "2017-06-03 23:59:23 IST"
> ceiling_date(now(), unit = "month") - days(1)
[1] "2017-06-30 IST"
> # is it morning?
> am(now())
[1] FALSE
> ld - dyears(1)
[1] "2016-05-31 23:59:59 UTC"

Vectorization

Data Summary