| Home | Libraries | People | FAQ | More

## Gregorian

### Gregorian Date System

Introduction -- Usage Examples

#### Introduction

The gregorian date system provides a date programming system based the Gregorian Calendar. The first introduction of the Gregorian calendar was in 1582 to fix an error in the Julian Calendar. However, many local jurisdictions did not adopt this change until much later. Thus there is potential confusion with historical dates.

The implemented calendar is a "proleptic Gregorian calendar" which extends dates back prior to the Gregorian Calendar's first adoption in 1582. The current implementation supports dates in the range 1400-Jan-01 to 9999-Dec-31. Many references will represent dates prior to 1582 using the Julian Calendar, so caution is in order if accurate calculations are required on historic dates. See Calendrical Calculations by Reingold & Dershowitz for more details. Date information from Calendrical Calculations has been used to cross-test the correctness of the Gregorian calendar implementation.

All types for the gregorian system are found in namespace boost::gregorian. The library supports a convenience header boost/date_time/gregorian/gregorian_types.hpp that will include all the classes of the library with no input/output dependency. Another header boost/date_time/gregorian/gregorian.hpp will include the types and the input/output code.

The class boost::gregorian::date is the primary temporal type for users. If you are interested in learning about writing programs that do specialized date calculations such as finding the "first sunday in april" see the date generators and algorithms page.

#### Usage Examples

Example | Description
--- | ---
Days Alive Days Between New Years | Simple date arithmetic. Retrieve current day from clock.
Dates as strings | Simple parsing and formatting of dates from/to strings
Date Period Calculations | See if a date is in a set of date periods (eg: is it a holiday/weekend)
Print a month | Small utility program which prints out all the days in a month from command line. Need to know if 1999-Jan-1 was a Friday or a Saturday? This program shows how to do it.
Print Holidays | Uses date generators to convert abstract specification into concrete set of dates.

### Date

Introduction -- Header -- Construction -- Construct from String -- Construct from Clock -- Accessors -- Convert to String -- Operators -- Struct tm Functions

#### Introduction

The class boost::gregorian::date is the primary interface for date programming. In general, the date class is immutable once constructed although it does allow assignment from another date. Techniques for creating dates include reading the current date from the clock, using date iterators, and date algorithms or generators.

Internally boost::gregorian::date is stored as a 32 bit integer type. The class is specifically designed to NOT contain virtual functions. This design allows for efficient calculation and memory usage with large collections of dates.

The construction of a date validates all input so that it is not possible to construct an 'invalid' date. That is 2001-Feb-29 cannot be constructed as a date. Various exceptions derived from std::out_of_range are thrown to indicate which aspect of the date input is invalid. Note that the special value not-a-date-time can be used as 'invalid' or 'null' date if so desired.

#### Header

    #include "boost/date_time/gregorian/gregorian.hpp" //include all types plus i/o
    or
    #include "boost/date_time/gregorian/gregorian_types.hpp" //no i/o just types

#### Construction

Syntax | Description
--- | ---
Example
    date(greg_year, greg_month, greg_day)
| Construct from parts of date. Throws bad_year, bad_day_of_month, or bad_day_month (derivatives of std::out_of_range) if the year, month or day are out of range.
    date d(2002,Jan,10);
    date(date d)
| Copy constructor
    date d1(d);
    date(special_values sv)
| Constructor for infinities, not-a-date-time, max_date_time, and min_date_time
    date d1(neg_infin);
    date d2(pos_infin);
    date d3(not_a_date_time);
    date d4(max_date_time);
    date d5(min_date_time);
    date()
| Default constructor. Creates a date object initialized to not_a_date_time. NOTE: this constructor can be disabled by defining DATE_TIME_NO_DEFAULT_CONSTRUCTOR (see compiler_config.hpp)
    date d; // d => not_a_date_time

#### Construct from String

Syntax | Description
--- | ---
Example
    date from_string(std::string)
