N2058=06-0128 Proposed Text for Proposal to add Date-Time to the Standard Library 1.0

Jeff Garland (jeff-at-crystalclearsoftware.com)


Table of Contents

Detailed Table of Contents
Introduction
Proposed Text
Acknowledgments
References

Detailed Table of Contents

Introduction

Note: This draft is only partially complete and will need to be updated. However, it does show the scope and extent of the proposal.

This paper will focus on the details of the proposal to add a date-time library to the c++ standard. Please see N1900=05-0160 Proposal to Add Date-Time to the C++ Standard Library for an overview of the motivations, design, and major design decisions.

The author fully expects the Library Working Group to have many suggestions and refinements since this is a lengthy proposal and this is the authors first experience writing a standards proposal.

Proposed Text

Text in notes is meant as explanatory information about the proposal. It is not to be added to the TR.

Note

This is an example of a note that is NOT part of the TR text.

All dates and times in this proposal are supplied in ISO extended form unless otherwise specified. Specifically year-month-day hour:minute:second.fractional_seconds. So the 15th day of September 2006 is specified as 2006-09-15.

Chapter (tbs) - Datetime Library

This clause contains components that C++ programs may use to manipulate dates, times, and timezones.

Unless otherwise specified, all components described in this clause are declared in namespace std::tr2::datetime.

Requirements

Requirements on Programs

Requirements on Implemenations

FW.1 Normative References

ISO 8601:2004 Data elements and interchange formats -- Information interchange -- Representation of dates and times

FW.2 Definitions

Time Point: An instant in the time continuum (dimensionless).

Time Duration: A length of time unattached to a any time point. Time durations have an assigned maxiumum resolution (eg: 1 second).

Time Period: A length of time between two time points

Epoch: The start of a given time scale. For time_t the epoch is 1970-01-01 00:00:00. In this text the epoch will normally be called the 'minimum date' or 'minimum time'.

Maximum Date/Time: The maxiumum representable time in a time system implementation. For time_t the maximum representable time is January 19, 2038 03:14:08.

Valid Date/Time: A date or time that can be represented within the range of a time system with a defined epoch, resolution, and maximum date/time.

Header <datetime> Synopsis

The header <datetime> defines a basic date, basic duration, and basic period class templates.

The header <datetime> defines a basic gregorian calendar templates that implements core calendric calcuations.

The header <datetime> defines a series of typedefs to provide date and other time types.

The header <datetime> defines a timezone classes to provide for local time adjustment calculations input and output.

The header <datetime> defines a input output functions and facets for the date time types.

The header <datetime> defines a set of exception classes used to signal errors in construction of incorrect dates and times.

namespace std 
{
  namespace tr2 
  {
    namespace datetime 
    {

      enum special_values {negative_infinity, positive_infinity, not_a_date_time,
                           max_date_time, min_date_time, not_special };

      enum week_of_month {1st_week = 1, 2nd_week, 3rd_week, 4th_week, 
                          5th_week, last_week_of_month};

      //corresponds to iso 8601 day of the week numbering
      enum day_of_the_week {sunday=1, monday, tuesday, wednesday, thursday, friday, saturday }

      struct year_month_day;

      //basic class for time durations
      template<class duration_rep_traits> class basic_duration;

      //common calendar functions.
      template<typename ymd_type_, typename date_int_type_>
      class basic_calendar;

      //classes and functions for date
      template<class date_impl> 
      class basic_date;


      //Exception classes for construction of dates
      class bad_date_error;   // public std::runtime_error
      class bad_day_of_month; // public bad_date_error
      class bad_day_of_year;  // public bad_date_error
      class bad_week_of_year  // public bad_date_error
      class bad_year;         // public bad_date_error
      class bad_month;        // public bad_date_error
      class bad_weekday;      // public bad_date_error
      class bad_date_conversion; //public bad_date_error

      //high resolution durations
      template<class time_impl>
      class basic_time_duration;

      //Classes and functions for time representation
      template <class time_impl>
      class basic_date_time;

