Handling date and time in R

In this tutorial you will learn how to work with Date and Time in R.When we consider date and time in normal life it seems to be very simple but it is a bit complicated when moving to the programming language concepts. But R makes it simpler with different options for dealing with date alone and together with date and time with as.Date, as.POSIXct, as.POSIXlt,conversion specifications etc. Also introduces date and time creation using make_date(), make_datetime(),etc.

date,time img

We will also introduce the use of lubridate package. The lubridate package is one of the R packages that deal with dates and times in R.

Installation of lubridate package

Lubridate package makes it easier to work with the most frustrating date and time data in the R programming language. This function is robust to daylight savings time, leap days, time zones, etc

We have already discussed the installation of R packages for more to know check out our tutorial installation in R package. Check for the lubridate package in RStudio under packages, if already available load the package to your program using the library(lubridate) function. If the lubridate package is uninstalled, install it with either of the ways mentioned in our installation in the R package to get the package downloaded and used.


# The easiest way to get lubridate is to install the whole tidyverse:
install.packages("tidyverse")

# Alternatively, install just lubridate:
install.packages("lubridate")

# Or the the development version from GitHub:
# install.packages("devtools")
devtools::install_github("tidyverse/lubridate")

How to get the current date and time?

current date,time img

We use lubridate package functions for performing with date and time before beginning to start learning keep your RStudio ready to work with Date and Time by loading lubridate package.

Step by step we will learn. Let us get started with loading lubridate package.


#Load lubridate package
library(lubridate)

To get the current date two functions can be used from different available R packages. The base R supports date retrieval using Sys.Date() function. The lubridate  R package use function today() to get the same output as that of Sys.Date() function. Both provide the current date "2022-03-27" the format it follows is year/month/date.

The syntax and output for retrieving the current date and time is


# to get current date
Sys.Date()           #{base}
today()              #{lubridate}

Output after execution


> Sys.Date()
[1] "2022-03-27"
> today()
[1] "2022-03-27"

The lubridate and base R packages support the user to get the current time using two functions given below given


# to get current time
Sys.time()
now()

The output after running the codes is


> Sys.time()
[1] "2022-03-27 07:38:04 IST"
> now()
[1] "2022-03-27 07:38:04 IST"

The time zone is also mentioned in the output with IST (Indian Standard Time). The R follows the ISO standard for specifying and representing the data and time. It is clear from the output because the date component is followed by the time component.

ISO std img
date,time snippet

How do check the time is am or pm?

The am() and pm() are lubridate package functions to check Does date-time occurs in the am or pm? It returns a logical value TRUE or FALSE depending on whether x occurs in the am or pm.


am(x)
pm(x)

Where x is the argument that specifies the R date-time object.

Let us see an example,


#to get time in a.m or p.m
am(Sys.time())
pm(Sys.time())

The function Sys.time() gives current time and it forms the argument represented in syntax as x to pass through the function am () or pm (). The function gets the current time and checks whether the time belongs before noon or afternoon. The output after the execution of codes is


> am(Sys.time())
[1] TRUE
> pm(Sys.time())
[1] FALSE

The Sys.time() of our example is "2022-03-27 08:24:51 IST" which is am so the function am(x) returns a logical True. And when the same time is checked with pm(x) returns logical FALSE because the time does not match with the afternoon session i.e., not pm.

We can also use the ymd() of lubricate package to check am(x) or pm(x). These functions parse through the dates and recognize the separators to transform the dates stored in characters into date objects. Let us check an example


x <- ymd("2022-03-27")
am(x)
pm(x)

The code returns the same output as above because the time is the same.


> x <- ymd("2022-03-27")
> am(x)
[1] TRUE
> pm(x)
[1] FALSE

NOTE: The ymd() family of functions is based on parse_date_time()

The screenshot for our discussed codes in RStudio

am pm snippet

How to check a leap year?

