A Comprehensive Introduction to Handling Date & Time in R (2024)

[This article was first published on Rsquared Academy Blog, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)

Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

A Comprehensive Introduction to Handling Date & Time in R (1)

In this tutorial, we will learn to handle date & time in R. We will start off by learning howto get current date & time before moving on to understand how R handles date/time internallyand the different classes such as Date & POSIXct/lt. We will spend some timeexploring time zones, daylight savings and ISO 8001 standard for representing date/time.We will look at all the weird formats in which date/time come in real world and learn toparse them using conversion specifications. After this, we will also learn how to handle date/timecolumns while reading external data into R. We will learn to extract and update different date/timecomponents such as year, month, day, hour, minute etc., create sequence of dates in different waysand explore intervals, durations and period. We will end the tutorial by learning how to round/rollbackdates. Throughout the tutorial, we will also work through a case study to better understand theconcepts we learn. Happy learning!

Resources

Below are the links to all the resources related to this tutorial:

A Comprehensive Introduction to Handling Date & Time in R (2)

Introduction

Date

Let us begin by looking at the current date and time. Sys.Date() and today() will return the current date.

Sys.Date()## [1] "2020-04-17"lubridate::today()## [1] "2020-04-17"

Time

Sys.time() and now() return the date, time and the timezone. In now(), we can specify the timezone using the tzone argument.

Sys.time()## [1] "2020-04-17 17:37:21 IST"lubridate::now()## [1] "2020-04-17 17:37:21 IST"lubridate::now(tzone = "UTC")## [1] "2020-04-17 12:07:21 UTC"

AM or PM?

am() and pm() allow us to check whether date/time occur in the AM or PM? They return a logical value i.e.TRUE or FALSE

lubridate::am(now())## [1] FALSElubridate::pm(now())## [1] TRUE

Leap Year

We can also check if the current year is a leap year using leap_year().

Sys.Date()## [1] "2020-04-17"lubridate::leap_year(Sys.Date())## [1] TRUE

Summary

FunctionDescription
Sys.Date()Current Date
lubridate::today()Current Date
Sys.time()Current Time
lubridate::now()Current Time
lubridate::am()Whether time occurs in am?
lubridate::pm()Whether time occurs in pm?
lubridate::leap_year()Check if the year is a leap year?

Your Turn

  • get current date
  • get current time
  • check whether the time occurs in am or pm?
  • check whether the following years were leap years
    • 2018
    • 2016

Case Study

Throughout the tutorial, we will work on a case study related to transactions of an imaginary trading company. The data set includes information about invoice and payment dates.

Data

transact <- readr::read_csv('https://raw.githubusercontent.com/rsquaredacademy/datasets/master/transact.csv')## # A tibble: 2,466 x 3## Invoice Due Payment ## <date> <date> <date> ## 1 2013-01-02 2013-02-01 2013-01-15## 2 2013-01-26 2013-02-25 2013-03-03## 3 2013-07-03 2013-08-02 2013-07-08## 4 2013-02-10 2013-03-12 2013-03-17## 5 2012-10-25 2012-11-24 2012-11-28## 6 2012-01-27 2012-02-26 2012-02-22## 7 2013-08-13 2013-09-12 2013-09-09## 8 2012-12-16 2013-01-15 2013-01-12## 9 2012-05-14 2012-06-13 2012-07-01## 10 2013-07-01 2013-07-31 2013-07-26## # ... with 2,456 more rows

We will explore more about reading data sets with date/time columns after learning how toparse date/time. We have shared the code for reading the data sets used in the practicequestions both in the Learning Management System as well as in our GitHub repo.

Data Dictionary

The data set has 3 columns. All the dates are in the format (yyyy-mm-dd).

ColumnDescription
InvoiceInvoice Date
DueDue Date
PaymentPayment Date

In the case study, we will try to answer a few questions we have about the transact data.

  • extract date, month and year from Due
  • compute the number of days to settle invoice
  • compute days over due
  • check if due year is a leap year
  • check when due day in february is 29, whether it is a leap year
  • how many invoices were settled within due date
  • how many invoices are due in each quarter

Date & Time Classes

In this section, we will look at two things. First, how to create date/timedata in R, and second, how to convert other data types to date/time. Let usbegin by creating the release date of R 3.6.2.

release_date <- 2019-12-12release_date## [1] 1995

Okay! Why do we see 1995 when we call the date? What is happening here? Let usquickly check the data type of release_date.

class(release_date)## [1] "numeric"

The data type is numeric i.e.R has subtracted 12 twice from 2019 toreturn 1995. Clearly, the above method is not the right way to storedate/time. Let us see if we can get some hints from the built-in R functions weused in the previous section. If you observe the output, all of them returneddate/time wrapped in quotes. Hmmm… let us wrap our date in quotes and see whathappens.

release_date <- "2019-12-12"release_date## [1] "2019-12-12"

Alright, now R does not do any arithmetic and returns the date as we specified.Great! Is this the right format to store date/time then? No.Why? What is the problemif date/time is saved as character/string? The problem is the nature or type ofoperations done on date/time are different when compared to string/character,number or logical values.

  • how do we add/subtract dates?
  • how do we extract components such as year, month, day etc.

To answer the above questions, we will first check the data type of Sys.Date()and now().

class(Sys.Date())## [1] "Date"class(lubridate::now())## [1] "POSIXct" "POSIXt"class(release_date)## [1] "character"

As you can see from the above output, there are 3 different classes for storingdate/time in R

  • Date
  • POSIXct
  • POSIXlt

Let us explore each of the above classes one by one.

Date

Introduction

The Date class represents calendar dates. Let us go back to Sys.Date(). Ifyou check the class of Sys.Date(), it is Date. Internally, this date is anumber i.e.an integer. The unclass() function will show how dates are storedinternally.

Sys.Date()## [1] "2020-04-17"unclass(Sys.Date())## [1] 18369

What does this integer represent? Why has R stored the date as an integer?In R, dates are represented as the number of days since 1970-01-01. All the dates in R areinternally stored in this way. Before we explore this concept further, let uslearn to create Date objects in R. We will continue to use the release dateof R 3.6.2, 2019-12-12.

Until now, we have stored the above date as character/string but now we will useas.Date() to save it as a Date object. as.Date() is the easiest andsimplest way to create dates in R.

release_date <- as.Date("2019-12-12")release_date## [1] "2019-12-12"

The as_date() function from the lubridate package is similar to as.Date().

release_date <- lubridate::as_date("2019-12-12")release_date## [1] "2019-12-12"

If you look at the difference between release_date and 1970-01-01, it willbe the same as unclass(release_date).

release_date - as.Date("1970-01-01")## Time difference of 18242 daysunclass(release_date)## [1] 18242

Let us come back to 1970-01-01 i.e.the origin for dates in R.

lubridate::origin## [1] "1970-01-01 UTC"

From the previous examples, we know that dates are internally stored as numberof days since 1970-01-01. How about dates older than the origin? How are theystored? Let us look at that briefly.

unclass(as.Date("1963-08-28"))## [1] -2318