      template <class CharT, class TraitsT>
      std::basic_ostream<CharT, TraitsT>&
      operator<<(std::basic_ostream<CharT, TraitsT>& os, const basic_date_time&);

      template <class CharT, class Traits>
      std::basic_istream<CharT, Traits>&
      operator>>(std::basic_istream<CharT, Traits>& is, basic_date_time&);

      //Classes and functions for time periods
      template<class point_rep, class duration_rep>
      class basic_time_period;

      template<typename time_type, typename CharT = char>
      class time_zone_base;

      template<class CharT = char>
      class time_zone_names_base;

      //Timezone type used for user customization (TODO????)
      class time_zone : public time_zone_base<date_time>;

      //Exception class for conversions of local time values
      class invalid_time_label;  // public std::logic_error

      template<typename time_type, typename charT=char>
      class posix_time_zone : public time_zone<time_type, charT>;

      template<class date_type>
      class day_clock;

      template<class time_type>
      class second_clock;

      template<class time_type>
      class microsecond_clock;

      //...indicates implementation defined
      typedef basic_date<implementation-defined>                  date;
      typedef basic_duration<implementation-defined>              days;
      typedef basic_duration<implementation-defined>              weeks;
      typedef basic_duration<implementation-defined>              months;
      typedef basic_duration<implementation-defined>              years;
      typedef basic_time_period<date, days>    date_period;

      typedef basic_date_time<implementation-defined>             date_time;
      typedef basic_time_duration<implementation-defined>         hours;
      typedef basic_time_duration<implementation-defined>         minutes;
      typedef basic_time_duration<implementation-defined>         seconds;
      typedef basic_time_duration<implementation-defined>         milliseconds;
      typedef basic_time_duration<implementation-defined>         microseconds;
      typedef basic_time_duration<implementation-defined>         nanoseconds;

  
      //io stuff
      template <class CharT, class TraitsT>
      std::basic_ostream<CharT, TraitsT>&
      operator<<(std::basic_ostream<CharT, TraitsT>& os, basic_duration&);

      template <class CharT, class Traits>
      std::basic_istream<CharT, Traits>&
      operator>>(std::basic_istream<CharT, Traits>& is,  basic_duration&);

      template <class CharT, class TraitsT>
      std::basic_ostream<CharT, TraitsT>&
      operator<<(std::basic_ostream<CharT, TraitsT>& os, const basic_date&);

      template <class CharT, class Traits>
      std::basic_istream<CharT, Traits>&
      operator>>(std::basic_istream<CharT, Traits>& is, basic_date&);

      template <class CharT, class TraitsT>
      std::basic_ostream<CharT, TraitsT>&
      operator<<(std::basic_ostream<CharT, TraitsT>& os, const basic_time_duration&);

      template <class CharT, class Traits>
      std::basic_istream<CharT, Traits>&
      operator>>(std::basic_istream<CharT, Traits>& is, basic_time_duration&);


      template <class CharT, class TraitsT>
      std::basic_ostream<CharT, TraitsT>&
      operator<<(std::basic_ostream<CharT, TraitsT>& os, const basic_time_period&);

      template <class CharT, class Traits>
      std::basic_istream<CharT, Traits>&
      operator>>(std::basic_istream<CharT, Traits>& is, basic_time_period&);

      template <class CharT, class TraitsT>
      std::basic_ostream<CharT, TraitsT>&
      operator<<(std::basic_ostream<CharT, TraitsT>& os, posix_time_zone&);

      template <class CharT, class Traits>
      std::basic_istream<CharT, Traits>&
      operator>>(std::basic_istream<CharT, Traits>& is,  posix_time_zone&);

      template <class date_type,
                class CharT, 
                class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
      class date_facet; // : public std::locale::facet

      template <class date_type,
                class CharT, 
                class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
      class date_input_facet; // public std::locale::facet {


      template <class time_type,
                class CharT, 
                class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
      class time_facet;

      template <class time_type,
                class CharT, 
                class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
      class time_input_facet;


    }  // namespace datetime 
  }  //namespace tr2
}  //namespace std

