Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you iterate through every day of the year?

Tags:

c#

datetime

Given a start date of 1/1/2009 and an end date of 12/31/2009, how can I iterate through each date and retrieve a DateTime value using c#?

Thanks!

like image 602
Chris Conway Avatar asked Feb 10 '09 19:02

Chris Conway


People also ask

How do you iterate over months in Python?

Method 2: rrule rrule is a package present in dateutil library and this package consists of a method also rrule which takes dtstart, until and specific time period as parameters which are start date, end date, and time period based on iteration respectively. Specific time periods are WEEKLY, MONTHLY, YEARLY, etc.

How do I iterate through an Arraylist of a class type?

Iterate ArrayList using Stream API Java program to iterate through an ArrayList of objects with Java 8 stream API. Create a stream of elements from the list with the method stream. foreach() and get elements one by one. ArrayList<String> namesList = new ArrayList<String>(Arrays.


7 Answers

I would use a loop that looks like this

for(DateTime date = begin; date <= end; date = date.AddDays(1))
{
}

Set begin and end accordingly

like image 74
Samantha Branham Avatar answered Sep 27 '22 14:09

Samantha Branham


Another option implementing the Iterator design pattern:

This may sound unnecessary, but I depending on how to you use this functionality, you may also implement the Iterator design pattern.

Think on this. Suppose that everything works just fine, and you copy/paste all over the place the "for" sentence. And suddenly as part of the requirements, you have to iterate all the days but skip some of them ( like in calendar, skip holydays, weekends, custom etc. )

You would have to create a new "snipped" and use Calendar instead. Then search and replace all your for's.

In OOP, this could be achieved using the Iterator pattern.

From Wikpedia:

In object-oriented programming, the Iterator pattern is a design pattern in which iterators are used to access the elements of an aggregate object sequentially without exposing its underlying representation. An Iterator object encapsulates the internal structure of how the iteration occurs.

So the idea is to use a construct like this:

        DateTime fromDate = DateTime.Parse("1/1/2009");
        DateTime toDate   = DateTime.Parse("12/31/2009");

        // Create an instance of the collection class
        DateTimeEnumerator dateTimeRange = 
                              new DateTimeEnumerator( fromDate, toDate );


        // Iterate with foreach
        foreach (DateTime day in dateTimeRange )
        {
            System.Console.Write(day + " ");
        }

And then if needed you could create subclasses to implement different algorithms, one that uses AddDay(1), other that uses AddDay( 7 ) or other that simple uses Calendar instead. Etc. etc.

The idea is to lower the coupling between objects.

Again, this would be overkill for most of the cases, but if the iteration forms a relevant part of a system ( let's say , you are creating some kind of whatever notification, for an enterprise, and should adhere to different globalizations

The basic implementation of course would use the for.

public class DateTimeEnumerator : System.Collections.IEnumerable
{
    private DateTime begin;
    private DateTime end;

    public DateTimeEnumerator ( DateTime begin , DateTime end ) 
    {
        // probably create a defensive copy here... 
        this.begin = begin;
        this.end = end;
    }
    public System.Collections.IEnumerator GetEnumerator()
    {
        for(DateTime date = begin; date < end; date = date.AddDays(1))
        {
            yield return date;
        }
    }
}

Just an idea :)

like image 30
OscarRyz Avatar answered Sep 28 '22 14:09

OscarRyz


DateTime dateTime = new DateTime(2009, 1, 1);    

while(dateTime.Year < 2010)
    {

      dateTime = dateTime.AddDays(1);
    }
like image 31
kemiller2002 Avatar answered Sep 29 '22 14:09

kemiller2002


I'd use MiscUtil and its extension methods:

foreach(DateTime date in 1.January(2009)
                         .To(31.December(2009))
                         .Step(1.Days())
{
    Console.WriteLine(date);
}
like image 21
Jon Skeet Avatar answered Sep 28 '22 14:09

Jon Skeet


Set two variables:

DateTime lowValue = DateTime.Parse("1/1/2009");
DateTime highValue = DateTime.Parse("12/31/2009");

Then, add a day to the low value until it is equal to highvalue:

while (lowValue <= highValue)
{
   //Do stuff here
   lowValue = lowValue.AddDays(1);
}

Or something like that.

like image 31
jgallant Avatar answered Sep 28 '22 14:09

jgallant


An alternative method that might be more reusable is to write an extension method on DateTime and return an IEnumerable.

For example, you can define a class:

public static class MyExtensions
{
    public static IEnumerable EachDay(this DateTime start, DateTime end)
    {
        // Remove time info from start date (we only care about day). 
        DateTime currentDay = new DateTime(start.Year, start.Month, start.Day);
        while (currentDay <= end)
        {
            yield return currentDay;
            currentDay = currentDay.AddDays(1);
        }
    }
}

Now in the calling code you can do the following:

DateTime start = DateTime.Now;
DateTime end = start.AddDays(20);
foreach (var day in start.EachDay(end))
{
    ...
}

Another advantage to this approach is that it makes it trivial to add EachWeek, EachMonth etc. These will then all be accessible on DateTime.

like image 30
healsjnr Avatar answered Sep 27 '22 14:09

healsjnr


int day; for (int i = 1; i<365;i++) { day++; }

Sorry, couldn't resist.

like image 40
Robert S. Avatar answered Sep 30 '22 14:09

Robert S.