| From delimited date string where with order year-month-day eg: 2002-1-25
    std::string ds("2002/1/25");
    date d(from_string(ds));
    date from_undelimited_string(std::string)
| From iso type date string where with order year-month-day eg: 20020125
    std::string ds("20020125");
    date d(from_undelimited_string(ds));

#### Construct from Clock

Syntax | Description
--- | ---
Example
    day_clock::local_day()
| Get the local day based on the time zone settings of the computer.
    date d(day_clock::local_day());
    day_clock::universal_day()
| Get the UTC day.
    date d(day_clock::universal_day());

#### Accessors

Syntax | Description
--- | ---
Example
    greg_year year() const
| Get the year part of the date.
    date d(2002,Jan,10);
    d.year(); // --> 2002
    greg_month month() const
| Get the month part of the date.
    date d(2002,Jan,10);
    d.month(); // --> 1
    greg_day day() const
| Get the day part of the date.
    date d(2002,Jan,10);
    d.day(); // --> 10
    greg_ymd year_month_day() const
| Return a year_month_day struct. More efficient when all 3 parts of the date are needed.
    date d(2002,Jan,10);
    date::ymd_type ymd = d.year_month_day();
    // ymd.year  --> 2002,
    // ymd.month --> 1,
    // ymd.day   --> 10
    greg_day_of_week day_of_week() const
| Get the day of the week (Sunday, Monday, etc.)
    date d(2002,Jan,10);
    d.day(); // --> Thursday
    greg_day_of_year day_of_year() const
| Get the day of the year. Number from 1 to 366
    date d(2000,Jan,10);
    d.day_of_year(); // --> 10
    date end_of_month() const
| Returns a `date` object set to the last day of the calling objects current month.
    date d(2000,Jan,10);
    d.end_of_month(); // --> 2000-Jan-31
    bool is_infinity() const
| Returns true if date is either positive or negative infinity
    date d(pos_infin);
    d.is_infinity(); // --> true
    bool is_neg_infinity() const
| Returns true if date is negative infinity
    date d(neg_infin);
    d.is_neg_infinity(); // --> true
    bool is_pos_infinity() const
| Returns true if date is positive infinity
    date d(neg_infin);
    d.is_pos_infinity(); // --> true
    bool is_not_a_date() const
| Returns true if value is not a date
    date d(not_a_date_time);
    d.is_not_a_date(); // --> true
    bool is_special() const
| Returns true if date is any `special_value`
    date d(pos_infin);
    date d2(not_a_date_time);
    date d3(2005,Mar,1);
    d.is_special(); // --> true
    d2.is_special(); // --> true
    d3.is_special(); // --> false
    special_value as_special() const
| Returns represented `special_value` or `not_special` if the represented date is a normal date.
    long modjulian_day() const
| Returns the modified julian day for the date.
    long julian_day() const
| Returns the julian day for the date.
    int week_number() const
| Returns the ISO 8601 week number for the date.
    date end_of_month_day() const
| Returns the last day of the month for the date.
    date d(2000,Feb,1);
    //gets Feb 28 -- 2000 was leap year
    date eom = d.end_of_month_day();

#### Convert to String

Syntax | Description
--- | ---
Example
    std::string to_simple_string(date d)
| To `YYYY-mmm-DD` string where `mmm` is a 3 char month name.
    "2002-Jan-01"
    std::string to_iso_string(date d)
| To `YYYYMMDD` where all components are integers.
    "20020131"
    std::string to_iso_extended_string(date d)
| To `YYYY-MM-DD` where all components are integers.
    "2002-01-31"

#### Operators

Syntax | Description
--- | ---
Example
    operator<<
| Stream output operator
    date d(2002,Jan,1);
    std::cout << d << std::endl;
    operator>>
| Stream input operator. Note: As of version 1.33, streaming operations have been greatly improved. See Date Time IO System for details on exceptions and error conditions.
    date d(not_a_date_time);
    stringstream ss("2002-Jan-01");
    ss >> d;
    operator==, operator!=,
    operator>, operator<,
    operator>=, operator<=