Core Classes

Template Class basic_calendar

This is a parameterized implementation of a proleptic Gregorian, iso, and julian calendar functions. These functions allow for the calculation of various date-related values including the conversion of values such as the 'year-month-day' into an integer value that can be used to represent a date.

Note

All the methods of this class are static functions, so the intent is to never create instances of this class.

Note

This class is parameterized to allow for alternate date time implemenations to utilize these functions as part of an implementation.

template<typename ymd_type_, typename date_int_type_>
class basic_calendar {
public:
  typdef  typename ymd_type_::weekday_type weekday_type; //TODO change to traits?
  typedef ymd_type_                        ymd_type;
  typedef typename ymd_type::month_type    month_type;
  typedef typename ymd_type::day_type      day_type;
  typedef typename ymd_type::year_type     year_type;
  typedef date_int_type_                   date_int_type;


  //iso/gregorian related functions
  static unsigned short day_of_week    (const ymd_type& ymd);
  static int            week_number    (const ymd_type& ymd);
  static bool           is_leap_year(year_type y);
  static unsigned short last_day_of_month(year_type y, month_type m);

  //TODO document or remove
  static int            days_after_weekday(date_int_type day_number, weekday_type);
  static int            days_before_weekday(date_int_type day_number, weekday_type);
  

  static date_int_type  day_number     (const ymd_type& ymd);
  static ymd_type       from_day_number(date_int_type);

  //julian calendar functions
  static date_int_type  julian_day_number(const ymd_type& ymd);
  static long           modjulian_day_number(const ymd_type& ymd);
  static ymd_type       from_julian_day_number(long julian_day_number);
  static ymd_type       from_modjulian_day_number(long modjulian_day);

  //calendar traits functions
  static ymd_type       min_ymd();
  static ymd_type       max_ymd();
  static date_int_type  min_count();
  static date_int_type  max_count();
  static unsigned short days_in_week();
};

Remarks:

Returns:

basic_calendar ymd template parameter

The ymd_type parameter is a simple structure that has the following requirements.

ymd_type requirements

ExpressionNotes
ymd_type::year_typeA typedef that provides the integer type used for year field of the ymd_type.
ymd_type::month_typeA typedef that provides the integer type used for month field of the ymd_type.
ymd_type::day_typeA typedef that provides the integer type used for month field of the ymd_type.
ymd_type.yearAn integer type that represents the current year. TODO--ragne
ymd_type.monthAn integer type the represents a month. Values will be assigned with January == 1 thru December ==12
ymd_type.dayAn integer type that represents a day within a month. Values will range from 1 to 31.
ymd_type.day_of_yearAn integer type that represents the day of the year. Values will range from 1 to 366

basic_calendar typedefs

basic_calendar calculation functions

static unsigned short day_of_week    (const ymd_type& ymd);

Returns: Day of the week from the specified year-month-day where Sunday is 0, Monday is 1, thru Saturday == 6.

static int week_number    (const ymd_type& ymd);

Remarks: Calculate the iso week number for the year-month-day as defined in ISO 8601:2004 Data elements and interchange formats -- Information interchange -- Representation of dates and times

Returns: An integer value from 0 to 53 corresponding to the week number for the year,month,day.

static bool           is_leap_year(year_type y);

Returns: True if the specified year is a leap year, false otherwise.

static unsigned short last_day_of_month(year_type y, month_type m);

Remarks: Calculate the last day of the month taking into account leap years. This is a constant for all months except February which returns 28 for a non leap year and 29 for a leap year. For example, the value for January is always 31.

Returns: An integer value between 1 and 31 that represents the last day of the month.

static date_int_type  day_number     (const ymd_type& ymd);

Remarks: Calculate an integer day count based on the proleptic Gregorian/ISO calendar that corresponds to the date. The number must monotinically increase starting from min_count to max_count with one value for each day.

Note

This function provides the infrastructure to implement the days_between dates externally from the calendar class.