The lubridate package provides a function leap_year(x) to check Is a year a leap year? It takes two types of arguments, the argument x can be either a year or Sys.Date() function to determine whether the given year or current year is a leap year or not.

Syntax


leap_year(x)

Where argument x  is a date-time object or a year.

Function leap_year(x) Description
leap_year(year) If argument x is a year (number),the leap_year function returns a logical TRUE if it is a leap year else FALSE using Gregorian calendar Example  : leap_year(2022)              
leap_year(Date) If x is recognized as a Date, the leap year() returns checks and return logical values as output. Example : leap_year(Sys.Date())  

NOTE: Sys.Date() returns current Date

Let u do a practical example


#To check a leap year or not?
leap_year(2022)      #{lubridate package}
leap_year(Sys.Date())

Output after running the codes is


> leap_year(2022)   #{lubridate package}
[1] FALSE
> leap_year(Sys.Date())
[1] FALSE

Consider another example with a slightly different way of Date representation. Here a variable x is assigned with a date conversion function as.Date().


x <- as.Date("2009-08-02")
leap_year(x) # FALSE
leap_year(2009) # FALSE
leap_year(2008) # TRUE
leap_year(1900) # FALSE
leap_year(2000) # TRUE

NOTE: as.Date() is a function under the R base package to convert a character string representation to the objects of class “Date”

The screenshot displays how the leap_year() codes were learned in our discussion.

leap yr snippet

How do Date and Time stored in R?

Dates are stored internally as the number of days since their origin on 1970-01-01and belong to the date class. The date and time are represented using POSIXct or POSIXlt class. The time is internally stored as a number of seconds as the number of seconds since 1970-01-01

How to understand date and time classes in R?

date n time classes img

The built-in R functions have different classes. The Sys.Date() of lubridate package, now() of R base package to represent Date belongs to different classes. For example


class(Sys.Date())
[1] "Date"
> class(now())
[1] "POSIXct" "POSIXt"

NOTE: class() is used to determine the internal type of R objects. There are different types of classes such as character, integer, logical, factor, data frame, etc. The date is also one such class.

Under this session, you will learn about three different classes

  1. Date
  2. POSIXct
  3. POSIXt

Date class – as.Date() for date

In R all dates are internally stored as the number of days. When we store some date the R internally stores the date as some number representation. Why do R store dates as numbers?

In R, dates are represented as the number of days since their origin on 1970-01-01 for date and time in R.You can view it by using lubridate::origin in RStudio. The R store the current date in days since 1970-01-01.

Let us do a practical example to find the current date "2022-03-27" in terms of its number of days,19078 since 1970-01-01.


#date
lubridate::origin
Sys.Date()
unclass(Sys.Date())

The output after running these codes is


lubridate::origin
[1] "1970-01-01 UTC"
> Sys.Date()
[1] "2022-03-27"
> unclass(Sys.Date())
[1] 19078

The as.Date()  function under R base package is used to convert the Date stored as characters class to an object of date class. The information regarding the date is not stored.


Todays_date = as.Date("2022-03-27")
> print(Todays_date)
[1] "2022-03-27"

When you try to identify the class to which Todays_date belongs using class() it returns as Date.


class(Todays_date)
[1] "Date"

Consider the given below codes and resulting output. You can observe that the Date represented is stored to a variable date as a string of characters ("2022-03-27"). It is a date but the system recognizes it as a string only. The class() returns the character as output. Therefore to store the given data in a date format, we should use as.Date() then only the strings to get converted to the date class to store internally as a date.


date = "2022-03-27"
> print(date)
[1] "2022-03-27"
> class(date)
[1] "character"

NOTE: as.Date() converts a number to date with respect to data and time origin in R.

Example

The number 19078 together with data and time origin returns that specific date.


as.Date( 19078,origin= "1970-01-01 ")
[1] "2022-03-27"

NOTE: The date class is used only with data containing the date component, not with date and times components or time zone.

POSIX classes for date and time