| A full complement of comparison operators
    d1 == d2, etc
    date operator+(date_duration) const
| Return a date adding a day offset
    date d(2002,Jan,1);
    date_duration dd(1);
    date d2 = d + dd;
    date operator-(date_duration) const
| Return a date by substracting a day offset
    date d(2002,Jan,1);
    date_duration dd(1);
    date d2 = d - dd;
    date_duration operator-(date) const
| Return a date_duration by subtracting two dates
    date d1(2002,Jan,1);
    date d2(2002,Jan,2);
    date_duration dd = d2-d1;

#### Struct tm Functions

Functions for converting a `date` object to, and from, a `tm` struct are provided.

Syntax | Description
--- | ---
Example
    tm to_tm(date)
| A function for converting a `date` object to a `tm` struct. The fields: `tm_hour`, `tm_min`, and `tm_sec` are set to zero. The `tm_isdst` field is set to -1.
    date d(2005,Jan,1);
    tm d_tm = to_tm(d);
    /* tm_year => 105
       tm_mon  => 0
       tm_mday => 1
       tm_wday => 6 (Saturday)
       tm_yday => 0
       tm_hour => 0
       tm_min  => 0
       tm_sec  => 0
       tm_isddst => -1 */
    date date_from_tm(tm datetm)
| A function for converting a `tm` struct to a `date` object. The fields: `tm_wday` , `tm_yday` , `tm_hour`, `tm_min`, `tm_sec`, and `tm_isdst` are ignored.
    tm d_tm;
    d_tm.tm_year = 105;
    d_tm.tm_mon  = 0;
    d_tm.tm_mday = 1;
    date d = date_from_tm(d_tm);
    // d => 2005-Jan-01

### Date Duration (aka Days)

Introduction -- Header -- Construction -- Accessors -- Operators -- Additional Duration Types

#### Introduction

The class boost::gregorian::date_duration is a simple day count used for arithmetic with gregorian::date. A duration can be either positive or negative.

As of version 1_32 the date_duration class has been typedef'd as days in the boost::gregorian namespace. Throughout the examples you will find days used instead of date_duration.

#### Header

    #include "boost/date_time/gregorian/gregorian.hpp" //include all types plus i/o
    or
    #include "boost/date_time/gregorian/gregorian_types.hpp" //no i/o just types

#### Construction

Syntax | Description
--- | ---
Example
    date_duration(long)
| Create a duration count.
    date_duration dd(3); //3 days
    days(special_values sv)
| Constructor for infinities, not-a-date-time, max_date_time, and min_date_time
    days dd1(neg_infin);
    days dd2(pos_infin);
    days dd3(not_a_date_time);
    days dd4(max_date_time);
    days dd5(min_date_time);

#### Accessors

Syntax | Description
--- | ---
Example
    long days() const
| Get the day count.
    date_duration dd(3); dd.days() --> 3
    bool is_negative() const
| True if number of days is less than zero.
    date_duration dd(-1); dd.is_negative() --> true
    static date_duration unit()
| Return smallest possible unit of duration type.
    date_duration::unit() --> date_duration(1)
    bool is_special() const
| Returns true if days is any `special_value`
    days dd(pos_infin);
    days dd2(not_a_date_time);
    days dd3(25);
    dd.is_special(); // --> true
    dd2.is_special(); // --> true
    dd3.is_special(); // --> false

#### Operators

Syntax | Description
--- | ---
Example
    operator<<, operator>>
| Streaming operators. Note: As of version 1.33, streaming operations have been greatly improved. See Date Time IO System for more details (including exceptions and error conditions).
    date d(not_a_date_time);
    stringstream ss("2002-Jan-01");
    ss >> d;
    std::cout << d; // "2002-Jan-01"
    operator==, operator!=,
    operator>, operator<,
    operator>=, operator<=