Returns: An integer cooresponding to the specified year-month-day. The return value from this function will map to the same passed year-month-day as calculated by from_day_number.

static ymd_type       from_day_number(date_int_type day_number);

Remarks: Converts an integer back to a year-month-day.

Returns: The year-month-day value cooresponding to the specified day_number.

basic_calendar date_int_type template parameter

The date_int_type provides an integer type that is used in all calculations of the date.

Note

The intent of the date_int_type is to allow implementations to use different integer sizes within the implementation. For example, some implementations my use 64 bit integer in representing a combined date time and will find it helpful to directly calculate into this specific integer type even though a 32 bit integer would be sufficient to represent the valid date range. In addition, this enables low level user access to these functions using user defined integer types.

basic_calendar julian calendar functions

The following functions provide conversions to and from julian an modified julian day numbers.

Note

A freely available resource with descriptions of the algorithms to be implemented here can be found at http://www.tondering.dk/claus/calendar.html

static date_int_type  julian_day_number(const ymd_type& ymd);

Remarks: Calculate the julian day number (TODO reference and outside).

Returns: An integer representing the julian day number for the specified year-month-day.

static long modjulian_day_number(const ymd_type& ymd);

Remarks: Calculate the modified julian day number (TODO reference and outside).

Returns: Day of the week from the specified year-month-day where Sunday=0, Monday1, thru Saturday=6.

static ymd_type       from_julian_day_number(long julian_day);

Remarks:

Returns: A year-month-day structure with day, month, year fields set.

static ymd_type       from_modjulian_day_number(long mod_julian_day);

Remarks: A year-month-day structure from the modified julian day.

Returns: Day of the week from the specified year-month-day where Sunday = 0, Monday = 1, thru Saturday == 6.

basic_calendar traits functions

The following functions provide basic information about the minimum and maximum dates handled by the implementation.

static ymd_type       min_ymd();

Remarks: Get the year-month-day of the minimum date provided by the calendar implementation.

Returns: An instance of the ymd_type with the year, month, and day fields set.

Note