R provides two similar POSIX classes POSIXct and POSIXlt to operate with date and time.

POSIXct – as.POSIXct

POSIX stands for portable operating system interface and ct means calendar time. It is a family of standards for specifying the maintenance of compatibility with different OS. We know from our earlier discussions now() belongs to POSIXct class. The date and time components are included in this class. The as.POSIXct() stores both date and time components. The syntax is given below with arguments date and time enclosed within parentheses.


#POSIXct
as.POSIXct("2022-03-27 08:24:51 ")

The output produced is


[1] "2022-03-27 08:24:51 IST"

POSIXlt – as.POSXlt

The POSIXlt class stores date and time information in a list format (e.g., second, min, hour, day of the month, month, year, numeric day of the year, etc). The POSIXlt looks similar to the POSIXct format.


as.POSIXlt("2022-03-27 08:24:51 ")
[1] "2022-03-27 08:24:51 IST"


> #convert character data into POSIXlt date and time
> A=as.POSIXlt("2022-03-27 08:24:51 ")
> unclass(A)
$sec
[1] 51

$min
[1] 24

$hour
[1] 8

$mday
[1] 27

$mon
[1] 2

$year
[1] 122


$wday
[1] 0

$yday
[1] 85

$isdst
[1] 0

$zone
[1] "IST"

$gmtoff
[1] NA


NOTE: The as.POSIXct method converts a date-time string into a POSIXct class.

NOTE: In R, the unlcass function allows to view the details regarding the storage of a particular object.

What is the difference between POSIXct and POSIXlt?

POSIXct POSIXlt
The POSIXct stores date and time components internally as the number of seconds since January 1, 1970 The POSIXlt stores date and time components as in a  a list format for second, min, hour, day of month, month, year, numeric day of year, etc

NOTE: as.POSIX* functions convert an object to one of the two classes used to represent date/times

How to extract Date and time components in R?

You can extract the components of date and time such as YEAR, MONTH, DAY, HOUR, MINUTES, SECONDS, and WEEK, etc with the help of a special built-in function made available in R. Look at the table below for how to extract the year, month and week functions and its corresponding description.

Functions Descriptions
year() Get year
month() Get month in number
month(label=TRUE) Get month in abbreviated form
month(abbr=FALSE) Get month in full name
months() Get month
week() Get week

Let us do some practical examples to show how it works. Start by creating a date and time object. Let it be stored in a variable named DT built using another function ymd_hms() from lubridate package.


>DT = ymd_hms("2022-03-27 08:24:51")
> DT
[1] "2022-03-27 08:24:51 UTC"
>

Let us see the table to find the syntax to extract different parts of the same DATE object created as DT.

FUNCTION OUTPUT
year(DT) [1] 2022
month(DT)   [1] 3
month(DT, label = TRUE) [1] Mar 12 Levels: Jan < Feb < Mar < Apr < ... < Dec  
month(DT,label = TRUE,abbr=FALSE)   [1] March 12 Levels: January < February < ... < December
months(DT) [1] "March"  
week(DT) [1] 13  

Now let us see how to extract day-related components from date and time. Look at the below table to see some functions and its description followed by examples. DT is the date object "2022-03-27 08:24:51 UTC" we created in our earlier example

Function   Description syntax Output  
day() Get day   day(DT)   [1] 27
mday()  day of the month mday(DT)   [1] 27
wday() day of the week

wday(DT)  

wday(DT,label=TRUE)      

wday(DT,label=TRUE,abbr=FALSE)    

[1] 1  

[1] Sun 7 Levels: Sun < Mon < Tue < Wed < ... < Sat  

[1] Sunday 7 Levels: Sunday < Monday < ... < Saturday  

qday() day of the quarter qday(DT)   [1] 86
yday() day of the year yday(DT)   [1] 86
weekdays() day of week

weekdays(DT)

weekdays(DT,abbreviate=FALSE)  

