Skip to content

Iterating Through a Date Range

The Iterable and Iterator interfaces are a great way to simplify code. For example, what if you want to iterate through dates in a range? Perhaps you’d like to write code like this:

For Each day As DateTime In startDate.Range(endDate)
  ListBox1.AddRow(day.ToString)
Next

Although that is not part of the Xojo language, you can add it yourself using these Xojo features:

First, create an extension method in a module like this (make sure the method is Global):

Range(Extends startDate As DateTime, endDate As DateTime) As Iterable
  Return New DateTimeIterable(startDate, endDate)

Now add a new class, called DateTimeIterable. In its Inspector, click Interfaces and choose Iterable and click OK.

Your class now has an Iterable method on it. Before implementing that, add a Constructor:

Constructor(startDate As DateTime, endDate As DateTime)
  mStartDate = startDate
  mEndDate = endDate

Now create the two private properties:

  • mStartDate As DateTime
  • mEndDate As DateTime

Lastly, implement the Iterator method:

Return New DateTimeIterator(mStartDate, mEndDate)

With that done, now create the DateTimeIterator class and set its Interface to Iterator, which adds two methods: MoveNext and Value.

Before implementing those, add the Constructor:

Constructor(startDate As DateTime, endDate As DateTime)
  // Have to set the first date to be 1 before the actual first date
  // so that when it is first iterated it starts where we want.
  Var oneDay As New DateInterval
  oneDay.Days = 1

  mCurrentDate = startDate - oneDay
  mEndDate = endDate

Now create the private properties:

  • mEndDate As DateTime
  • mCurrentDate As DateTime

MoveNext moves to the next item in the iterator and returns True. If there is no next item it returns False. Its code:

Var oneDay As New DateInterval
oneDay.Days = 1

mCurrentDate = mCurrentDate + oneDay

If mCurrentDate <= mEndDate Then
  Return True
Else
  Return False
End If

The Value method returns the current iterator value. Its code:

Return mCurrentDate

That is it. With this setup you can now write code like this to populate a ListBox with all the days in January 2022:

Var startDate As New DateTime(2022, 1, 1)
Var endDate As New DateTime(2022, 1, 31)

For Each day As DateTime In startDate.Range(endDate)
  ListBox1.AddRow(day.ToString)
Next

Download the sample project. I hope you find this technique useful.