| A full complement of comparison operators
    dd1 == dd2, etc
    date_duration operator+(date_duration) const
| Add date durations.
    date_duration dd1(3);
    date_duration dd2(5);
    date_duration dd3 = dd1 + dd2;
    date_duration operator-(date_duration) const
| Subtract durations.
    date_duration dd1(3);
    date_duration dd2(5);
    date_duration dd3 = dd1 - dd2;

#### Additional Duration Types

These additional types are logical representations of spans of days.

Syntax | Description
--- | ---
Example
    months(int num_of_months)
| A logical month representation. Depending on the usage, this `months` object may cover a span of 28 to 31 days. The objects also use a snap to end-of-month behavior when used in conjunction with a date that is the last day of a given month. WARNING: this behavior may lead to unexpected results. See: Reversibility of Operations Pitfall for complete details and alternatives.
    months single(1);
    date leap_year(2004,Jan,31);
    date norm_year(2005,Jan,31);
    leap_year + single; // => 2004-Feb-29
    norm_year + single; // => 2005-Feb-28
    date(2005,Jan,1) + single; // => 2005-Feb-01
    date(2005,Feb,1) + single; // => 2005-Mar-01
    date(2005,Feb,28) + single; // => 2005-Mar-31
    years(int num_of_years)
| A logical representation of a year. The `years` object has the same behavior as the `months` objects with regards to the end-of-the-month.
    years single(1);
    date(2003,Feb,28) + single;
    // results in => 2004-Feb-29
    date(2004,Feb,29) + single;
    // results in => 2005-Feb-28
    weeks(int num_of_weeks)
| A duration type representing a number of `n * 7` days.
    weeks single(1);
    date(2005,Jan,1) + single; // => 2005-Jan-08

##### Reversibility of Operations Pitfall

A natural expectation when adding a number of months to a date, and then subtracting the same number of months, is to end up exactly where you started. This is most often the result the `date_time` library provides but there is one significant exception: The snap-to-end-of-month behavior implemented by the months duration type. The months duration type may provide unexpected results when the starting day is the 28th, 29th, or 30th in a 31 day month. The month_iterator is not affected by this issue and is therefore included in the examples to illustrate a possible alternative.

When the starting date is in the middle of a month, adding or subtracting any number of months will result in a date that is the same day of month (e.g. if you start on the 15th, you will end on the 15th). When a date is the last day of the month, adding or subtracting any number of months will give a result that is also the last day of the month (e.g if you start on Jan 31st, you will land on: Feb 28th, Mar 31st, etc).

        // using months duration type
        date d(2005, Nov, 30); // last day of November
        d + months(1); // result is last day of December "2005-Dec-31"
        d - months(1); // result is last day of October "2005-Oct-31"

        // using month_iterator
        month_iterator itr(d); // last day of November
        ++itr; // result is last day of December "2005-Dec-31"
        --itr; // back to original starting point "2005-Nov-30"
        --itr; // last day of October "2005-Oct-31"

If the start date is the 28th, 29th, or 30th in a 31 day month, the result of adding or subtracting a month may result in the snap-to-end-of-month behavior kicking in unexpectedly. This would cause the final result to be different than the starting date.

        // using months duration type
        date d(2005, Nov, 29);
        d += months(1); // "2005-Dec-29"
        d += months(1); // "2006-Jan-29"
        d += months(1); // "2006-Feb-28" --> snap-to-end-of-month behavior kicks in
        d += months(1); // "2006-Mar-31" --> unexpected result
        d -= months(4); // "2005-Nov-30" --> unexpected result, not where we started

        // using month_iterator
        month_iterator itr(date(2005, Dec, 30));
        ++itr; // "2006-Jan-30" --> ok
        ++itr; // "2006-Feb-28" --> snap-to DOES NOT kick in
        ++itr; // "2006-Mar-30" --> ok
        --itr; // "2006-Feb-28" --> ok
        --itr; // "2006-Jan-30" --> ok
        --itr; // "2005-Dec-30" --> ok, back where we started

