Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Click here to view the latest version of this page.
PrevUpHomeNext

Time grids for months and weeks

A split_interval_set preserves all interval borders on insertion and intersection operations. So given a split_interval_set and an addition of an interval

x =  {[1,     3)}
x.add(     [2,     4)) 

then the intervals are split at their borders

x == {[1,2)[2,3)[3,4)}

Using this property we can intersect split_interval_maps in order to iterate over intervals accounting for all occurring changes of interval borders.

In this example we provide an intersection of two split_interval_sets representing a month and week time grid.

// The next line includes <boost/gregorian/date.hpp>
// and a few lines of adapter code.
#include <boost/icl/gregorian.hpp> 
#include <iostream>
#include <boost/icl/split_interval_set.hpp>

using namespace std;
using namespace boost::gregorian;
using namespace boost::icl;

typedef split_interval_set<boost::gregorian::date> date_grid;

// This function splits a gregorian::date interval 'scope' into a month grid:
// For every month contained in 'scope' that month is contained as interval
// in the resulting split_interval_set.
date_grid month_grid(const discrete_interval<date>& scope)
{
    split_interval_set<date> month_grid;

    date frame_months_1st = first(scope).end_of_month() + days(1) - months(1);
    month_iterator month_iter(frame_months_1st);

    for(; month_iter <= last(scope); ++month_iter)
        month_grid += discrete_interval<date>::right_open(*month_iter, *month_iter + months(1));

    month_grid &= scope; // cut off the surplus

    return month_grid;
}

// This function splits a gregorian::date interval 'scope' into a week grid:
// For every week contained in 'scope' that month is contained as interval
// in the resulting split_interval_set.
date_grid week_grid(const discrete_interval<date>& scope)
{
    split_interval_set<date> week_grid;

    date frame_weeks_1st = first(scope) + days(days_until_weekday(first(scope), greg_weekday(Monday))) - weeks(1);
    week_iterator week_iter(frame_weeks_1st);

    for(; week_iter <= last(scope); ++week_iter)
        week_grid.insert(discrete_interval<date>::right_open(*week_iter, *week_iter + weeks(1)));

    week_grid &= scope; // cut off the surplus

    return week_grid;
}

// For a period of two months, starting from today, the function
// computes a partitioning for months and weeks using intersection
// operator &= on split_interval_sets.
void month_and_time_grid()
{
    date someday = day_clock::local_day();
    date thenday = someday + months(2);

    discrete_interval<date> itv = discrete_interval<date>::right_open(someday, thenday);

    // Compute a month grid
    date_grid month_and_week_grid = month_grid(itv);
    // Intersection of the month and week grids:
    month_and_week_grid &= week_grid(itv);

    cout << "interval : " << first(itv) << " - " << last(itv) 
         << " month and week partitions:" << endl;
    cout << "---------------------------------------------------------------\n";

    for(date_grid::iterator it = month_and_week_grid.begin(); 
        it != month_and_week_grid.end(); it++)
    {
        if(first(*it).day() == 1)
            cout << "new month: ";
        else if(first(*it).day_of_week()==greg_weekday(Monday))
            cout << "new week : " ;
        else if(it == month_and_week_grid.begin())
            cout << "first day: " ;
        cout << first(*it) << " - " << last(*it) << endl;
    }
}


int main()
{
    cout << ">>Interval Container Library: Sample month_and_time_grid.cpp <<\n";
    cout << "---------------------------------------------------------------\n";
    month_and_time_grid();
    return 0;
}

// Program output:
/*
>>Interval Container Library: Sample month_and_time_grid.cpp <<
---------------------------------------------------------------
interval : 2008-Jun-22 - 2008-Aug-21 month and week partitions:
---------------------------------------------------------------
first day: 2008-Jun-22 - 2008-Jun-22
new week : 2008-Jun-23 - 2008-Jun-29
new week : 2008-Jun-30 - 2008-Jun-30
new month: 2008-Jul-01 - 2008-Jul-06
new week : 2008-Jul-07 - 2008-Jul-13
new week : 2008-Jul-14 - 2008-Jul-20
new week : 2008-Jul-21 - 2008-Jul-27
new week : 2008-Jul-28 - 2008-Jul-31
new month: 2008-Aug-01 - 2008-Aug-03
new week : 2008-Aug-04 - 2008-Aug-10
new week : 2008-Aug-11 - 2008-Aug-17
new week : 2008-Aug-18 - 2008-Aug-21
*/


PrevUpHomeNext