Split date range into date range chunks

python split date range into chunks
divide range into intervals python
divide time into intervals python
split date range into months sql

I am looking for a method of splitting a date range into a series of date ranges by chunk size of days. I am planning on using this to buffer calls to a service which if the date range is too large, the service faults.

This is what I have come up with so far. It seems to work, but I am not sure if it will exit properly. This seems like something that has probably been done several times before, but I can't find it.

public IEnumerable<Tuple<DateTime, DateTime>> SplitDateRange(DateTime start, DateTime end, int dayChunkSize)
{
    var newStart = start;
    var newEnd = start.AddDays(dayChunkSize);

    while (true)
    {
        yield return new Tuple<DateTime, DateTime>(newStart, newEnd);

        if (newEnd == end)
            yield break;

        newStart = newStart.AddDays(dayChunkSize);
        newEnd = (newEnd.AddDays(dayChunkSize) > end ? end : newEnd.AddDays(dayChunkSize));
    }
}

I'm looking for improvement suggestions, or "Dude, use this existing function for this!"

I think your code fails when the difference between start and end is smaller than dayChunkSize. See this:

var singleRange = SplitDateRange(DateTime.Now, DateTime.Now.AddDays(7), dayChunkSize: 15).ToList();
Debug.Assert(singleRange.Count == 1);

Proposed solution:

 public static IEnumerable<Tuple<DateTime, DateTime>> SplitDateRange(DateTime start, DateTime end, int dayChunkSize)
    {
        DateTime chunkEnd;
        while ((chunkEnd = start.AddDays(dayChunkSize)) < end)
        {
            yield return Tuple.Create(start, chunkEnd);
            start = chunkEnd;
        }
        yield return Tuple.Create(start, end);
    }

