1 /*-----------------------------------------------------------------------------+
2 Interval Container Library
3 Author: Joachim Faulhaber
4 Copyright (c) 2007-2009: Joachim Faulhaber
5 Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
6 +------------------------------------------------------------------------------+
7    Distributed under the Boost Software License, Version 1.0.
8       (See accompanying file LICENCE.txt or copy at
9            http://www.boost.org/LICENSE_1_0.txt)
10 +-----------------------------------------------------------------------------*/
11 /** Example month_and_week_grid.cpp \file month_and_week_grid.cpp
12     \brief Creating and combining time grids.
13 
14     A split_interval_set preserves all interval borders on insertion
15     and intersection operations. So given a split_interval_set ...
16     \code
17     x =  {[1,     3)}
18     x.add(     [2,     4)) then
19     x == {[1,2)[2,3)[3,4)}
20     \endcode
21     ... using this property we can intersect splitting interval containers
22     in order to iterate over intervals accounting for all changes of
23     interval borders.
24 
25     In this example we provide an intersection of two split_interval_sets
26     representing a month and week time grid.
27 
28     \include month_and_week_grid_/month_and_week_grid.cpp
29 */
30 //[example_month_and_week_grid
31 // The next line includes <boost/gregorian/date.hpp>
32 // and a few lines of adapter code.
33 #include <boost/icl/gregorian.hpp>
34 #include <iostream>
35 #include <boost/icl/split_interval_set.hpp>
36 
37 using namespace std;
38 using namespace boost::gregorian;
39 using namespace boost::icl;
40 
41 typedef split_interval_set<boost::gregorian::date> date_grid;
42 
43 // This function splits a gregorian::date interval 'scope' into a month grid:
44 // For every month contained in 'scope' that month is contained as interval
45 // in the resulting split_interval_set.
month_grid(const discrete_interval<date> & scope)46 date_grid month_grid(const discrete_interval<date>& scope)
47 {
48     split_interval_set<date> month_grid;
49 
50     date frame_months_1st = first(scope).end_of_month() + days(1) - months(1);
51     month_iterator month_iter(frame_months_1st);
52 
53     for(; month_iter <= last(scope); ++month_iter)
54         month_grid += discrete_interval<date>::right_open(*month_iter, *month_iter + months(1));
55 
56     month_grid &= scope; // cut off the surplus
57 
58     return month_grid;
59 }
60 
61 // This function splits a gregorian::date interval 'scope' into a week grid:
62 // For every week contained in 'scope' that month is contained as interval
63 // in the resulting split_interval_set.
week_grid(const discrete_interval<date> & scope)64 date_grid week_grid(const discrete_interval<date>& scope)
65 {
66     split_interval_set<date> week_grid;
67 
68     date frame_weeks_1st = first(scope) + days(days_until_weekday(first(scope), greg_weekday(Monday))) - weeks(1);
69     week_iterator week_iter(frame_weeks_1st);
70 
71     for(; week_iter <= last(scope); ++week_iter)
72         week_grid.insert(discrete_interval<date>::right_open(*week_iter, *week_iter + weeks(1)));
73 
74     week_grid &= scope; // cut off the surplus
75 
76     return week_grid;
77 }
78 
79 // For a period of two months, starting from today, the function
80 // computes a partitioning for months and weeks using intersection
81 // operator &= on split_interval_sets.
month_and_time_grid()82 void month_and_time_grid()
83 {
84     date someday = day_clock::local_day();
85     date thenday = someday + months(2);
86 
87     discrete_interval<date> itv = discrete_interval<date>::right_open(someday, thenday);
88 
89     // Compute a month grid
90     date_grid month_and_week_grid = month_grid(itv);
91     // Intersection of the month and week grids:
92     month_and_week_grid &= week_grid(itv);
93 
94     cout << "interval : " << first(itv) << " - " << last(itv)
95          << " month and week partitions:" << endl;
96     cout << "---------------------------------------------------------------\n";
97 
98     for(date_grid::iterator it = month_and_week_grid.begin();
99         it != month_and_week_grid.end(); it++)
100     {
101         if(first(*it).day() == 1)
102             cout << "new month: ";
103         else if(first(*it).day_of_week()==greg_weekday(Monday))
104             cout << "new week : " ;
105         else if(it == month_and_week_grid.begin())
106             cout << "first day: " ;
107         cout << first(*it) << " - " << last(*it) << endl;
108     }
109 }
110 
111 
main()112 int main()
113 {
114     cout << ">>Interval Container Library: Sample month_and_time_grid.cpp <<\n";
115     cout << "---------------------------------------------------------------\n";
116     month_and_time_grid();
117     return 0;
118 }
119 
120 // Program output:
121 /*
122 >>Interval Container Library: Sample month_and_time_grid.cpp <<
123 ---------------------------------------------------------------
124 interval : 2008-Jun-22 - 2008-Aug-21 month and week partitions:
125 ---------------------------------------------------------------
126 first day: 2008-Jun-22 - 2008-Jun-22
127 new week : 2008-Jun-23 - 2008-Jun-29
128 new week : 2008-Jun-30 - 2008-Jun-30
129 new month: 2008-Jul-01 - 2008-Jul-06
130 new week : 2008-Jul-07 - 2008-Jul-13
131 new week : 2008-Jul-14 - 2008-Jul-20
132 new week : 2008-Jul-21 - 2008-Jul-27
133 new week : 2008-Jul-28 - 2008-Jul-31
134 new month: 2008-Aug-01 - 2008-Aug-03
135 new week : 2008-Aug-04 - 2008-Aug-10
136 new week : 2008-Aug-11 - 2008-Aug-17
137 new week : 2008-Aug-18 - 2008-Aug-21
138 */
139 //]
140 
141