Iterating Between Two Datetimes, with a One Hour Step

Iterating between two DateTimes, with a one hour step

Similar to my answer in "How do I return an array of days and hours from a range?", the trick is to use to_i to work with seconds since the epoch:

('2013-01-01'.to_datetime.to_i .. '2013-02-01'.to_datetime.to_i).step(1.hour) do |date|
puts Time.at(date)
end

Note that Time.at() converts using your local time zone, so you may want to specify UTC by using Time.at(date).utc

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().

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).

How to iterate over a timespan after days, hours, weeks and months?

Use dateutil and its rrule implementation, like so:

from dateutil import rrule
from datetime import datetime, timedelta

now = datetime.now()
hundredDaysLater = now + timedelta(days=100)

for dt in rrule.rrule(rrule.MONTHLY, dtstart=now, until=hundredDaysLater):
print dt

Output is

2008-09-30 23:29:54
2008-10-30 23:29:54
2008-11-30 23:29:54
2008-12-30 23:29:54

Replace MONTHLY with any of YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, or SECONDLY. Replace dtstart and until with whatever datetime object you want.

This recipe has the advantage for working in all cases, including MONTHLY. Only caveat I could find is that if you pass a day number that doesn't exist for all months, it skips those months.

Iterate over dates range (the scala way)

You may use plusDays:

val now = DateTime.now
(0 until 5).map(now.plusDays(_)).foreach(println)

Given start and end dates:

import org.joda.time.Days

val start = DateTime.now.minusDays(5)
val end = DateTime.now.plusDays(5)

val daysCount = Days.daysBetween(start, end).getDays()
(0 until daysCount).map(start.plusDays(_)).foreach(println)

Creating a loop for two dates

Your first step should have been to look at the python datetime library.

Overall, your first solution could look something like this:

date1 = datetime.date(2004, 9, 25)
date2 = datetime.date(2004, 10, 8)
day = datetime.timedelta(days=1)

while date1 <= date2:
print date1.strftime('%Y.%m.%d')
date1 = date1 + day

(one thing to note: this will obviously clobber your date1 variable)

I would later refactor this into a daterange function so that you can do something closer to what you did; it would look like

for d in daterange(date1, date2):
print d.strftime('%Y.%m.%d')

Later on, when you develop your python skills, it could like like this:

for i in range((date2 - date1).days + 1):
print (date1 + datetime.timedelta(days=i)).strftime('%Y.%m.%d')

Or this, which would be my final version:

def daterange(d1, d2):
return (d1 + datetime.timedelta(days=i) for i in range((d2 - d1).days + 1))

for d in daterange(date1, date2):
print d.strftime('%Y.%m.%d')

How to loop between two dates


static IEnumerable<DateTime> AllDatesBetween(DateTime start, DateTime end)
{
for(var day = start.Date; day <= end; day = day.AddDays(1))
yield return day;
}

Edit: Added code to solve your particular example and to demonstrate usage:

var calculatedDates = 
new List<string>
(
AllDatesBetween
(
DateTime.Parse("2009-07-27"),
DateTime.Parse("2009-07-29")
).Select(d => d.ToString("yyyy-MM-dd"))
);

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.

Creating a range of dates in Python

Marginally better...

base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(numdays)]


Related Topics



Leave a reply



Submit