The additional duration types (`months`, `years`, and `weeks`) are provided as a convenience and can be easily removed to insure this pitfall never occurs. To remove these types simply undefine BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES.

### Date Period

Introduction -- Header -- Construction -- Mutators -- Accessors -- Convert to String -- Operators

#### Introduction

The class boost::gregorian::date_period provides direct representation for ranges between two dates. Periods provide the ability to simplify some types of calculations by simplifying the conditional logic of the program. For example, testing if a date is within an irregular schedule such as a weekend or holiday can be accomplished using collections of date periods. This is facilitated by several methods that allow evaluation if a date_period intersects with another date period, and to generate the period resulting from the intersection. The date period calculation example provides an example of this.

A period that is created with beginning and end points being equal, or with a duration of zero, is known as a zero length period. Zero length periods are considered invalid (it is perfectly legal to construct an invalid period). For these periods, the `last` point will always be one unit less that the `begin` point.

Date periods used in combination with infinity values have the ability to represent complex concepts such as 'until further notice'.

#### Header

    #include "boost/date_time/gregorian/gregorian.hpp" //include all types plus i/o
    or
    #include "boost/date_time/gregorian/gregorian_types.hpp" //no i/o just types

#### Construction

Syntax | Description
--- | ---
Example
    date_period(date, date)
| Create a period as [begin, end). If end is <= begin then the period will be invalid.
    date_period dp(date(2002,Jan,10),
                   date(2002,Jan,12));
    date_period(date, days)
| Create a period as [begin, begin+len) where end point would be begin+len. If len is <= zero then the period will be defined as invalid.
    date_period dp(date(2002,Jan,10),
                   days(2));
    date_period(date_period)
| Copy constructor
    date_period dp1(dp);

#### Mutators

Syntax | Description
--- | ---
Example
    date_period shift(days)
| Add duration to both begin and end.
    date_period dp(date(2005,Jan,1), days(3));
    dp.shift(days(3));
    // dp == 2005-Jan-04 to 2005-Jan-07
    date_period expand(days)
| Add duration to both begin and end.
    date_period dp(date(2005,Jan,2), days(2));
    dp.expand(days(1));
    // dp == 2005-Jan-01 to 2005-Jan-04

#### Accessors

Syntax | Description
--- | ---
Example
    date begin()
| Return first day of period.
    date_period dp(date(2002,Jan,1),
                   date(2002,Jan,10));
    dp.begin() --> 2002-Jan-01
    date last()
| Return last date in the period
    date_period dp(date(2002,Jan,1),
                   date(2002,Jan,10));
    dp.last() --> 2002-Jan-09
    date end()
| Return one past the last in period
    date_period dp(date(2002,Jan,1),
                   date(2002,Jan,10));
    dp.end() --> 2002-Jan-10
    days length()
| Return the length of the date_period
    date_period dp(date(2002,Jan,1),
                   days(2));
    dp.length() --> 2
    bool is_null()
| True if period is not well formed. eg: end less than or equal to begin.
    date_period dp(date(2002,Jan,10),
                   date(2002,Jan,1));
    dp.begin() --> true
    bool contains(date)
| True if date is within the period. Zero length periods cannot contain any points
    date d(2002,Jan,1);
    date_period dp(d, date(2002,Jan,10));
    dp.contains(date(2002,Jan,2));// true
    date_period dp2(d, d);
    dp.contains(date(2002,Jan,1));// false
    bool contains(date_period)
| True if date period is within the period
    date_period dp1(date(2002,Jan,1),
                    date(2002,Jan,10));
    date_period dp2(date(2002,Jan,2),
                    date(2002,Jan,3));
    dp1.contains(dp2) --> true
    dp2.contains(dp1) --> false
    bool intersects(date_period)
