How to calculate with dates and hours in R

[This article was first published on Dang, another error, 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 while ago I was asked whether calculating with datums and hours is possible in R. Especially, if you added an hours to 23:45 (say Jan 1, 2010) , would R know to jump to the next day – 00:45 (jan 2, 2010)? The answer is yes. Our only job is to tell R in what format our datum and time is. After we have done so, we can use these datums and times for different calculations.

Let’s say we have a vector (or any other object type) with datum and hour:

1.1.2010 11:35

We need to tell R that this is in fact a POSIX type object, whereas we need to specify which number corresponds to what. We will tell it that the first number is day, followed by a dot (.), followed by a month, followed by a dot… You get the picture. This is done through the format argument.

dtm <- strptime(c("1.1.2010 11:35"), format = "%d.%m.%Y %H:%M", tz = "CET")

While the inclusion of tz argument (time zone) is not applicable here, be careful if you’re calculating with datums and times from different time zones. For the following examples, I’ve added another element to the vector to spice things up.

> dtm
[1] "2010-01-01 11:35:00 CET" "2010-02-01 08:45:00 CET"
> str(dtm)
 POSIXlt[1:9], format: "2010-01-01 11:35:00" "2010-02-01 08:45:00"

For pedagogic purposes, I will make things a wee more complicated (at least for novice). Let’s write two simple (and I mean SIMPLE) yet not mandatory functions that will convert hours and minutes to seconds. Because calculating with POSIX objects is done via seconds (see below), by using these functions we free ourselves from typing 3 * 3600 every time we want to use 3 hours or 3*60 for 3 minutes. At least in my view, this makes the code (where we calculate) a bit more readable.

Here are the two functions:

hrs <- function(u) {
 x <- u * 3600

mns <- function(m) {
 x <- m * 60

This will add three hours to the current date/time values in dtm

> dtm + hrs(3)
[1] "2010-01-01 14:35:00 CET" "2010-02-01 11:45:00 CET"

This will add 3 hours and 10 minutes.

> dtm + hrs(3) + mns(10)
[1] "2010-01-01 14:45:00 CET" "2010-02-01 11:55:00 CET"

If we hadn’t used our functions, our input would look like this

> dtm + 3*3600 + 10*60
 [1] "2010-01-01 14:45:00 CET" "2010-02-01 11:55:00 CET"

See, I told you hrs() and mns() is more intuitive. :P

We can also subtract. Let’s cut off 111 seconds

> dtm - 111
[1] "2010-01-01 11:33:09 CET" "2010-02-01 08:43:09 CET"

We are interested if datum will change if we add enough hours (or minutes). Let’s add 15 hours.

> dtm + hrs(15)
[1] "2010-01-02 02:35:00 CET" "2010-02-01 23:45:00 CET"

No surprises there – first element changed to the next day and the seconds element fell short for 15 minutes.

If we’re curious how far apart are two datums, we use the following function:

> difftime(dtm2[1], dtm2[2])
Time difference of -30.88194 days

All this and more can be also found in The R Book by Michael J. Crawley. This particular chapter can be accessed through the web. Data manipulations with R by Phil Specter can in part be previewed here (kudos to aL3xa for pointing it out). Help pages on datums and time classes can be found in


To leave a comment for the author, please follow the link and comment on their blog: Dang, another error. 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.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)