Create a Vector of All Days Between Two Dates
Asked Answered
C

4

104

Is there an easy way in R for me to itemize all valid days that occurred between two specified dates? For instance, I'd like the following inputs:

itemizeDates(startDate="12-30-11", endDate="1-4-12")

To produce the following dates:

"12-30-11" "12-31-11", "1-1-12", "1-2-12", "1-3-12", "1-4-12"

I'm flexible on classes and formatting of the dates, I just need an implementation of the concept.

Cockatrice answered 22/1, 2013 at 1:58 Comment(0)
B
165

You're looking for seq

> seq(as.Date("2011-12-30"), as.Date("2012-01-04"), by="days")
[1] "2011-12-30" "2011-12-31" "2012-01-01" "2012-01-02" "2012-01-03"
[6] "2012-01-04"

Or, you can use :

> as.Date(as.Date("2011-12-30"):as.Date("2012-01-04"), origin="1970-01-01")
[1] "2011-12-30" "2011-12-31" "2012-01-01" "2012-01-02" "2012-01-03"
[6] "2012-01-04"

Note that with : "Non-numeric arguments are coerced internally". Thus, we convert back to class Date, using as.Date method for class 'numeric' and provide origin.


Here's a function to meet your specific request

itemizeDates <- function(startDate="12-30-11", endDate="1-4-12", 
                         format="%m-%d-%y") {
  out <- seq(as.Date(startDate, format=format), 
             as.Date(endDate, format=format), by="days")  
  format(out, format)
}

> itemizeDates(startDate="12-30-11", endDate="1-4-12")
[1] "12-30-11" "12-31-11" "01-01-12" "01-02-12" "01-03-12" "01-04-12"
Ballyrag answered 22/1, 2013 at 2:2 Comment(3)
seq.Date even. I was not aware of its existence.Ginelle
Indeed I am. Thanks for your help!Cockatrice
I gotta say, this is one of the more efficient answers I've seenScuba
J
19

I prefer using the lubridate package to solve datetime problems. It is more intuitive and easier to understand and use once you know it.

library(lubridate)
#mdy() in lubridate package means "month-day-year", which is used to convert
#the string to date object
>start_date <- mdy("12-30-11")
>end_date <- mdy("1-4-12")
#calculate how many days in this time interval
>n_days <- interval(start_date,end_date)/days(1)
>start_date + days(0:n_days)
[1]"2011-12-30" "2011-12-31" "2012-01-01" "2012-01-02" "2012-01-03" "2012-01-04"
#convert to original format
format(start_date + days(0:n_days), format="%m-%d-%y")
[1] "12-30-11" "12-31-11" "01-01-12" "01-02-12" "01-03-12" "01-04-12"

Reference: Dates and Times Made Easy with lubridate

Judiejudith answered 3/2, 2018 at 22:28 Comment(0)
B
11

2 similar implementations in lubridate:

library(lubridate)

as_date(mdy("12-30-11"):mdy("1-4-12"))

# OR

seq(mdy("12-30-11"), mdy("1-4-12"), by = "days")

These don't format your dates in month-day-year but you can fix the formatting if you want. But year-month-day is a bit easy to work with when analyzing.

Binoculars answered 18/9, 2020 at 17:22 Comment(0)
R
2

There are a few ways you can do this using the clock package.

There is a sequencing function like many other answers, however with this function you have a finer control over the sequencing:

library(clock)

# every day between two dates
date_seq(from = Sys.Date(), to = Sys.Date() + 5, by = duration_days(1))
# [1] "2024-03-07" "2024-03-08" "2024-03-09" "2024-03-10" "2024-03-11" "2024-03-12"

# every other day between two dates
date_seq(from = Sys.Date(), to = Sys.Date() + 5, by = duration_days(2))
# [1] "2024-03-07" "2024-03-09" "2024-03-11"

# every 3rd month until total size is 3
# can do arithmetic in duration function and 
# provide explicit resolution to invalid dates
date_seq(from = date_build(2024, 3, 31), by = duration_months(sqrt(9)), 
         total_size = 3, invalid = "previous-day")
# [1] "2024-03-31" "2024-06-30" "2024-09-30"

There is also a set of spanning functions that will span from the min and max of a vector:

x <- date_build(2024, c(3, 3, 3), c(7, 8, 11))
# [1] "2024-03-07" "2024-03-08" "2024-03-11"

# spans from min 2024-03-07 to max 2024-03-11
date_spanning_seq(x)
[1] "2024-03-07" "2024-03-08" "2024-03-09" "2024-03-10" "2024-03-11"

date_spanning_seq uses day precision, so there is not as much control. calendar_spanning_seq is available where you can provide more control over how to span.

Raver answered 7/3, 2024 at 19:0 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.