开发者

Getting all DateTimes between two 'DateTime's in C#

I have two DateTimes, and I want to get all DateTimes between these Dates. Such as, if my Dates are like 01.01.2010 - 05.01.2010, my function should return me a list of date (List), and it must contain 01.01.2010, 02.01.2010, 03.01.2010, 04.01.2010, and 05.01.2010.

I wrote a function like this. It works fine, if my dates are in a month. It won't work if my dates are like 01.01.2010 - 05.02.2010. Because the month changed, and my function can't handle it. Is there a function in C# that returns all dates between two dates? Or how can I handle month change?

public void GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
    {
        List<DateTime> allDates = new List<DateTime>();

        int starting = startingDate.Day;
    开发者_运维问答    int ending = endingDate.Day;

        for (int i = starting; i <= ending; i++)
        {
            allDates.Add(new DateTime(startingDate.Year, startingDate.Month, i));
        }

Question solved, see Tim Robinson's simple answer to use.


You can use DateTime objects directly in the loop, in place of your int. DateTime.AddDays handles month ends correctly.

for (DateTime date = startingDate; date <= endingDate; date = date.AddDays(1))
    allDates.Add(date);


How about something like this?

public IEnumerable<DateTime> DateRange(DateTime fromDate, DateTime toDate)
{
    return Enumerable.Range(0, toDate.Subtract(fromDate).Days + 1)
                     .Select(d => fromDate.AddDays(d));
}

Edit: Tested now. :)


public IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
    if (endingDate < startingDate)
    {
        throw new ArgumentException("endingDate should be after startingDate");
    }
    var ts = endingDate - startingDate;
    for (int i = 0; i < ts.TotalDays; i++)
    {
        yield return startingDate.AddDays(i);
    }
}


You were so close... just don't use the day, use the whole date.

static IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
    List<DateTime> allDates = new List<DateTime>();


    for (DateTime i = startingDate; i <= endingDate; i = i.AddDays(1))
    {
        allDates.Add(i);
    }
    return allDates.AsReadOnly();
}


Given a lowerdate value and higher date value in String and a frequency as the third parameter this method should return a dictionary of dates; where the key is the start value of a date range and the value is the respective range. This works fine if the frequency is either weekly or monthly- you can customize it as per your need. The date values passed should be in proper format or you might need to format it using tryParseExact or something like that.

    protected static Dictionary<DateTime, String> getDateRange(String lowerDate, String higherDate, String frequency)
    {
        DateTime startDate, endDate;
        startDate = Convert.ToDateTime(lowerDate);
        endDate = Convert.ToDateTime(higherDate);

        Dictionary<DateTime, String> returnDict = new Dictionary<DateTime, String>();

        while (frequency.Equals("weekly") ? (startDate.AddDays(7) <= endDate) : (startDate.AddMonths(1) <= endDate))
        {
            if (frequency.Equals("weekly"))
            {
                returnDict.Add(startDate, startDate + "-" + startDate.AddDays(7));
                startDate = startDate.AddDays(8);
            }
            if (frequency.Equals("monthly"))
            {
                returnDict.Add(startDate, startDate + "-" + startDate.AddMonths(1));
                startDate = startDate.AddMonths(1).AddDays(1);
            }
        }

        returnDict.Add(startDate, startDate + "-" + endDate);

        return returnDict;
    }


The top solutions will fail if the date includes different hours. Here is a solution getting all hours and all days:

All Days:

static public List<string> get_days_between_two_dates(DateTime start_date, DateTime end_date)
    {
        List<string> days_list = new List<string>();
        DateTime temp_start;
        DateTime temp_end;

        //--Normalize dates by getting rid of minues since they will get in the way when doing the loop
        temp_start = new DateTime(start_date.Year, start_date.Month, start_date.Day);
        temp_end = new DateTime(end_date.Year, end_date.Month, end_date.Day);

        //--Example Should return
        //--1-12-2014 5:59AM - 1-13-2014 6:01AM return 12 and 13
        for (DateTime date = temp_start; date <= temp_end; date = date.AddDays(1))
        {
            days_list.Add(date.ToShortDateString());
        }

        return days_list;
    }

All Hours:

static public List<string> get_hours_between_two_dates(DateTime start_date, DateTime end_date)
    {
        List<string> hours_24_list = new List<string>();
        DateTime temp_start;
        DateTime temp_end;

        //--Normalize dates by getting rid of minutes since they will get in the way when doing the loop
        temp_start = new DateTime(start_date.Year, start_date.Month, start_date.Day, start_date.Hour, 0, 0);
        temp_end = new DateTime(end_date.Year, end_date.Month, end_date.Day, end_date.Hour, 0, 0);

        //--Example Should return
        //--5:59AM - 6:01AM return 5am and 6am
        for (DateTime date = temp_start; date <= temp_end; date = date.AddHours(1))
        {
            hours_24_list.Add(date.ToShortTimeString());
        }

        return hours_24_list;
    }


Based on your starting code and using the features available at the time of writing, here is a quick console app to demonstrate how to do it - use AddDays() instead:

class Program
{
    static void Main(string[] args)
    {
        GetDates(new DateTime(2010, 1, 1), new DateTime(2010, 2, 5));

        Console.ReadKey();
    }

    static List<DateTime> GetDates(DateTime startDate, DateTime endDate)
    {
        List<DateTime> dates = new List<DateTime>();

        while ((startDate = startDate.AddDays(1)) < endDate)
            dates.Add(startDate);

        return dates;
    }
}

Although I think the Enumerable.Range() answer from Matt is a nicer solution.


static IEnumerable<DateTime> GetAllDatesAndInitializeTickets(DateTime startingDate, DateTime endingDate)
{
    List<DateTime> allDates = new List<DateTime>();


    for (DateTime i = startingDate; i <= endingDate; i = i.AddDays(1))
    {
        allDates.Add(i);
    }
    return allDates.AsReadOnly();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