For this proposal this will nominally be [1400-01-01

static ymd_type       max_ymd();

Remarks: Get the year-month-day of the maximum date provided by the calendar implementation.

Returns: An instance of the ymd_type with the year, month, and day fields set.

Note

For this proposal this will nominally be [10000-01-01

static date_int_type  min_count();

Returns: Returns the minimum day number value used by the calendar.

Note

This will typically be 0, but implementations may use 0 for special values internally.

static date_int_type  max_count();

Returns: Returns the maximum day number value used by the calendar.

static unsigned short days_in_week();

Remarks: Enables generic programming for non-iso calendar systems.

Returns: Returns 7.

Template Class basic_date

The basic_date template provide the core interface for the date typedef that will be the primary interface for date programming. Internally, the basic_date will hold an implementation defined integer type. This allows the basic_date interface to provide with with different calendar implementations that provide different valid date ranges the typedef date.

template<class date_impl> 
class basic_date {
 public:

  //typedefs
  typedef typename date_impl::calendar_type calendar_type;

  typedef typename date_impl::year_type  year_type;
  typedef typename date_impl::month_type month_type;
  typedef typename date_impl::day_type   day_type;
  typedef typename date_impl::ymd_type   ymd_type;

  typedef typename date_impl::day_of_week_type    day_of_week_type;  
  typedef typename date_impl::day_of_year_type    day_of_year_type;  
  typedef typename date_impl::week_of_year_type   week_of_year_type;

  typedef typename date_impl::weekday_type        weekday_type; 
  typedef typename date_impl::week_of_month_type  week_of_month_type; 

  typedef typename date_impl::special_values_type special_values_type;

  typedef typename date_impl::date_duration_type  date_duration_type;

  typedef typename date_impl::date_int_type date_int_type;


  //constructors
  basic_date(year_type y, month_type m, day_type d);
  basic_date(const ymd_type& ymd);
  basic_date(year_type y, day_of_year_type doy);
  basic_date(const basic_date& rhs);
  //constructs something like: Sunday in Week 50 of year 2004
  basic_date(year_type y, week_of_year_type week_number, weekday_type wd);
  //constructs something like: 3rd Monday in Feb of 2004
  basic_date(year_type y, month_type m, week_of_month_type week_number, weekday_type wd);
  basic_date(std::time_t t);
  basic_date(const std::tm& datetm);
  //construct positive/negative infinity max or min date
  basic_date(special_values_type sv);
  //default constuctor == not-a-date-time
  basic_date(); 

  //Basic accessors
  year_type        year()           const;
  month_type       month()          const;
  day_type         day()            const;
  day_of_week_type day_of_week()    const; //eg: Sun, Mon, ...


  //additional accessors
  day_of_year_type  day_of_year()  const; //1..365 or 1..366 (for leap year)
  week_of_year_type week_number()  const; //ISO 8601 week number 1..53
  date_int_type     day_number()   const; //Return the day number since start of the epoch
  basic_date        end_of_month() const; //Return the last day of the current month

  //special value accessors
  bool is_special()                 const;
  special_values_type as_special()  const;

  //conversion accessors
  time_t        to_time_t()      const;   
  ymd_type      year_month_day() const; //Get ymd structure

  // Conversion to julian calendar
  date_int_type julian_day()     const;
  long          modjulian_day()  const; 

  //calculation accessors 
  date_duration_type days_until  (weekday_type) const;
  date_duration_type days_before (weekday_type) const;
  basic_date         next        (weekday_type) const;
  basic_date         previous    (weekday_type) const;
      
  //comparison operators
  bool operator<  (const basic_date&) const;
  bool operator<= (const basic_date&) const;
  bool operator>  (const basic_date&) const;
  bool operator>= (const basic_date&) const;
  bool operator== (const basic_date&) const;
  bool operator!= (const basic_date&) const;

  //arithmetic operators
  date_duration_type operator-  (const basic_date&)     const;
  basic_date         operator-  (const date_duration_type&) const;
  basic_date         operator-= (const date_duration_type&);
  basic_date         operator+  (const date_duration_type&) const;
  basic_date         operator+= (const date_duration_type&);

};


template <class CharT, class TraitsT>
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const date&);

template <class CharT, class Traits>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, date&);


//Exception classes for construction of dates
class bad_day_of_month : public std::out_of_range
{};
class bad_day_of_year : public std::out_of_range
{};
class bad_week_of_year : public std::out_of_range
{};
class bad_year : public std::out_of_range
{};
class bad_month : public std::out_of_range
{};
class bad_weekday : public std::out_of_range
{};
  //Exception class for conversions of local time values
class invalid_time_label : public std::logic_error
{};

Template Class basic_date - typedefs

Template Class basic_date - constructors

The date type provides may types of constructors for creating a date type.

basic_date(); 

Remarks: Construct date with the special value not-a-date-time.

Throws: none

basic_date(const basic_date& rhs);

Remarks: Copy constructor.

Throws: none

basic_date(year_type year, month_type month, day_type day);

Remarks: Construct a month from integer year, month, day values.

Throws: bad_year if year > calendar::max_ymd().year

Throws: bad_month if month < 0 or month > 12

Throws: bad_day if day is greater than calendar::last_day_of_month(year,month)

Note

This last case requires the exception be thrown in the case of a non leap-year and a Feb 29th specification.

basic_date(const ymd_type& ymd);

Remarks: Construct a month from integer year, month, day values in the ymd struct.

Throws: bad_year if ymd.year > calendar::max_ymd().year

Throws: bad_month if ymd.month < 0 or month > 12

Throws: bad_day if ymd.day is greater than calendar::last_day_of_month(year,month)

basic_date(year_type year, day_of_year_type day_of_year);

Remarks: Construct a date based on the year and the day of year value.

Throws: bad_year if ymd.year > calendar::max_ymd().year

Throws: bad_day_of_year day_of_year > 366 or (day_of_year = 366 and and year ! leap year)