| True if periods overlap
    date_period dp1(date(2002,Jan,1),
                   date(2002,Jan,10));
    date_period dp2(date(2002,Jan,2),
                   date(2002,Jan,3));
    dp2.intersects(dp1) --> true
    date_period intersection(date_period)
| Calculate the intersection of 2 periods. Null if no intersection.
    date_period dp1(date(2002,Jan,1),
                    date(2002,Jan,10));
    date_period dp2(date(2002,Jan,2),
                    date(2002,Jan,3));
    dp2.intersection(dp1) --> dp2
    date_period is_adjacent(date_period)
| Check if two periods are adjacent, but not overlapping.
    date_period dp1(date(2002,Jan,1),
                    date(2002,Jan,3));
    date_period dp2(date(2002,Jan,3),
                    date(2002,Jan,10));
    dp2.is_adjacent(dp1) --> true
    date_period is_after(date)
| Determine the period is after a given date.
    date_period dp1(date(2002,Jan,10),
                    date(2002,Jan,30));
    date d(2002,Jan,3);
    dp1.is_after(d) --> true
    date_period is_before(date)
| Determine the period is before a given date.
    date_period dp1(date(2002,Jan,1),
                    date(2002,Jan,3));
    date d(2002,Jan,10);
    dp1.is_before(d) --> true
    date_period merge(date_period)
| Returns union of two periods. Null if no intersection.
    date_period dp1(date(2002,Jan,1),
                    date(2002,Jan,10));
    date_period dp2(date(2002,Jan,9),
                    date(2002,Jan,31));
    dp2.merge(dp1)
    // 2002-Jan-01/2002-Jan-31
    date_period span(date_period)
| Combines two periods and any gap between them such that begin = min(p1.begin, p2.begin) and end = max(p1.end , p2.end)
    date_period dp1(date(2002,Jan,1),
                    date(2002,Jan,5));
    date_period dp2(date(2002,Jan,9),
                    date(2002,Jan,31));
    dp2.span(dp1); // 2002-Jan-01/2002-Jan-31
    date_period shift(days)
| Add duration to both begin and end.
    date_period dp1(date(2002,Jan,1),
                    date(2002,Jan,10));
    dp1.shift(days(1));
    // 2002-Jan-02/2002-Jan-11
    date_period expand(days)
| Subtract duration from begin and add duration to end.
    date_period dp1(date(2002,Jan,4),
                    date(2002,Jan,10));
    dp1.expand(days(2));
    // 2002-Jan-02/2002-Jan-12

#### Convert to String

Syntax | Description
--- | ---
Example
    std::string to_simple_string(date_period dp)
| To `[YYYY-mmm-DD/YYYY-mmm-DD]` string where `mmm` is 3 char month name.
    [2002-Jan-01/2002-Jan-31]

#### Operators

Syntax | Description
--- | ---
Example
    operator<<
| ostream operator for date_period. Uses facet to format time points. Typical output: [2002-Jan-01/2002-Jan-31].
    std::cout << dp << std::endl;
    operator>>
| istream operator for date_period. Uses facet to parse time points.
    "[2002-Jan-01/2002-Jan-31]"
    operator==, operator!=,
    operator>, operator<
| A full complement of comparison operators
    dp1 == dp2, etc
    operator<
| True if dp1.end() less than dp2.begin()
    dp1 < dp2, etc
    operator>
| True if dp1.begin() greater than dp2.end()
    dp1 > dp2, etc

### Date Iterators

Introduction -- Header -- Overview

#### Introduction

Date iterators provide a standard mechanism for iteration through dates. Date iterators are a model of Bidirectional Iterator and can be used to populate collections with dates and other date generation tasks. For example, the print month example iterates through all the days in a month and prints them.

All of the iterators here derive from boost::gregorian::date_iterator.

#### Header

    #include "boost/date_time/gregorian/gregorian.hpp" //include all types plus i/o
    or
    #include "boost/date_time/gregorian/gregorian_types.hpp" //no i/o just types