Dates older than the origin are stored as negative integers. For those who arenot aware, Martin Luther King, Jr.delivered his famous I Have a Dreamspeech on 1963-08-28. Let us move on and learn how to convert numbers intodates.

Convert Numeric

The as.Date() function can be used to convert any of the following to a Dateobject

  • character/string
  • number
  • factor (categorical/qualitative)

We have explored how to convert strings to date. How about converting numbers todate? Sure, we can create date from numbers by specifying the origin and numberof days since it.

as.Date(18242, origin = "1970-01-01")## [1] "2019-12-12"

The origin can be changed to another date (while changing the number as well.)

as.Date(7285, origin = "2000-01-01")## [1] "2019-12-12"

ISO 8601

A Comprehensive Introduction to Handling Date & Time in R (3)

If you have carefully observed, the format in which we have been specifying thedates as well as of those returned by functions such as Sys.Date() orSys.time() is the same i.e.YYYY-MM-DD. It includes

  • the year including the century
  • the month
  • the date

The month and date separated by -. This default format used in R is the ISO8601 standard for date/time. ISO 8601 is the internationally accepted way torepresent dates and times and uses the 24 hour clock system. Let us create therelease date using another function ISOdate().

ISOdate(year = 2019, month = 12, day = 12, hour = 8, min = 5, sec = 3, tz = "UTC")## [1] "2019-12-12 08:05:03 UTC"

We will look at all the different weird ways in which date/time are specified inthe real world in the Date & Time Formats section. For the time being, let uscontinue exploring date/time classes in R. The next class we are going to lookat is POSIXct/POSIXlt.

POSIX

You might be wondering what is this POSIX thing? POSIX stands for PortableOperating System Interface. It is a family of standards specified formaintaining compatibility between different operating systems. Before welearn to create POSIX objects, let us look at now() from lubridate.

class(lubridate::now())## [1] "POSIXct" "POSIXt"

now() returns current date/time as a POSIXct object. Let us look at itsinternal representation using unclass()

unclass(lubridate::now())## [1] 1587125246## attr(,"tzone")## [1] ""

The output you see is the number of seconds since January 1, 1970.

POSIXct

POSIXct represents the number of seconds since the beginning of 1970 (UTC) andct stands for calendar time. To store date/time as POSIXct objects, useas.POSIXct(). Let us now store the release date of R 3.6.2 as POSIXct as shownbelow

release_date <- as.POSIXct("2019-12-12 08:05:03")class(release_date)## [1] "POSIXct" "POSIXt"unclass(release_date) ## [1] 1576118103## attr(,"tzone")## [1] ""

POSIXlt

POSIXlt represents the following information in a list

  • seconds
  • minutes
  • hour
  • day of the month
  • month
  • year
  • day of week
  • day of year
  • daylight saving time flag
  • time zone
  • offset in seconds from GMT

The lt in POSIXlt stands for local time. Use as.POSIXlt() to storedate/time as POSIXlt objects. Let us store the release date as a POSIXltobject as shown below

release_date <- as.POSIXlt("2019-12-12 08:05:03")release_date## [1] "2019-12-12 08:05:03 IST"

As we said earlier, POSIXlt stores date/time components in a list and thesecan be extracted. Let us look at the date/time components returned by POSIXltusing unclass().

release_date <- as.POSIXlt("2019-12-12 08:05:03")unclass(release_date)## $sec## [1] 3## ## $min## [1] 5## ## $hour## [1] 8## ## $mday## [1] 12## ## $mon## [1] 11## ## $year## [1] 119## ## $wday## [1] 4## ## $yday## [1] 345## ## $isdst## [1] 0## ## $zone## [1] "IST"## ## $gmtoff## [1] NA

Use unlist() if you want the components returned as a vector.

release_date <- as.POSIXlt("2019-12-12 08:05:03")unlist(release_date)## sec min hour mday mon year wday yday isdst zone gmtoff ## "3" "5" "8" "12" "11" "119" "4" "345" "0" "IST" NA

To extract specific components, use $.

release_date <- as.POSIXlt("2019-12-12 08:05:03")release_date$hour## [1] 8release_date$mon## [1] 11release_date$zone## [1] "IST"

Now, let us look at the components returned by POSIXlt. Some of them areintuitive