segmentio/chunk-date-range: Split a date range into , Split a date range into a certain amount of equal sized chunks, or into boundaries by 'day', 'week', 'year', etc. Quickstart. var chunk = require('chunk-date-range  Split a date range into a certain amount of equal sized chunks, or into boundaries by 'day', 'week', 'year', etc.

Your code looks fine for me. I don't really like the idea of while(true) But other solution would be to use enumerable.Range:

public static IEnumerable<Tuple<DateTime, DateTime>> SplitDateRange(DateTime start, DateTime end, int dayChunkSize)
        {
            return Enumerable
                  .Range(0, (Convert.ToInt32((end - start).TotalDays) / dayChunkSize +1))
                  .Select(x => Tuple.Create(start.AddDays(dayChunkSize * (x)), start.AddDays(dayChunkSize * (x + 1)) > end
                                                                               ? end : start.AddDays(dayChunkSize * (x + 1))));
        }  

or also, this will also work:

public static IEnumerable<Tuple<DateTime, DateTime>> SplitDateRange(DateTime start, DateTime end, int dayChunkSize)
        {

            var dateCount = (end - start).TotalDays / 5;
            for (int i = 0; i < dateCount; i++)
            {
                yield return Tuple.Create(start.AddDays(dayChunkSize * i)
                                        , start.AddDays(dayChunkSize * (i + 1)) > end 
                                         ? end : start.AddDays(dayChunkSize * (i + 1)));
            }

        }   

I do not have any objects for any of the implementations. They are practically identical.

Splitting a date-range - can it be improved somehow?, Looks pretty nice overall. Small bits: I would create a special type for the DateTime[] (as it can have only exactly 2 DateTime s), or reuse an  The chunks can be of any number of days/months. I put the code in an SO post, after my main method and I get some errors. Post - Split date range into date range chunks. Code -

Split date range into separate records, One way to do it is to use a table of numbers and CROSS APPLY . Sample data. DECLARE @T TABLE (RecordID int, date_from datetime2(0), date_to  Iterate over chunks of date range. Ask Question Something like "1996-2016" is split into smaller chunks for convenience \$\endgroup\$ – AlanSTACK Apr 30 '16 at

With respect to accepted answer you could use the short form of tuples:

private static IEnumerable<(DateTime, DateTime)> GetDateRange1(DateTime startDate, DateTime endDate, int daysChunkSize)
{
    DateTime markerDate;

    while ((markerDate = startDate.AddDays(daysChunkSize)) < endDate)
    {
        yield return (startDate, markerDate);
        startDate = markerDate;
    }

    yield return (startDate, endDate);
}

But I prefer to use named tuples:

private static IEnumerable<(DateTime StartDate, DateTime EndDate)> GetDateRange(DateTime startDate, DateTime endDate, int daysChunkSize)
{
    DateTime markerDate;

    while ((markerDate = startDate.AddDays(daysChunkSize)) < endDate)
    {
        yield return (StartDate: startDate, EndDate: markerDate);
        startDate = markerDate;
    }

    yield return (StartDate: startDate, EndDate: endDate);
}

https://social.msdn.microsoft.com/Forums/vstudio/e, I used the following two methods in a recent page to neatly break a date range into distinct segments as part of a analytics app I'm currently  Now, we need the data for the dates in the range, there are two pieces to that - the data that clearly falls in the date range: 6 items 7 as 8 ( 9 select * 10 from itemStatus 11 where status_time between to_date(:sdate,'dd/mm/yyyy') and to_date(:edate,'dd/mm/yyyy') 12 and itemid = :itemid

If you know how many chunks/intervals/periods/parts you want to split your time range into, I've found the following to be helpful

You can use the DateTime.Ticks property to define your intervals, and then create a series of DateTime objects based on your defined interval:

IEnumerable<DateTime> DivideTimeRangeIntoIntervals(DateTime startTS, DateTime endTS, int numberOfIntervals)
{
    long startTSInTicks = startTS.Ticks;
    long endTsInTicks = endTS.Ticks;
    long tickSpan = endTS.Ticks - startTS.Ticks;
    long tickInterval = tickSpan / numberOfIntervals;

    List<DateTime> listOfDates = new List<DateTime>();
    for (long i = startTSInTicks; i <= endTsInTicks; i += tickInterval)
    {
        listOfDates.Add(new DateTime(i));
    }
    return listOfDates;
}

You can convert that listOfDates into however you want to represent a timerange (a tuple, a dedicated date range object, etc). You can also modify this function to directly return it in the form you need it.

Splitting a date range in Python, from datetime import timedelta, date def daterange(date1, date2): for n in range(​int ((date2 - date1).days)+1): yield date1 + timedelta(n) start_dt  If the "from" day is 2017-02-02 at 17:00, and the "to" day is 2017-02-04 17:00 then there will be three records, one of which is date range from 2017-02-03 00:00:00 until 2017-02-03 23:59:59. For midnight, I guess it is based on the date time default.

Python Exercise: Get a list of dates between two dates, Developers and DBAs get help from Oracle experts on: How to split date range into months with start and end dates. A 0 (zero) indicates that the date is not in a date range, 1 means that the date is in one date range, 2 means two dates ranges and so on. Step 5 - Replace any number except 0 (zero) with corresponding date. The IF function has three arguments, the first one must be a logical expression. If the expression evaluates to TRUE then one thing happens (argument 2) and if FALSE another thing happens (argument 3).

Ask TOM "How to split date range into months with start and", Splitting Date Ranges. The power and beauty of F# pattern matching are often underestimated. To shine more light on them I decided to share  the rowid range splitting is nice because it lets you break the table up into NON-OVERLAPPING pieces -- least contention that way. Your current approach is maybe even using an index -- really bad (you end up reading every row via the index -- Many times the work you could perform just by scanning by rowid ranges).

Splitting Date Ranges, Whether to include the start date in the set of recurring dates or not. start. The start date of the period. $daterange = new DatePeriod($begin, $interval ,$end); The minium time span says that we cannot split any further a date range. midBetween function computes a date between two other dates. Inside split function, dateA and dateB stand for dates for which we'll compute a date in between. Nested dates function takes a mid date and splits given range into two sub-ranges.

Comments
  • Thanks for pointing out the bug, Love the clean look of your solution.
  • Very nice answer. Thank you! I would add as an additional - if you don't want "overlapping" modify the line "yield return Tuple.Create(start,chunkEnd);" to be "chunkEnd.AddDays(-1)". This will ensure that the start/end dates for each row do not overlap.
  • Does not work for me. I am actually using it inside a C# script embedded in an SSIS (ETL tool) package. I get two errors - Error The body of 'CodeHere.csproj.ScriptMain.SplitDateRange(System.DateTime, System.DateTime, int)' cannot be an iterator block because 'IEnumerable<Tuple<System.DateTime,System.DateTime>>' is not an iterator interface type C:\Users\............blah blah... $$$ AND $$$ The name 'Tuple' does not exist in the current context
  • BTW, I added your code after my main method. Also, I was using System.Tuple and i still get the tuple error. I am new to c#, so please bear with me.
  • ^^^^^^^^^^^^^^^^^^ This code works only for .NET 4.0 and above. How to make it work for 3.5 and below ?
  • I cringed while I was typing the while(true) ;). Thank you