weekdays(DT,abbreviate=TRUE)  

[1] "Sunday"  

[1] "Sunday"    

[1] "Sun"  

days_in_month()  days in month days_in_month(DT)     Mar  31

 

In a similar manner using built-in functions hours, minutes, and seconds can be extracted from the Date object. In the same way, the table below helps to get a clear concept of different functions for finding or extracting hours, minutes, and seconds.

Function syntax Output
hour() hour(DT) [1] 8
minute() minute(DT) [1] 24
second() second(DT) [1] 51
seconds() seconds(DT) [1] "1648369491S"
ISO std img

How to create a date and time?

To create a date you can use the function make_date() and create both the date and time the built-in function make_datetime() is used.

The syntax follows to create a date & the date and time are


make date(year = 1970L, m day = 1L)  #To make  date only 
or
make_datetime(                                 #To make both date and time
  year = 1970L,   m
  day = 1L,
  hour = 0L,
  min = 0L,
  sec = 0,
  tz = "UTC"
)

Where arguments

  • year numeric year
  • month numeric month
  • day numeric day
  • hour numeric hour
  • min  numeric minute
  • sec numeric second
  • tz time zone. Defaults to UTC.

Consider a simple example for both functions

Function Example Output
make_date()

make_date(year =2020, m day=27)  

[1] "2020-03-27"  
make_datetime()

make_datetime(year =2020,mday=27, hour = 0L,min = 0L,sec = 0, tz = "UTC")  

 [1] "2020-03-27 UTC"

Date and time formats in R

The dates can be represented in different formats like “March 03, 22“, ”3rd march 2022”, ”Mar 3rd, 2022”, ”03.03.22” so on. The conversion specifications can be used with the introduction of percentage symbols followed by a single letter which can be capital or small letters. Some of the most important formats we will learn in this section.

We use the conversion specification to specify the format of the date. We use the as.Date() function with the character string representing the type of format we require in the first place of argument followed by format argument which represents the conversion specification.

Let us do a simple example, the as.Date() takes the "22/03/27" character string that needs to be stored as a date object class and transforms to the format specified inside the format argument as format ="%y/%m/%d".


#date and time formats in R
#"27/03/22"
as.Date("22/03/27",format ="%y/%m/%d" )

It creates an output


[1] "2022-03-27"

Look at the given table which shows conversion specifications to use for different date and time components.

Specification Description Example
%d Day of month(decimal number) 27
%m Month(decimal number) 03
%b Month(abbreviated) Mar
%B Month(full name) March
%y Year (2 digits) 22
%Y Year(4 digits) 2022
%H Hour 8
%M Minute 15
%S second 5

 

The below program contains a set of different format specifications. Using as.Date(), as.POSIXct().Try doing each program yourself to get a better understanding of different formats.


#date and time formats in R
#"26/03/22"
as.Date("22/03/26",format ="%y/%m/%d" )

#2022-march-26
as.Date("2022-march-26",format="%Y-%b-%d")


#adding time component
#"26/03/22" 06:06:02
as.POSIXct("22/03/26  06:06:02 ",format ="%y/%m/%d   %H:%M:%S" )

#adding time component with time zone
#"26/03/22" 06:06:02
as.POSIXct("22/03/26  06:06:02 ",format ="%y/%m/%d  %H:%M:%S",tz="UTC")

The output for these different conversion specifications is pretty simple to understand.


> as.Date("22/03/27",format ="%y/%m/%d" )
[1] "2022-03-27"
> as.Date("2022-march-26",format="%Y-%b-%d")
[1] "2022-03-26"
> as.POSIXct("22/03/26  06:06:02 ",format ="%y/%m/%d   %H:%M:%S" )
[1] "2022-03-26 06:06:02 IST"
> as.POSIXct("22/03/26  06:06:02 ",format ="%y/%m/%d  %H:%M:%S",tz="UTC")
[1] "2022-03-26 06:06:02 UTC"