How to Loop Through a Date Range

How do I loop through a date range?

Well, you'll need to loop over them one way or the other. I prefer defining a method like this:

public IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for(var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}

Then you can use it like this:

foreach (DateTime day in EachDay(StartDate, EndDate))
// print it or whatever

In this manner you could hit every other day, every third day, only weekdays, etc. For example, to return every third day starting with the "start" date, you could just call AddDays(3) in the loop instead of AddDays(1).

Iterating through a range of dates in Python

Why are there two nested iterations? For me it produces the same list of data with only one iteration:

for single_date in (start_date + timedelta(n) for n in range(day_count)):
print ...

And no list gets stored, only one generator is iterated over. Also the "if" in the generator seems to be unnecessary.

After all, a linear sequence should only require one iterator, not two.

Update after discussion with John Machin:

Maybe the most elegant solution is using a generator function to completely hide/abstract the iteration over the range of dates:

from datetime import date, timedelta

def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days)):
yield start_date + timedelta(n)

start_date = date(2013, 1, 1)
end_date = date(2015, 6, 2)
for single_date in daterange(start_date, end_date):
print(single_date.strftime("%Y-%m-%d"))

NB: For consistency with the built-in range() function this iteration stops before reaching the end_date. So for inclusive iteration use the next day, as you would with range().

Loop through a date range with JavaScript

Here's a way to do it by making use of the way adding one day causes the date to roll over to the next month if necessary, and without messing around with milliseconds. Daylight savings aren't an issue either.

var now = new Date();
var daysOfYear = [];
for (var d = new Date(2012, 0, 1); d <= now; d.setDate(d.getDate() + 1)) {
daysOfYear.push(new Date(d));
}

Note that if you want to store the date, you'll need to make a new one (as above with new Date(d)), or else you'll end up with every stored date being the final value of d in the loop.

Iterating through a daterange in python

A good place to start are datetime, date and timedelta objects docs.

First, let's construct our starting date and ending date (today):

>>> from datetime import date, timedelta
>>> start = date(2015, 9, 9)
>>> end = date.today()
>>> start, end
(datetime.date(2015, 9, 9), datetime.date(2017, 9, 27))

Now let's define the unit of increment -- one day:

>>> day = timedelta(days=1)
>>> day
datetime.timedelta(1)

A nice thing about dates (date/datetime) and time deltas (timedelta) is they and can be added:

>>> start + day
datetime.date(2015, 9, 10)

We can also use format() to get that date in a human-readable form:

>>> "{date.day:02}{date.month:02}{date.year}".format(date=start+day)
'10092015'

So, when we put all this together:

from datetime import date, timedelta

start = date(2015, 9, 9)
end = date.today()
week = timedelta(days=7)

mydate = start
while mydate < end:
print("{date.day:02}{date.month:02}{date.year}".format(date=mydate))
mydate += week

we get a simple iteration over dates starting with 2015-09-09 and ending with today, incremented by 7 days (a week):

09092015
16092015
23092015
30092015
07102015
...

How to loop through dates using Bash?

Using GNU date:

d=2015-01-01
while [ "$d" != 2015-02-20 ]; do
echo $d
d=$(date -I -d "$d + 1 day")

# mac option for d decl (the +1d is equivalent to + 1 day)
# d=$(date -j -v +1d -f "%Y-%m-%d" $d +%Y-%m-%d)
done

Note that because this uses string comparison, it requires full ISO 8601 notation of the edge dates (do not remove leading zeros). To check for valid input data and coerce it to a valid form if possible, you can use date as well:

# slightly malformed input data
input_start=2015-1-1
input_end=2015-2-23

# After this, startdate and enddate will be valid ISO 8601 dates,
# or the script will have aborted when it encountered unparseable data
# such as input_end=abcd
startdate=$(date -I -d "$input_start") || exit -1
enddate=$(date -I -d "$input_end") || exit -1

d="$startdate"
while [ "$d" != "$enddate" ]; do
echo $d
d=$(date -I -d "$d + 1 day")
done

One final addition: To check that $startdate is before $enddate, if you only expect dates between the years 1000 and 9999, you can simply use string comparison like this:

while [[ "$d" < "$enddate" ]]; do

To be on the very safe side beyond the year 10000, when lexicographical comparison breaks down, use

while [ "$(date -d "$d" +%Y%m%d)" -lt "$(date -d "$enddate" +%Y%m%d)" ]; do

The expression $(date -d "$d" +%Y%m%d) converts $d to a numerical form, i.e., 2015-02-23 becomes 20150223, and the idea is that dates in this form can be compared numerically.

Loop through date range with a monthly step

There are lots of way to do it, but trying to keep it similar to what you have, removing things that are not needed, and using a Dictionary instead:

Sub test()
Dim sDate As String
Dim dict As Object
Dim Cell As Range

Set dict = CreateObject("Scripting.Dictionary")

For Each Cell In Range("F2", Range("F2").End(xlDown))
sDate = Format$(Range("D" & Cell.Row), "mm/yyyy")
If Not dict.Exists(sDate) Then
dict.Add sDate, 1
Debug.Print sDate
End If
Next

Debug.Print "Total: " & dict.Count

End Sub

There are things you can do with the Dictionary afterwards if your Debug.Print is not exactly what you needed.

How to iterate through range of Dates in Java?

Well, you could do something like this using Java 8's time-API, for this problem specifically java.time.LocalDate (or the equivalent Joda Time classes for Java 7 and older)

for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1))
{
...
}

I would thoroughly recommend using java.time (or Joda Time) over the built-in Date/Calendar classes.



Related Topics



Leave a reply



Submit