#### Overview

Syntax | Description
--- | ---
Example
    date_iterator
| Common (abstract) base class for all day level iterators.
    day_iterator(date start_date, int day_count=1)
| Iterate `day_count` days at a time. This iterator does not provide postfix increment/decrement operators. Only prefix operators are provided.
    day_iterator day_itr(date(2005,Jan,1));
    ++d_itr; // 2005-Jan-02
    day_iterator 2day_itr(date(2005,Feb,1),2);
    ++2d_itr; // 2005-Feb-03
    week_iterator(...)
      Parameters:
        date start_date
        int week_offset (defaults to 1)
| Iterate `week_offset` weeks at a time. This iterator does not provide postfix increment/decrement operators. Only prefix operators are provided.
    week_iterator wk_itr(date(2005,Jan,1));
    ++wk_itr; // 2005-Jan-08
    week_iterator 2wk_itr(date(2005,Jan,1),2);
    ++2wk_itr; // 2005-Feb-15
    month_iterator(...)
      Parameters:
        date start_date
        int month_offset (defaults to 1)
| Iterate `month_offset` months. There are special rules for handling the end of the month. These are: if start date is last day of the month, always adjust to last day of the month. If date is beyond the end of the month (e.g. Jan 31 + 1 month) adjust back to end of month (for more details and examples of this, see Reversibility of Operations Pitfall. NOTE: the `month_iterator` is not effected by this pitfall.) This iterator does not provide postfix increment/decrement operators. Only prefix operators are provided.
    month_iterator m_itr(date(2005,Jan,1));
    ++m_itr; // 2005-Feb-01
    month_iterator 2m_itr(date(2005,Feb,1),2);
    ++2m_itr; // 2005-Apr-01
    year_iterator(...)
      Parameters:
        date start_date
        int year_offset (defaults to 1)
| Iterate year_offset years. The year_iterator will always land on the day of the date parameter except when date is Feb 28 in a non-leap year. In this case the iterator will return Feb 29 for leap years (eg: 2003-Feb-28, 2004-Feb-29, 2005-Feb-28). This iterator does not provide postfix increment/decrement operators. Only prefix operators are provided.
    year_iterator y_itr(date(2005,Jan,1));
    ++y_itr; // 2006-Jan-01
    year_iterator 2y_itr(date(2005,Feb,1),2);
    ++2y_itr; // 2007-Feb-01

### Date Generators/Algorithms

Introduction -- Header -- Class Overview -- Function Overview

#### Introduction

Date algorithms or generators are tools for generating other dates or schedules of dates. A generator function starts with some part of a date such as a month and day and is supplied another part to then generate a concrete date. This allows the programmer to represent concepts such as "The first Sunday in February" and then create a concrete set of dates when provided with one or more years. Note: As of boost version 1_31_0, date generator names have been changed. Old names are still available but are no longer documented and may someday be deprecated

Also provided are stand-alone functions for generating a date, or calculation a duration of days. These functions take a date object and a weekday object as parameters.

All date generator classes and functions are in the boost::gregorian namespace.

The print holidays example shows a detailed usage example.

#### Header

    #include "boost/date_time/gregorian/gregorian.hpp"

#### Overview

Class and get_date Parameter | Description
--- | ---
Example
    year_based_generator
    date get_date(greg_year year)
| A unifying (abstract) date_generator base type for: `partial_date`, `nth_day_of_the_week_in_month`, `first_day_of_the_week_in_month`, and `last_day_of_the_week_in_month`.
The print holidays example shows a detailed usage example.
    last_day_of_the_week_in_month(greg_weekday,
                                  greg_month)
    date get_date(greg_year year)
| Calculate something like last Monday of January
    last_day_of_the_week_in_month lwdm(Monday,Jan);
    date d = lwdm.get_date(2002);
    //2002-Jan-28
    first_day_of_the_week_in_month(greg_weekday,
                                   greg_month)
    date get_date(greg_year year)