Note

In the 8601 standard the day_of_year is called the 'ordinal number'. In leap years, dates after Feb 29 have a different day number than in common years. As a result the day_of_year for March 1 is 61 in a leap year and 60 in common years.

basic_date(year_type y, week_of_year_type week_number, weekday_type wd);

Remarks: Construct a date using a specification like: Sunday in Week 50 of year 2004.

Throws: bad_year if ymd.year > calendar::max_ymd().year

Throws: bad_weekday

Throws: bad_week_of_year

basic_date(year_type y, month_type m, week_of_month_type week_number, weekday_type wd);

Remarks: Constructs something like: 3rd Monday in Feb of 2004

Throws: bad_year if ymd.year > calendar::max_ymd().year

Throws: bad_weekday

Throws: bad_week_of_year

basic_date(std::time_t t);

Remarks: Constructs date base on offset from time_t epoch of 1970-01-01.

Throws: None.

basic_date(const std::tm& datetm);

Remarks: Constructs date from the fields specified in the tm structure. In particular uses the fields tm_mday, tm_mon, tm_year. Values of tm_year are treated as years since 1900. Negative values of tm_year are interpreted as a negative offset from the year 1900.

Note

Most implementations of date input/output in current standard libraries accept and correctly handle tm_year with negative values. For example, tm_year == -1 logically corresponds to 1899. Recently one implementation made a recent change by that prohibited negative tm_year values. The author has not been able to find anything in the standard or otherwise that specifies how negative values of tm_year should be handled. This may need to change to support portable implementations going forward.

Throws: bad_year if datetm.tm_year+1900 > calendar::max_ymd().year or datetm.tm_year+1900 < calendar::min_ymd().year

Throws: bad_month if datetm.tm_month < 0 or datetm.tm_month > 11

Throws: bad_day if datetm.tm_day is greater than calendar::last_day_of_month(year,month) or datetm.tm_day < 1

basic_date(special_values_type sv);

Remarks: Constructs date to one of the supported special values.

Throws: None.

Template Class basic_date - Basic accessors

year_type        year()           const;

Returns: Returns year part of the date. Undefined if date is a special_value.

Throws: None.

month_type       month()          const;

Returns: Returns month part of the date. Undefined if date is a special_value.

Throws: None.

day_type         day()            const;

Returns: Returns month part of the date. Undefined if date is a special_value.

Throws: None.

day_of_week_type day_of_week()    const; 

Returns: Returns the iso day of the week represented by the date. Undefined if date is a special value.

Throws: None.

day_of_year_type  day_of_year()  const; //1..365 or 1..366 (for leap year)

Returns: Returns the iso day of the year (1..366) respresented by the date. Undefined if date is a special value.

Throws: None.

week_of_year_type week_number()  const; 

Returns: Returns the iso week number (1..53) of the day respresented by the date. Undefined if date is a special value.

Throws: None.

date_int_type     day_number()   const; 

Returns: Returns the count of days from calendar::ymd_min() to date represented by date. Undefined if date is a special value.

Throws: None.

basic_date        end_of_month() const; 

Returns: Returns the last day in the month of the date as defined by calendar::last_day_of_month(year, month). Undefined if date is a special value.

Throws: None.

bool is_special() const;

Returns: True of the date is set to one of the special values, false otherwise.

Throws: None.

special_values_type as_special()  const;

Returns: Returns one of the special values

Throws: None.

time_t to_time_t() const;   

Returns: Conversion accessor that returns time_t value represented by the date.

Throws: bad_date_conversion if date value is outside the valid date range represented by time_t or date is a special value.

ymd_type      year_month_day() const; 

Returns: Returns the date broken into the year, month, and day structure.

date_int_type julian_day()     const;

Returns: Conversion accessor that returns julian day value represented by the date.

Throws: bad_date_conversion if date value is outside the valid date range represented by julian_day or date is a special value.

date_int_type modjulian_day()  const; 

Returns: Conversion accessor that returns time_t value represented by the date.