ComponentDescription
secSecond
minMinute
hourHour of the day
monMonth of the year (0-11
zoneTimezone
wdayDay of week
mdayDay of month
yearYears since 1900
ydayDay of year
isdstDaylight saving flag
gmtoffOffset is seconds from GMT

Great! We will end this section with a few tips/suggestions on when to useDate or POSIXct/POSIXlt.

  • use Date when there is no time component
  • use POSIX when dealing with time and timezones
  • use POSIXlt when you want to access/extract the different components

Your Turn

R 1.0.0 was released on 2000-02-29 08:55:23 UTC. Save it as

  • Date using character
  • Date using origin and number
  • POSIXct
  • POSIXlt and extract
    • month day
    • day of year
    • month
    • zone
  • ISODate

Date Arithmetic

Time to do some arithmetic with the dates. Let us calculate the length of acourse you have enrolled for (Become a Rock Star Data Scientist in 10 Days) by subtracting the course start date from the course end date.

A Comprehensive Introduction to Handling Date & Time in R (4)

course_start <- as_date('2017-04-12')course_end <- as_date('2017-04-21')course_duration <- course_end - course_startcourse_duration## Time difference of 9 days

Shift Date

Time to shift the course dates. We can shift a date by days, weeks or months. Let us shift the course start date by:

  • 2 days
  • 3 weeks
  • 1 year

A Comprehensive Introduction to Handling Date & Time in R (5)

course_start + days(2)## [1] "2017-04-14"course_start + weeks(3)## [1] "2017-05-03"course_start + years(1)## [1] "2018-04-12"

Case Study

Compute days to settle invoice

Let us estimate the number of days to settle the invoice by subtracting thedate of invoice from the date of payment.

transact %>% mutate( days_to_pay = Payment - Invoice )## # A tibble: 2,466 x 4## Invoice Due Payment days_to_pay## <date> <date> <date> <drtn> ## 1 2013-01-02 2013-02-01 2013-01-15 13 days ## 2 2013-01-26 2013-02-25 2013-03-03 36 days ## 3 2013-07-03 2013-08-02 2013-07-08 5 days ## 4 2013-02-10 2013-03-12 2013-03-17 35 days ## 5 2012-10-25 2012-11-24 2012-11-28 34 days ## 6 2012-01-27 2012-02-26 2012-02-22 26 days ## 7 2013-08-13 2013-09-12 2013-09-09 27 days ## 8 2012-12-16 2013-01-15 2013-01-12 27 days ## 9 2012-05-14 2012-06-13 2012-07-01 48 days ## 10 2013-07-01 2013-07-31 2013-07-26 25 days ## # ... with 2,456 more rows

Compute days over due

How many of the invoices were settled post the due date? We can find this by:

  • subtracting the due date from the payment date
  • counting the number of rows where delay > 0
transact %>% mutate( delay = Payment - Due ) %>% filter(delay > 0) %>% count(delay)## # A tibble: 36 x 2## delay n## <drtn> <int>## 1 1 days 61## 2 2 days 65## 3 3 days 51## 4 4 days 62## 5 5 days 69## 6 6 days 56## 7 7 days 55## 8 8 days 49## 9 9 days 38## 10 10 days 33## # ... with 26 more rows

Your Turn

  • compute the length of a vacation which begins on 2020-04-19 and ends on 2020-04-25
  • recompute the length of the vacation after shifting the vacation start and end date by 10 days and 2 weeks
  • compute the days to settle invoice and days overdue from the receivables.csv data set
  • compute the length of employment (only for those employees who have been terminated) from the hr-data.csv data set (use date of hire and termination)

Time Zones & Daylight Savings

Introduction

A Comprehensive Introduction to Handling Date & Time in R (6)

In the previous section, POSIXlt stored date/time components as a list. Amongthe different components it returned were

  • gmtoff
  • zone

gmtoff is offset in seconds from GMT i.e.difference in hours and minutes fromUTC. Wait.. What do UTC and GMT stand for?

  • Coordinated Universal Time (UTC)
  • Greenwich Meridian Time (GMT)

Since we are talking about UTC, GMT etc., let us spend a little time onunderstanding the basics of time zones and daylight savings.

Time Zones

Timezones exist because different parts of the Earth receive sun light atdifferent times. If there was a single timezone, noon or morning would meandifferent things in different parts of the world. The timezones are based onEarth’s rotation. The Earth moves ~15 degrees every 60 minutes i.e.360 degreesin 24 hours. The planet is divided into 24 timezones, each 15 degrees oflongitude width.

Now, you have heard of Greenwich Meridian Time (GMT) right? We just saw GMT offset in POSIXlt and you would have come across it in other time formats aswell. For example, India timezone is given as GMT +5:30. Let us explore GMT in alittle more detail. Greenwich is a suburb of London and the time at Greenwichis Greenwich Mean Time. As you move West from Greenwich, every 15degree section is one hour earlier than GMT and every 15 degree section to theEast is an hour later.

Alright! What is UTC then? Coordinated Universal Time (UTC) ,on the other hand, is the time standard commonly used across the world. Eventhough they share the same current time, GMT is a timezone whileUTC is a time standard.

So how do we check the timezone in R? When you run Sys.timezone(), you shouldbe able to see the timezone you are in.

Sys.timezone()## [1] "Asia/Calcutta"

If you do not see the timezone, use Sys.getenv() to get the value of theTZ environment variable.

Sys.getenv("TZ")## [1] ""

If nothing is returned, it means we have to set the timezone. Use Sys.setenv()to set the timezone as shown below. The author resides in India and hence thetimezone is set to Asia/Calcutta. You need to set the timezone in which youreside or work.

Sys.setenv(TZ = "Asia/Calcutta")

Another way to get the timezone is through tz() from the lubridate package.

lubridate::tz(Sys.time())## [1] "Asia/Calcutta"

If you want to view the time in a different timezone, use with_tz(). Let uslook at the current time in UTC instead of Indian Standard Time.

lubridate::with_tz(Sys.time(), "UTC")## [1] "2020-04-17 12:07:28 UTC"

Daylight Savings

A Comprehensive Introduction to Handling Date & Time in R (7)

Daylight savings also known as

  • daylight saving time
  • daylight savings time
  • daylight time
  • summer time

is the practice of advancing clocks during summer months so that darkness fallslater each day according to the clock. In other words

  • advance clock by one hour in spring (spring forward)
  • retard clocks by one hour in autumn (fall back)

In R, the dst() function is an indicator for daylight savings. It returnsTRUE if daylight saving is in force, FALSE if not and NA if unknown.

Sys.Date()## [1] "2020-04-17"dst(Sys.Date()) ## [1] FALSE

Your Turn

  • check the timezone you live in
  • check if daylight savings in on
  • check the current time in UTC or a different time zone

Date & Time Formats

After the timezones and daylight savings detour, let us get back on path andexplore another important aspect, date & time formats. Although it is a goodpractice to adher to ISO 8601 format, not all date/time data will comply withit. In real world, date/time data may come in all types of weird formats. Belowis a sample

Format
December 12, 2019
12th Dec, 2019
Dec 12th, 19
12-Dec-19
2019 December
12.12.19

When the data is not in the default ISO 8601 format, we need to explicitlyspecify the format in R. We do this using conversion specifications. Aconversion specification is introduced by %, usually followed by a singleletter or O or E and then a single letter.

Conversion Specifications

SpecificationDescriptionExample
%dDay of the month (decimal number)12
%mMonth (decimal number)12
%bMonth (abbreviated)Dec
%BMonth (full name)December
%yYear (2 digit)19
%YYear (4 digit)2019
%HHour8
%MMinute5
%SSecond3

Time to work through a few examples. Let us say you are dealing with dates inthe format 19/12/12. In this format, the year comes first followed by monthand the date; each separated by a slash (/). The year consists of only 2digits i.e.it does not include the century. Let us now map each component ofthe date to the conversion specification table shown at the beginning.

DateSpecification
19%y
12%m
12%d

Using the format argument, we will specify the conversion specification as a character vectori.e.enclosed in quotes.

as.Date("19/12/12", format = "%y/%m/%d")## [1] "2019-12-12"

Another way in which the release data can be written is 2019-Dec-12. We stillhave the year followed by the month and the date but there are a few changeshere:

  • the components are separated by a - instead of /
  • year has 4 digits i.e.includes the century
  • the month is specified using abbreviation instead of digits

Let us map the components to the format table:

DateSpecification
2019%Y
Dec%b
12%d

Let us specify the format for the date using the above mapping.

as.Date("2019-Dec-12", format = "%Y-%b-%d")## [1] "2019-12-12"

In both the above examples, we have not dealt with time components. Let usinclude the release time of R 3.6.2 in the next one i.e.19/12/12 08:05:03.

DateSpecification
19%y
12%m
12%d
08%H
05%M
03%S

Since we are dealing with time, we will use as.POSIXct() instead ofas.Date().

as.POSIXct("19/12/12 08:05:03", tz = "UTC", format = "%y/%m/%d %H:%M:%S")## [1] "2019-12-12 08:05:03 UTC"

In the below table, we look at some of the most widely used conversionspecifications. You can learn more about these specifications by running?strptime or help(strptime).

SpecificationDescription
%aAbbreviated weekday
%AFull weekday
%CCentury (00-99)
%DSame as %m/%d/%y
%eDay of month [1 - 31]
%FSame as %Y-%m-%d
%hSame as %b
%IHours as decimal [01 - 12]
%jDay of year [001 - 366]
%RSame as %H:%M
%tTab
%TSame as %H:%M:%S
%uWeekday 1 - 7
%UWeek of year [00 - 53]
%VWeek of year [01 - 53]
%wWeekday 0 - 6
%WWeek of year [00 - 53]

We have included a lot of practice questions for you to explore the differentdate/time formats. The solutions are available in the Learning Management Systemas well as in our GitHub repo. Try them and let us know if you have any doubts.

Guess Format

guess_formats() from lubridate is a very useful function. It will guess thedate/time format if you specify the order in which year, month, date, hour,minute and second appear.

release_date_formats <- c("December 12th 2019", "Dec 12th 19", "dec 12 2019")guess_formats(release_date_formats, orders = "mdy", print_matches = TRUE)## Omdy mdy ## [1,] "December 12th 2019" "%Om %dth %Y" "%B %dth %Y"## [2,] "Dec 12th 19" "%Om %dth %y" "%b %dth %y"## [3,] "dec 12 2019" "%Om %d %Y" "%b %d %Y"## Omdy Omdy Omdy mdy mdy ## "%Om %dth %Y" "%Om %dth %y" "%Om %d %Y" "%B %dth %Y" "%b %dth %y" ## mdy ## "%b %d %Y"

Your Turn

Below, we have specified July 5th, 2019 in different ways. Create the date using as.Date() while specifying the correct format for each of them.

  • 05.07.19
  • 5-July 2019
  • July 5th, 2019
  • July 05, 2019
  • 2019-July- 05
  • 05/07/2019
  • 07/05/2019
  • 7/5/2019
  • 07/5/19
  • 2019-07-05

Parse Date & Time

While creating date-time objects, we specified different formats using theconversion specification but most often you will not create date/time andinstead deal with data that comes your way from a database or API orcolleague/collaborator. In such cases, we need to be able to parse date/timefrom the data provided to us. In this section, we will focus on parsingdate/time from character data. Both base R and the lubridate package offerfunctions to parse date and time and we will explore a few of them in thissection. We will initially use functions from base R and later on explore thosefrom lubridate which will give us an opportunity to compare and contrast. Itwill also allow us to choose the functions based on the data we are dealingwith.

strptime() will convert character data to POSIXlt. You will use this whenconverting from character data to date/time. On the other hand, if you want toconvert date/time to character data, use any of the following:

  • strftime()
  • format()
  • as.character()

The above functions will convert POSIXct/POSIXlt to character. Let us startwith a simple example. The data we have been supplied has date/time ascharacter data and in the format YYYYMMDD i.e.nothing separates the year,month and date from each other. We will use strptime() to convert this to anobject of class POSIXlt.

rel_date <- strptime("20191212", format = "%Y%m%d")class(rel_date)## [1] "POSIXlt" "POSIXt"

If you have a basic knowledge of conversion specifications, you can usestrptime() to convert character data to POSIXlt. Let us quickly explore thefunctions to convert date/time to character data before moving on to thefunctions from lubridate.

rel_date_strf <- strftime(rel_date)class(rel_date_strf)## [1] "character"rel_date_format <- format(rel_date)class(rel_date_format)## [1] "character"rel_date_char <- as.character(rel_date)class(rel_date_char)## [1] "character"

As you can see, all the 3 functions converted date/time to character. Time tomove on and explore the lubridate package. We will start with an example inwhich the release date is formatted in 3 different ways but they have one thingin common i.e.the order in which the components appear. In all the 3 formats,the year is followed by the month and then the date.

To parse the release date, we will use parse_date_time() from lubridate whichparses the input into POSIXct objects.

release_date <- c("19-12-12", "20191212", "19-12 12")parse_date_time(release_date, "ymd")## [1] "2019-12-12 UTC" "2019-12-12 UTC" "2019-12-12 UTC"parse_date_time(release_date, "y m d")## [1] "2019-12-12 UTC" "2019-12-12 UTC" "2019-12-12 UTC"parse_date_time(release_date, "%y%m%d")## [1] "2019-12-12 UTC" "2019-12-12 UTC" "2019-12-12 UTC"

Try to use strptime() in the above example and see what happens. Now, let uslook at another data set.

release_date <- c("19-07-05", "2019-07-05", "05-07-2019")

What happens in the below case? The same date appears in multiple formats. Howdo we parse them? parse_date_time() allows us to specify mutiple date-timeformats. Let us first map the dates to their formats.

DateSpecification
19-07-05ymd
2019-07-05ymd
05-07-2019dmy

The above specifications can be supplied as a character vector.

parse_date_time(release_date, c("ymd", "ymd", "dmy"))## [1] "2019-07-05 UTC" "2019-07-05 UTC" "2019-07-05 UTC"

Great! We have used both strptime() and parse_date_time() now. Can you tellwhat differentiates parse_date_time() when compared to strptime()? Wesummarize it in the points below:

  • no need to include % prefix or separator
  • specify several date/time formats

There are other helper functions that can be used to

  • parse dates with only year, month, day components
  • parse dates with year, month, day, hour, minute, seconds components
  • parse dates with only hour, minute, second components

and are explored in the below examples.

# year/month/dateymd("2019-12-12")## [1] "2019-12-12"# year/month/dateymd("19/12/12")## [1] "2019-12-12"# date/month/yeardmy(121219)## [1] "2019-12-12"# year/month/date/hour/minute/secondymd_hms(191212080503)## [1] "2019-12-12 08:05:03 UTC"# hour/minute/secondhms("8, 5, 3")## [1] "8H 5M 3S"# hour/minute/secondhms("08:05:03")## [1] "8H 5M 3S"# minute/secondms("5,3")## [1] "5M 3S"# hour/minutehm("8, 5")## [1] "8H 5M 0S"

Note, in a couple of cases where the components are not separated by /, - orspace, we have not enclosed the values in quotes.

Your Turn

Below, we have specified July 5th, 2019 in different ways. Parse the dates using strptime() or parse_date_time() or any other helper function.

  • July-05-19
  • JUL-05-19
  • 05.07.19
  • 5-July 2019
  • July 5th, 2019
  • July 05, 2019
  • 2019-July- 05
  • 05/07/2019
  • 07/05/2019
  • 7/5/2019
  • 07/5/19
  • 2019-07-05

Date & Time Components

In the second section, we discussed the downside of saving date/time ascharacter/string in R. One of the points we discussed was that we can’t extractcomponents such as year, month, day etc. In this section, we will learn toextract date/time components such as

  • year
  • month
  • date
  • week
  • day
  • quarter
  • semester
  • hour
  • minute
  • second
  • timezone

A Comprehensive Introduction to Handling Date & Time in R (8)

The below table outlines the functions we will explore in the first part of thissection.

FunctionDescription
year()Get year
month()Get month (number)
month(label = TRUE)Get month (abbreviated name)
month(abbr = FALSE)Get month (full name)
months()Get month
week()Get week

Year

release_date <- ymd_hms("2019-12-12 08:05:03")year(release_date) ## [1] 2019

Month

month() will return the month as a number i.e.12 for December.

month(release_date)## [1] 12

Instead, if you want the name of the month , use the label argument and set itto TRUE. Now it returns Dec instead of 12.

month(release_date, label = TRUE)## [1] Dec## 12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < ... < Dec

But this is the abbreviated name and not the full name. How do we get the fullname of the month? Set the abbr argument to FALSE.

month(release_date, label = TRUE, abbr = FALSE)## [1] December## 12 Levels: January < February < March < April < May < June < ... < December

Ah! now we can see the full name of the month. months() from base R willreturn the full name of the month by default. If you want the abbreviated name,use the abbreviate argument and set it to TRUE.

months(release_date)## [1] "December"

Week

week() returns the number of complete 7 day periods between the date and 1stJanuary plus one.

week(release_date)## [1] 50

Day

Use day() to extract the date component. There are other variations such as

FunctionDescription
dayGet day
mday()Day of the month
wday()Day of the week
qday()Day of quarter
yday()Day of year
weekdays()Day of week
days_in_month()Days in the month
day(release_date)## [1] 12mday(release_date) ## [1] 12qday(release_date) ## [1] 73yday(release_date) ## [1] 346

wday can return

  • a number
  • abbreviation of the weekday
  • full name of the weekday
wday(release_date) ## [1] 5wday(release_date, label = TRUE)## [1] Thu## Levels: Sun < Mon < Tue < Wed < Thu < Fri < Satwday(release_date, label = TRUE, abbr = FALSE) ## [1] Thursday## 7 Levels: Sunday < Monday < Tuesday < Wednesday < Thursday < ... < Saturday

weekdays() from base R also returns the day of the week (the name and notthe number). If you want the abbreviated name, use the abbreviate argument.

weekdays(release_date)## [1] "Thursday"weekdays(release_date, abbreviate = TRUE)## [1] "Thu"

Days in Month

If you want to know the number of days in the month, use days_in_month().In our example, the month is December and it has 31 days.

days_in_month(release_date)## Dec ## 31

Hour, Minute & Seconds

FunctionDescription
hour()Get hour
minute()Get minute
second()Get second
seconds()Number of seconds since 1970-01-01

So far we have been looking at date components. Now, let us look at timecomponents.

hour(release_date)## [1] 8minute(release_date)## [1] 5second(release_date)## [1] 3

seconds() returns the number of seconds since 1970-01-01.

seconds(release_date)## [1] "1576137903S"

Quarter & Semester

A Comprehensive Introduction to Handling Date & Time in R (9)

quarter() will return the quarter from the date. December is in the 4thquarter and hence it returns 4.

quarter(release_date)## [1] 4

If you want the year along with the quarter, set the with_year argument toTRUE.

quarter(release_date, with_year = TRUE)## [1] 2019.4

In India, the fiscal starts in April and December falls in the 3rd quarter. Howcan we accommodate this change? The fiscal_start argument allows us to set themonth in which the fiscal begins. We will set it to 4 for April. Now it returns3 instead of 4.

quarter(release_date, fiscal_start = 4) ## [1] 3

quarters() from base R also returns the quarter.

quarters(release_date)## [1] "Q4"
FunctionDescription
quarter()Get quarter
quarter(with_year = TRUE)Quarter with year
quarter(fiscal_start = 4)Fiscal starts in April
quarters()Get quarter
semester()Get semester

Case Study

Extract Date, Month & Year from Due Date

Let us now extract the date, month and year from the Due column.

transact %>% mutate( due_day = day(Due), due_month = month(Due), due_year = year(Due) )## # A tibble: 2,466 x 6## Invoice Due Payment due_day due_month due_year## <date> <date> <date> <int> <dbl> <dbl>## 1 2013-01-02 2013-02-01 2013-01-15 1 2 2013## 2 2013-01-26 2013-02-25 2013-03-03 25 2 2013## 3 2013-07-03 2013-08-02 2013-07-08 2 8 2013## 4 2013-02-10 2013-03-12 2013-03-17 12 3 2013## 5 2012-10-25 2012-11-24 2012-11-28 24 11 2012## 6 2012-01-27 2012-02-26 2012-02-22 26 2 2012## 7 2013-08-13 2013-09-12 2013-09-09 12 9 2013## 8 2012-12-16 2013-01-15 2013-01-12 15 1 2013## 9 2012-05-14 2012-06-13 2012-07-01 13 6 2012## 10 2013-07-01 2013-07-31 2013-07-26 31 7 2013## # ... with 2,456 more rows

Data Sanitization

Let us do some data sanitization. If the due day happens to be February 29,let us ensure that the due year is a leap year. Below are the steps to checkif the due year is a leap year:

  • we will extract the following from the due date:
    • day
    • month
    • year
  • we will then create a new column is_leap which will have be set to TRUE ifthe year is a leap year else it will be set to FALSE
  • filter all the payments due on 29th Feb
  • select the following columns:
    • Due
    • is_leap
transact %>% mutate( due_day = day(Due), due_month = month(Due), due_year = year(Due), is_leap = leap_year(due_year) ) %>% filter(due_month == 2 & due_day == 29) %>% select(Due, is_leap) ## # A tibble: 4 x 2## Due is_leap## <date> <lgl> ## 1 2012-02-29 TRUE ## 2 2012-02-29 TRUE ## 3 2012-02-29 TRUE ## 4 2012-02-29 TRUE

Invoices Distribution by Quarter

Let us count the invoices due for each quarter.

transact %>% mutate( quarter_due = quarter(Due) ) %>% count(quarter_due)## # A tibble: 4 x 2## quarter_due n## <int> <int>## 1 1 521## 2 2 661## 3 3 618## 4 4 666

Your Turn

Get the R release dates using r_versions() from the rversions package andtabulate the following

  • year
  • month with label
  • weekday with label
  • hour
  • and quarter

Create, Update & Verify

In the second section, we learnt to create date-time objects using as.Date(),as.POSIXct() etc. In this section, we will explore a few other functions thatwill allow us to do the same

  • make_date()
  • make_datetime()

Create

To create date without time components, use make_date() and specify thefollowing:

  • year
  • month
  • date

We need to specify all the components in numbers i.e.we cannot use Dec orDecember for the month. It has to be 12.

make_date(year = 2019, month = 12, day = 12)## [1] "2019-12-12"

When you need to include time components, use make_datetime().

make_datetime(year = 2019, month = 12, day = 12, hour = 08, min = 05, sec = 03, tz = "UTC")## [1] "2019-12-12 08:05:03 UTC"

Update

Let us look at another scenario. You have a date-time object and want to changeone of its components i.e.any of the following

  • year
  • month
  • date

Instead of creating another date-time object, you can change any of thecomponents using update(). In the below example, we will start with the dateof release of R version 3.6.1 and using update(), we will change it to2019-12-12.

prev_release <- ymd("2019-07-05")prev_release %>% update(year = 2019, month = 12, mday = 12)## [1] "2019-12-12"

Date Sequence

So far we have created a single date-time instance. How about creating asequence of dates? We can do that using seq.Date(). We need to specify thefrom date as the bare minimum input. If the end date is not specified, it willcreate the sequence uptil the current date.

The interval of the sequence can be specified in any of the following units:

  • day
  • week
  • month
  • quarter
  • year

We can add the following to the interval units

  • integer
  • + / - (increment or decrement)

Using the integer, we can specify multiples of the units mentioned and using thesign, we can specify whether to increment or decrement.

The below table displays the main arguments used in seq.Date():

FunctionDescription
fromStarting date of the sequence
byEnd date of the sequence
toDate increment of the sequence
length.outLength of the sequence
along.withUse length of this value as length of sequence

In the first example, we will create a sequence of dates from 2010-01-01 to2019-12-31. The unit of increment should be a year i.e.the differencebetween the dates in the sequence should be 1 year, specified using the byargument.

seq.Date(from = as.Date("2010-01-01"), to = as.Date("2019-12-31"), by = "year")## [1] "2010-01-01" "2011-01-01" "2012-01-01" "2013-01-01" "2014-01-01"## [6] "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01"

In the next example, we change the unit of increment to a quarter i.e.thedifference between the dates in the sequence should be a quarter or 3 months.

seq.Date(from = as.Date("2009-12-12"), to = as.Date("2019-12-12"), by = "quarter")## [1] "2009-12-12" "2010-03-12" "2010-06-12" "2010-09-12" "2010-12-12"## [6] "2011-03-12" "2011-06-12" "2011-09-12" "2011-12-12" "2012-03-12"## [11] "2012-06-12" "2012-09-12" "2012-12-12" "2013-03-12" "2013-06-12"## [16] "2013-09-12" "2013-12-12" "2014-03-12" "2014-06-12" "2014-09-12"## [21] "2014-12-12" "2015-03-12" "2015-06-12" "2015-09-12" "2015-12-12"## [26] "2016-03-12" "2016-06-12" "2016-09-12" "2016-12-12" "2017-03-12"## [31] "2017-06-12" "2017-09-12" "2017-12-12" "2018-03-12" "2018-06-12"## [36] "2018-09-12" "2018-12-12" "2019-03-12" "2019-06-12" "2019-09-12"## [41] "2019-12-12"

We will now create a sequence of dates but instead of specifying the unit ofincrement, we specify the number of dates in the sequence i.e.the length of thesequence. We do this using the length.out argument which specifies the desiredlength of the sequence. We want the sequence to have 10 dates including thestart and end date, and hence we supply the value 10 for the length.outargument.

seq.Date(from = as.Date("2010-01-01"), to = as.Date("2019-12-31"), length.out = 10)## [1] "2010-01-01" "2011-02-10" "2012-03-22" "2013-05-02" "2014-06-11"## [6] "2015-07-22" "2016-08-31" "2017-10-10" "2018-11-20" "2019-12-31"

In all of the previous examples, we have specified both the start and the enddate. Let us look at a few examples where we create a sequence of dates wherewe only specify the start date. In the below example, we want to create asequence of dates starting from 2010-01-01. The unit of increment should be 1year i.e.the difference between the dates in the sequence should be 1 year andthe length of the sequence should be 10 i.e.the number of dates including thestart date should be 10.

seq.Date(from = as.Date("2010-01-01"), by = "year", length.out = 10)## [1] "2010-01-01" "2011-01-01" "2012-01-01" "2013-01-01" "2014-01-01"## [6] "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01"

The unit of increment can include multiples and +/- sign i.e.it can be anunit of increment or decrement. In the next example, we can increment the datesin the sequence by 2 i.e.the difference between the dates should be 2instead of 1. This is achieved by specifying the unit of increment (multiple)first followed by a space and then the unit. In our example, it is 2 year. Asyou can see, the sequence now goes all the way till 2028 and the gap betweenthe dates is 2 years.

seq.Date(from = as.Date("2010-01-01"), by = "2 year", length.out = 10)## [1] "2010-01-01" "2012-01-01" "2014-01-01" "2016-01-01" "2018-01-01"## [6] "2020-01-01" "2022-01-01" "2024-01-01" "2026-01-01" "2028-01-01"

Let us say instead of increment we want to decrement the dates i.e.the sequenceof dates will go backwards as shown in the next example. We achieve this byusing the - sign along with the unit of decrement. The sequence of dates innext example starts from 2010 and goes back upto 1992 and the differencebetween the dates in 2 years.

seq.Date(from = as.Date("2010-01-01"), by = "-2 year", length.out = 10)## [1] "2010-01-01" "2008-01-01" "2006-01-01" "2004-01-01" "2002-01-01"## [6] "2000-01-01" "1998-01-01" "1996-01-01" "1994-01-01" "1992-01-01"

In the last example, we will explore the along.with argument. Here we havesupplied a vector which is a sequence of numbers from 1 to 10. The length ofthis vector is 10 and the same length is used as the length of the sequence i.e.the length of value supplied to along.with is also the length of the sequence.

seq.Date(from = as.Date("2010-01-01"), by = "-2 year", along.with = 1:10)## [1] "2010-01-01" "2008-01-01" "2006-01-01" "2004-01-01" "2002-01-01"## [6] "2000-01-01" "1998-01-01" "1996-01-01" "1994-01-01" "1992-01-01"

Verify Type

How do you check if the data is a date-time object? You can do that using anyof the following from the lubridate package.

  • is.Date()
  • is.POSIXct()
  • is.POSIXlt()
is.Date(release_date)## [1] FALSEis.POSIXct(release_date)## [1] TRUEis.POSIXlt(release_date)## [1] FALSE

Your Turn

  • R 2.0.0 was released on 2004-10-04 14:24:38. Create this date using bothmake_date() and make_datetime()

  • R 3.0.0 was released on 2013-04-03 07:12:36. Update the date created in theprevious step to the above using update()

Intervals, Duration & Period

In this section, we will learn about

  • intervals
  • duration
  • and period

Interval

An interval is a timespan defined by two date-times. Let us represent the lengthof the course using interval.

A Comprehensive Introduction to Handling Date & Time in R (10)

course_start <- as_date('2017-04-12')course_end <- as_date('2017-04-21')interval(course_start, course_end)## [1] 2017-04-12 UTC--2017-04-21 UTC

If you observe carefully, the interval is represented by the course start andend dates. We will learn how to use intervals in the case study.

Overlapping Intervals

Let us say you are planning a vacation and want to check if the vacationdates overlap with the course dates. You can do this by:

  • creating vacation and course intervals
  • use int_overlaps() to check if two intervals overlap. It returns TRUEif the intervals overlap else FALSE.

Let us use the vacation start and end dates to create vacation_intervaland then check if it overlaps with course_interval.

A Comprehensive Introduction to Handling Date & Time in R (11)

vacation_start <- as_date('2017-04-19')vacation_end <- as_date('2017-04-25')course_interval <- interval(course_start, course_end)vacation_interval <- interval(vacation_start, vacation_end)int_overlaps(course_interval, vacation_interval)## [1] TRUE

How many invoices were settled within due date?

Let us use intervals to count the number of invoices that were settled withinthe due date. To do this, we will:

  • create an interval for the invoice and due date
  • create a new column due_next by incrementing the due date by 1 day
  • another interval for due_next and the payment date
  • if the intervals overlap, the payment was made within the due date
transact %>% mutate( inv_due_interval = interval(Invoice, Due), due_next = Due + days(1), due_pay_interval = interval(due_next, Payment), overlaps = int_overlaps(inv_due_interval, due_pay_interval) ) %>% select(Invoice, Due, Payment, overlaps)## # A tibble: 2,466 x 4## Invoice Due Payment overlaps## <date> <date> <date> <lgl> ## 1 2013-01-02 2013-02-01 2013-01-15 TRUE ## 2 2013-01-26 2013-02-25 2013-03-03 FALSE ## 3 2013-07-03 2013-08-02 2013-07-08 TRUE ## 4 2013-02-10 2013-03-12 2013-03-17 FALSE ## 5 2012-10-25 2012-11-24 2012-11-28 FALSE ## 6 2012-01-27 2012-02-26 2012-02-22 TRUE ## 7 2013-08-13 2013-09-12 2013-09-09 TRUE ## 8 2012-12-16 2013-01-15 2013-01-12 TRUE ## 9 2012-05-14 2012-06-13 2012-07-01 FALSE ## 10 2013-07-01 2013-07-31 2013-07-26 TRUE ## # ... with 2,456 more rows

Below we show another method to count the number of invoices paid within thedue date. Instead of using days to change the due date, we use int_shiftto shift it by 1 day.

transact %>% mutate( inv_due_interval = interval(Invoice, Due), due_pay_interval = interval(Due, Payment), due_pay_next = int_shift(due_pay_interval, by = days(1)), overlaps = int_overlaps(inv_due_interval, due_pay_next) ) %>% select(Invoice, Due, Payment, overlaps)## # A tibble: 2,466 x 4## Invoice Due Payment overlaps## <date> <date> <date> <lgl> ## 1 2013-01-02 2013-02-01 2013-01-15 TRUE ## 2 2013-01-26 2013-02-25 2013-03-03 FALSE ## 3 2013-07-03 2013-08-02 2013-07-08 TRUE ## 4 2013-02-10 2013-03-12 2013-03-17 FALSE ## 5 2012-10-25 2012-11-24 2012-11-28 FALSE ## 6 2012-01-27 2012-02-26 2012-02-22 TRUE ## 7 2013-08-13 2013-09-12 2013-09-09 TRUE ## 8 2012-12-16 2013-01-15 2013-01-12 TRUE ## 9 2012-05-14 2012-06-13 2012-07-01 FALSE ## 10 2013-07-01 2013-07-31 2013-07-26 TRUE ## # ... with 2,456 more rows

You might be thinking why we incremented the due date by a day before creatingthe interval between the due day and the payment day. If we do not increment,both the intervals will share a common date i.e.the due date and they willalways overlap as shown below:

transact %>% mutate( inv_due_interval = interval(Invoice, Due), due_pay_interval = interval(Due, Payment), overlaps = int_overlaps(inv_due_interval, due_pay_interval) ) %>% select(Invoice, Due, Payment, overlaps)## # A tibble: 2,466 x 4## Invoice Due Payment overlaps## <date> <date> <date> <lgl> ## 1 2013-01-02 2013-02-01 2013-01-15 TRUE ## 2 2013-01-26 2013-02-25 2013-03-03 TRUE ## 3 2013-07-03 2013-08-02 2013-07-08 TRUE ## 4 2013-02-10 2013-03-12 2013-03-17 TRUE ## 5 2012-10-25 2012-11-24 2012-11-28 TRUE ## 6 2012-01-27 2012-02-26 2012-02-22 TRUE ## 7 2013-08-13 2013-09-12 2013-09-09 TRUE ## 8 2012-12-16 2013-01-15 2013-01-12 TRUE ## 9 2012-05-14 2012-06-13 2012-07-01 TRUE ## 10 2013-07-01 2013-07-31 2013-07-26 TRUE ## # ... with 2,456 more rows

Shift Interval

Intervals can be shifted too. In the below example, we shift the courseinterval by:

  • 1 day
  • 3 weeks
  • 1 year

A Comprehensive Introduction to Handling Date & Time in R (12)

course_interval <- interval(course_start, course_end)# shift course_interval by 1 day int_shift(course_interval, by = days(1))## [1] 2017-04-13 UTC--2017-04-22 UTC# shift course_interval by 3 weeksint_shift(course_interval, by = weeks(3))## [1] 2017-05-03 UTC--2017-05-12 UTC# shift course_interval by 1 yearint_shift(course_interval, by = years(1))## [1] 2018-04-12 UTC--2018-04-21 UTC

Within

Let us assume that we have to attend a conference in April 2017. Does itclash with the course? We can answer this using %within% which willreturn TRUE if a date falls within an interval.

A Comprehensive Introduction to Handling Date & Time in R (13)

conference <- as_date('2017-04-15')conference %within% course_interval## [1] TRUE

How many invoices were settled within due date?

Let us use %within% to count the number of invoices that were settled withinthe due date. We will do this by:

  • creating an interval for the invoice and due date
  • check if the payment date falls within the above interval
transact %>% mutate( inv_due_interval = interval(Invoice, Due), overlaps = Payment %within% inv_due_interval ) %>% select(Due, Payment, overlaps)## # A tibble: 2,466 x 3## Due Payment overlaps## <date> <date> <lgl> ## 1 2013-02-01 2013-01-15 TRUE ## 2 2013-02-25 2013-03-03 FALSE ## 3 2013-08-02 2013-07-08 TRUE ## 4 2013-03-12 2013-03-17 FALSE ## 5 2012-11-24 2012-11-28 FALSE ## 6 2012-02-26 2012-02-22 TRUE ## 7 2013-09-12 2013-09-09 TRUE ## 8 2013-01-15 2013-01-12 TRUE ## 9 2012-06-13 2012-07-01 FALSE ## 10 2013-07-31 2013-07-26 TRUE ## # ... with 2,456 more rows

Duration

Duration is timespan measured in seconds. To create a duration object, useduration(). The timespan can be anything from seconds to years but it will berepresented as seconds. Let us begin by creating a duration object where the timespan is in seconds.

duration(50, "seconds")## [1] "50s"

Another way to specify the above timespan is shown below:

duration(second = 50)## [1] "50s"

As you can see, the output is same in both the cases. Let us increase the timespan to 60 seconds and see what happens.

duration(second = 60)## [1] "60s (~1 minutes)"

Although the timespan is primarily measured in seconds, it also shows ~1 minutes in the brackets. As the length of the timespan increases i.e.the number becomes large, it is represented using larger units such as hours and days. In the below examples, as the number of seconds increases, you can observe larger units being used to represent the timespan.

# minutesduration(minute = 50)## [1] "3000s (~50 minutes)"duration(minute = 60)## [1] "3600s (~1 hours)"# hoursduration(hour = 23)## [1] "82800s (~23 hours)"duration(hour = 24)## [1] "86400s (~1 days)"

The following helper functions can be used to create duration objects as well.

# defaultdseconds()## [1] "1s"dminutes()## [1] "60s (~1 minutes)"# secondsduration(second = 59)## [1] "59s"dseconds(59)## [1] "59s"# minutesduration(minute = 50)## [1] "3000s (~50 minutes)"dminutes(50)## [1] "3000s (~50 minutes)"# hoursduration(hour = 36)## [1] "129600s (~1.5 days)"dhours(36)## [1] "129600s (~1.5 days)"# weeksduration(week = 56)## [1] "33868800s (~1.07 years)"dweeks(56)## [1] "33868800s (~1.07 years)"

Let us use the above helper functions to get the course length in different units.

A Comprehensive Introduction to Handling Date & Time in R (14)

# course length in seconds course_interval / dseconds()## [1] 777600# course length in minutescourse_interval / dminutes()## [1] 12960# course length in hourscourse_interval / dhours()## [1] 216# course length in weekscourse_interval / dweeks()## [1] 1.285714# course length in yearscourse_interval / dyears()## [1] 0.02465753

Period

A period is a timespan defined in units such as years, months, and days. Inthe below examples, we use period() to represent timespan using differentunits.

# secondperiod(5, "second")## [1] "5S"period(second = 5)## [1] "5S"# minute & secondperiod(c(3, 5), c("minute", "second"))## [1] "3M 5S"period(minute = 3, second = 5)## [1] "3M 5S"# hour, minte & secondperiod(c(1, 3, 5), c("hour", "minute", "second"))## [1] "1H 3M 5S"period(hour = 1, minute = 3, second = 5)## [1] "1H 3M 5S"# day, hour, minute & secondperiod(c(3, 1, 3, 5), c("day", "hour", "minute", "second"))## [1] "3d 1H 3M 5S"period(day = 3, hour = 1, minute = 3, second = 5)## [1] "3d 1H 3M 5S"

A Comprehensive Introduction to Handling Date & Time in R (15)

Let us get the course length in different units using as.period().

# course length in secondas.period(course_interval, unit = "seconds")## [1] "777600S"# course length in hours and minutesas.period(course_interval, unit = "minutes")## [1] "12960M 0S"# course length in hours, minutes and secondsas.period(course_interval, unit = "hours")## [1] "216H 0M 0S"

time_length() computes the exact length of a timespan i.e.duration, interval or period. Let us use time_length() to compute the length of thecourse in different units.

A Comprehensive Introduction to Handling Date & Time in R (16)

# course length in secondstime_length(course_interval, unit = "seconds")## [1] 777600# course length in minutestime_length(course_interval, unit = "minutes")## [1] 12960# course length in hourstime_length(course_interval, unit = "hours")## [1] 216

Round & Rollback

In this section, we will learn to round date/time to the nearest unit and rollback dates.

Rounding Dates

We will explore functions for rounding dates

  • to the nearest value using round_dates()
  • down using floor_date()
  • up using ceiling_date()

The unit for rounding can be any of the following:

  • second
  • minute
  • hour
  • day
  • week
  • month
  • bimonth
  • quarter
  • season
  • halfyear
  • and year

We will look at a few examples using round_date() and you will then practiceusing the other two functions.

# minuteround_date(release_date, unit = "minute")## [1] "2019-12-12 08:05:00 UTC"round_date(release_date, unit = "mins")## [1] "2019-12-12 08:05:00 UTC"round_date(release_date, unit = "5 mins")## [1] "2019-12-12 08:05:00 UTC"# hourround_date(release_date, unit = "hour")## [1] "2019-12-12 08:00:00 UTC"# dayround_date(release_date, unit = "day")## [1] "2019-12-12 UTC"

Rollback

Use rollback() if you want to change the date to the last day of the previousmonth or the first day of the month.

rollback(release_date)## [1] "2019-11-30 08:05:03 UTC"

To change the date to the first day of the month, use the roll_to_firstargument and set it to TRUE.

rollback(release_date, roll_to_first = TRUE)## [1] "2019-12-01 08:05:03 UTC"

Your Turn

  • round up R release dates to hours
  • round down R release dates to minutes
  • rollback R release dates to the beginning of the month

Readings & References

*As the reader of this blog, you are our most important critic and commentator.We value your opinion and want to know what we are doing right, what we coulddo better, what areas you would like to see us publish in, and any other wordsof wisdom you are willing to pass our way.

We welcome your comments. You can email to let us know what you did or did notlike about our blog as well as what we can do to make our post better.*

Email: [emailprotected]

Related

To leave a comment for the author, please follow the link and comment on their blog: Rsquared Academy Blog.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.

Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

A Comprehensive Introduction to Handling Date & Time in R (2024)

References

Top Articles
50 years ago, Independent Life was more than a tall building in Jacksonville | Mark Woods
Richmond Results: August 11, 2024 (NASCAR Cup Series) - Racing News
Great Clips Mount Airy Nc
Po Box 7250 Sioux Falls Sd
Www.1Tamilmv.cafe
Craigslist Pets Longview Tx
Restaurer Triple Vitrage
Directions To Franklin Mills Mall
Room Background For Zepeto
Poe Pohx Profile
The Best English Movie Theaters In Germany [Ultimate Guide]
Learn How to Use X (formerly Twitter) in 15 Minutes or Less
Driving Directions To Atlanta
Hartford Healthcare Employee Tools
Oro probablemente a duna Playa e nomber Oranjestad un 200 aña pasa, pero Playa su historia ta bay hopi mas aña atras
Accuradio Unblocked
Premier Reward Token Rs3
Nene25 Sports
5 high school volleyball stars of the week: Sept. 17 edition
Tcu Jaggaer
G Switch Unblocked Tyrone
Bank Of America Financial Center Irvington Photos
NBA 2k23 MyTEAM guide: Every Trophy Case Agenda for all 30 teams
Two Babies One Fox Full Comic Pdf
Rust Belt Revival Auctions
Project Reeducation Gamcore
Olivia Maeday
Bento - A link in bio, but rich and beautiful.
2021 MTV Video Music Awards: See the Complete List of Nominees - E! Online
1979 Ford F350 For Sale Craigslist
Truvy Back Office Login
Myaci Benefits Albertsons
LG UN90 65" 4K Smart UHD TV - 65UN9000AUJ | LG CA
Stouffville Tribune (Stouffville, ON), March 27, 1947, p. 1
Kacey King Ranch
Missing 2023 Showtimes Near Mjr Southgate
Sf Bay Area Craigslist Com
First Light Tomorrow Morning
Roch Hodech Nissan 2023
Manatee County Recorder Of Deeds
That1Iggirl Mega
Craigslist Florida Trucks
888-822-3743
Despacito Justin Bieber Lyrics
LumiSpa iO Activating Cleanser kaufen | 19% Rabatt | NuSkin
'The Nun II' Ending Explained: Does the Immortal Valak Die This Time?
Brother Bear Tattoo Ideas
Zipformsonline Plus Login
2294141287
Phunextra
About us | DELTA Fiber
8663831604
Latest Posts
Article information

Author: Carmelo Roob

Last Updated:

Views: 5766

Rating: 4.4 / 5 (45 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Carmelo Roob

Birthday: 1995-01-09

Address: Apt. 915 481 Sipes Cliff, New Gonzalobury, CO 80176

Phone: +6773780339780

Job: Sales Executive

Hobby: Gaming, Jogging, Rugby, Video gaming, Handball, Ice skating, Web surfing

Introduction: My name is Carmelo Roob, I am a modern, handsome, delightful, comfortable, attractive, vast, good person who loves writing and wants to share my knowledge and understanding with you.