| Calculate something like first Monday of January
    first_day_of_the_week_in_month fdm(Monday,Jan);
    date d = fdm.get_date(2002);
    //2002-Jan-07
    nth_day_of_the_week_in_month(week_num,
                                 greg_weekday,
                                 greg_month)
    date get_date(greg_year year)
| `week_num` is a public enum member of `nth_day_of_the_week_in_month`. Calculate something like first Monday of January, second Tuesday of March, Third Sunday of December, etc. (first through fifth are provided, fifth is the equivalent of last)
    typedef nth_day_of_the_week_in_month nth_dow;
    nth_dow ndm(nth_dow::third, Monday,Jan);
    date d = ndm.get_date(2002);
    //2002-Jan-21
    partial_date(greg_day, greg_month)
    date get_date(greg_year year)
| Generates a date by applying the year to the given month and day.
    partial_date pd(1,Jan);
    date d = pd.get_date(2002);
    //2002-Jan-01
    first_day_of_the_week_after(greg_weekday)
    date get_date(date d)
| Calculate something like First Sunday after Jan 1,2002
    first_day_of_the_week_after fdaf(Monday);
    date d = fdaf.get_date(date(2002,Jan,1));
    //2002-Jan-07
    first_day_of_the_week_before(greg_weekday)
    date get_date(date d)
| Calculate something like First Monday before Feb 1,2002
    first_day_of_the_week_before fdbf(Monday);
    date d = fdbf.get_date(date(2002,Feb,1));
    //2002-Jan-28

#### Function Overview

Function Prototype | Description
--- | ---
Example
    days days_until_weekday date, greg_weekday)
| Calculates the number of days from given date until given weekday.
    date d(2004,Jun,1); // Tuesday
    greg_weekday gw(Friday);
    days_until_weekday(d, gw); // 3 days
    days days_before_weekday(date, greg_weekday)
| Calculates the number of day from given date to previous given weekday.
    date d(2004,Jun,1); // Tuesday
    greg_weekday gw(Friday);
    days_before_weekday(d, gw); // 4 days
    date next_weekday(date, greg_weekday)
| Generates a date object representing the date of the following weekday from the given date.
    date d(2004,Jun,1); // Tuesday
    greg_weekday gw(Friday);
    next_weekday(d, gw); // 2004-Jun-4
    date previous_weekday(date, greg_weekday)
| Generates a date object representing the date of the previous weekday from the given date.
    date d(2004,Jun,1); // Tuesday
    greg_weekday gw(Friday);
    previous_weekday(d, gw); // 2004-May-28

### Gregorian Calendar

Introduction -- Header -- Functions

#### Introduction

The class boost::gregorian::gregorian_calendar implements the functions necessary to create the gregorian date system. It converts to the year-month-day form of a date to a day number representation and back.

For most purposes this class is simply accessed by gregorian::date and is not used directly by the user. However, there are useful functions that might be of use such as the end_of_month_day function.

The print month example demonstrates this.

#### Header

    #include "boost/date_time/gregorian/gregorian.hpp" //include all types plus i/o
    or
    #include "boost/date_time/gregorian/gregorian_types.hpp" //no i/o just types

#### Functions

Syntax | Description
--- | ---
Example
    static short day_of_week(ymd_type)
| Return the day of the week (0==Sunday, 1==Monday, etc)
See also gregorian::date day_of_week
    static date_int_type day_number(ymd_type)
| Convert a ymd_type into a day number. The day number is an absolute number of days since the epoch start.
    static short end_of_month_day(year_type,
                                  month_type)
| Given a year and month determine the last day of the month.
    static ymd_type from_day_number(date_int_type)
| Convert a day number to a ymd struct.
    static bool is_leap_year(year_type)
| Returns true if specified year is a leap year.
    gregorian_calendar::is_leap_year(2000)
    //--> true