Throws: bad_date_conversion if date value is outside the valid date range represented by modjulian_day or date is a special value.

Template Class basic_date - comparison operators

The comparison operators will take into account the following rules for handling of special values. All representable dates between the minimum and maximum representable date are described as 'any valid date' below. In general, positive_infinity is considered to be greater than any valid date as well as not_a_date_time. negative_infinity is considered to be less than any valid date as well as not_a_date_time. Since max_date_time and min_date_time special values represent valid dates these special values utilize normal comparison rules.

Special Value Comparison Rules

descriptionresultNotes
negative_infinity < negative_infinityfalse 
negative_infinity == negative_infinitytrue 
negative_infinity < not_a_date_timetrueAlso true for less-equal
negative_infinity < any valid datetrue 
not_a_date_time == not_a_date_timetrue 
not_a_date_time < not_a_date_timefalseSame is true for less-equal, greater-equal and greater
not_a_date_time == any valid datefalseSame is true for less-equal, greater-equal and greater
positive_infinity > any valid datetrueAlso true for greater-equal
positive_infinity > negative_infinitytrueAlso true for greater-equal, less, less-equal
positive_infinity > negative_infinitytrueAlso true for greater-equal false for less and less-equal
bool operator<  (const basic_date& rhs) const;

Returns: True if date represented by *this < rhs - false otherwise.

bool operator<= (const basic_date&) const;

Returns: True if date represented by *this <= rhs - false otherwise.

bool operator>  (const basic_date&) const;

Returns: True if date represented by *this > rhs - false otherwise.

bool operator>= (const basic_date&) const;

Returns: True if date represented by *this >= rhs - false otherwise.

bool operator== (const basic_date&) const;

Returns: True if date represented by *this >= rhs - false otherwise.

bool operator!= (const basic_date&) const;

Template Class basic_date - arithmetic operators

The following arithmetic operators perform simple subtraction except when the value of the date is a special value. The table defines the rules for special value calculations where 'infinity' represents either positive_infinity or negative_infinity.

Special Value Calculation Rules

Rule --> Result TypeNotes
Timepoint(not_a_date_time) + Duration --> Timepoint(not_a_date_time) 
Timepoint(infinity) + Duration --> Timepoint(infinity) 
Timepoint + Duration(infinity) --> Timepoint(infinity) 
Timepoint - Duration(infinity) --> Timepoint(-infinity) 
Timepoint(+infinity) + Duration(-infinity) --> not_a_date_time 
Duration(+infinity) + Duration(-infinity) --> not_a_date_time 
Duration(infinity) * Zero --> not_a_date_time 
Duration(infinity) * Integer(Not Zero) --> Duration(infinity) 
Duration(+infinity) * -Integer --> Duration(-infinity) 
Duration(infinity) / Integer --> Duration(infinity) 
days operator-  (const basic_date&)     const;

Returns: Number of days between this and rhs date value, or special value results.

basic_date       operator-  (const days&) const;

Returns: Date with the specified number of days subtracted or a special value result.

basic_date       operator-= (const days&);

Effects: Set the date the the number of days subtracted or a special value result.

Returns: Date with the specified number of days subtracted or a special value result.

basic_date       operator+  (const days&) const;

Returns: Date with the specified number of days added or a special value result.

basic_date       operator+= (const days&);

Effects: Set the date the the number of days added or a special value result.

Returns: Date with the specified number of days added or a special value result.

Date Construction Exceptions

The following sections detail classes the represent various errors provided by the library to prevent incorrect construction of invalid date and time values.

Class datetime_error

The datetime_error is a base exception for all datetime error reporting. Derived classes provide additional detailed error information.

class datetime_error : public std::runtime_error 
{}

Note

This class derives from std::runtime_error under the presumption that most of the errors involving date construction are a result of bad data input from a user or other data source that can only be read at runtime.

Class bad_day_of_month

class bad_day_of_month : public bad_date_error 
{
 public:
  bad_day_of_month(int month);
  int bad_day() const;
  
};


bad_day_of_month(int<