[857] | 1 | #ifndef DATE_TIME_DATE_GENERATORS_HPP__
|
---|
| 2 | #define DATE_TIME_DATE_GENERATORS_HPP__
|
---|
| 3 |
|
---|
| 4 | /* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
|
---|
| 5 | * Use, modification and distribution is subject to the
|
---|
| 6 | * Boost Software License, Version 1.0. (See accompanying
|
---|
| 7 | * file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
|
---|
| 8 | * Author: Jeff Garland, Bart Garst
|
---|
| 9 | * $Date: 2005/04/17 21:48:19 $
|
---|
| 10 | */
|
---|
| 11 |
|
---|
| 12 | /*! @file date_generators.hpp
|
---|
| 13 | Definition and implementation of date algorithm templates
|
---|
| 14 | */
|
---|
| 15 | #include <stdexcept>
|
---|
| 16 | #include <sstream>
|
---|
| 17 | #include "boost/date_time/date.hpp"
|
---|
| 18 | #include "boost/date_time/compiler_config.hpp"
|
---|
| 19 |
|
---|
| 20 | namespace boost {
|
---|
| 21 | namespace date_time {
|
---|
| 22 |
|
---|
| 23 | //! Base class for all generators that take a year and produce a date.
|
---|
| 24 | /*! This class is a base class for polymorphic function objects that take
|
---|
| 25 | a year and produce a concrete date.
|
---|
| 26 | @param date_type The type representing a date. This type must
|
---|
| 27 | export a calender_type which defines a year_type.
|
---|
| 28 | */
|
---|
| 29 | template<class date_type>
|
---|
| 30 | class year_based_generator
|
---|
| 31 | {
|
---|
| 32 | public:
|
---|
| 33 | typedef typename date_type::calendar_type calendar_type;
|
---|
| 34 | typedef typename calendar_type::year_type year_type;
|
---|
| 35 | year_based_generator() {};
|
---|
| 36 | virtual ~year_based_generator() {};
|
---|
| 37 | virtual date_type get_date(year_type y) const = 0;
|
---|
| 38 | //! Returns a string for use in a POSIX time_zone string
|
---|
| 39 | virtual std::string to_string() const =0;
|
---|
| 40 | };
|
---|
| 41 |
|
---|
| 42 | //! Generates a date by applying the year to the given month and day.
|
---|
| 43 | /*!
|
---|
| 44 | Example usage:
|
---|
| 45 | @code
|
---|
| 46 | partial_date pd(1, Jan);
|
---|
| 47 | partial_date pd2(70);
|
---|
| 48 | date d = pd.get_date(2002); //2002-Jan-01
|
---|
| 49 | date d2 = pd2.get_date(2002); //2002-Mar-10
|
---|
| 50 | @endcode
|
---|
| 51 | \ingroup date_alg
|
---|
| 52 | */
|
---|
| 53 | template<class date_type>
|
---|
| 54 | class partial_date : public year_based_generator<date_type>
|
---|
| 55 | {
|
---|
| 56 | public:
|
---|
| 57 | typedef typename date_type::calendar_type calendar_type;
|
---|
| 58 | typedef typename calendar_type::day_type day_type;
|
---|
| 59 | typedef typename calendar_type::month_type month_type;
|
---|
| 60 | typedef typename calendar_type::year_type year_type;
|
---|
| 61 | typedef typename date_type::duration_type duration_type;
|
---|
| 62 | typedef typename duration_type::duration_rep duration_rep;
|
---|
| 63 | partial_date(day_type d, month_type m) :
|
---|
| 64 | day_(d),
|
---|
| 65 | month_(m)
|
---|
| 66 | {}
|
---|
| 67 | //! Partial date created from number of days into year. Range 1-366
|
---|
| 68 | /*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument
|
---|
| 69 | * exceeds range, partial_date will be created with closest in-range value.
|
---|
| 70 | * 60 will always be Feb29, if get_date() is called with a non-leap year
|
---|
| 71 | * an exception will be thrown */
|
---|
| 72 | partial_date(duration_rep days) :
|
---|
| 73 | day_(1), // default values
|
---|
| 74 | month_(1)
|
---|
| 75 | {
|
---|
| 76 | date_type d1(2000,1,1);
|
---|
| 77 | if(days > 1) {
|
---|
| 78 | if(days > 366) // prevents wrapping
|
---|
| 79 | {
|
---|
| 80 | days = 366;
|
---|
| 81 | }
|
---|
| 82 | days = days - 1;
|
---|
| 83 | duration_type dd(days);
|
---|
| 84 | d1 = d1 + dd;
|
---|
| 85 | }
|
---|
| 86 | day_ = d1.day();
|
---|
| 87 | month_ = d1.month();
|
---|
| 88 | }
|
---|
| 89 | //! Return a concrete date when provided with a year specific year.
|
---|
| 90 | /*! Will throw an 'invalid_argument' exception if a partial_date object,
|
---|
| 91 | * instantiated with Feb-29, has get_date called with a non-leap year.
|
---|
| 92 | * Example:
|
---|
| 93 | * @code
|
---|
| 94 | * partial_date pd(29, Feb);
|
---|
| 95 | * pd.get_date(2003); // throws invalid_argument exception
|
---|
| 96 | * pg.get_date(2000); // returns 2000-2-29
|
---|
| 97 | * @endcode
|
---|
| 98 | */
|
---|
| 99 | date_type get_date(year_type y) const
|
---|
| 100 | {
|
---|
| 101 | if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) {
|
---|
| 102 | std::stringstream ss("");
|
---|
| 103 | ss << "No Feb 29th in given year of " << y << ".";
|
---|
| 104 | throw std::invalid_argument(ss.str());
|
---|
| 105 | //return date_type(1,1,1); // should never reach
|
---|
| 106 | } else {
|
---|
| 107 | return date_type(y, month_, day_);
|
---|
| 108 | }
|
---|
| 109 | }
|
---|
| 110 | date_type operator()(year_type y) const
|
---|
| 111 | {
|
---|
| 112 | return get_date(y);
|
---|
| 113 | //return date_type(y, month_, day_);
|
---|
| 114 | }
|
---|
| 115 | bool operator==(const partial_date& rhs) const
|
---|
| 116 | {
|
---|
| 117 | return (month_ == rhs.month_) && (day_ == rhs.day_);
|
---|
| 118 | }
|
---|
| 119 | bool operator<(const partial_date& rhs) const
|
---|
| 120 | {
|
---|
| 121 | if (month_ < rhs.month_) return true;
|
---|
| 122 | if (month_ > rhs.month_) return false;
|
---|
| 123 | //months are equal
|
---|
| 124 | return (day_ < rhs.day_);
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | // added for streaming purposes
|
---|
| 128 | month_type month() const
|
---|
| 129 | {
|
---|
| 130 | return month_;
|
---|
| 131 | }
|
---|
| 132 | day_type day() const
|
---|
| 133 | {
|
---|
| 134 | return day_;
|
---|
| 135 | }
|
---|
| 136 |
|
---|
| 137 | //! Returns string suitable for use in POSIX time zone string
|
---|
| 138 | /*! Returns string formatted with up to 3 digits:
|
---|
| 139 | * Jan-01 == "0"
|
---|
| 140 | * Feb-29 == "58"
|
---|
| 141 | * Dec-31 == "365" */
|
---|
| 142 | virtual std::string to_string() const
|
---|
| 143 | {
|
---|
| 144 | std::stringstream ss;
|
---|
| 145 | date_type d(2004, month_, day_);
|
---|
| 146 | unsigned short c = d.day_of_year();
|
---|
| 147 | c--; // numbered 0-365 while day_of_year is 1 based...
|
---|
| 148 | ss << c;
|
---|
| 149 | return ss.str();
|
---|
| 150 | }
|
---|
| 151 | private:
|
---|
| 152 | day_type day_;
|
---|
| 153 | month_type month_;
|
---|
| 154 | };
|
---|
| 155 |
|
---|
| 156 |
|
---|
| 157 | //! Useful generator functor for finding holidays
|
---|
| 158 | /*! Based on the idea in Cal. Calc. for finding holidays that are
|
---|
| 159 | * the 'first Monday of September'. When instantiated with
|
---|
| 160 | * 'fifth' kday of month, the result will be the last kday of month
|
---|
| 161 | * which can be the fourth or fifth depending on the structure of
|
---|
| 162 | * the month.
|
---|
| 163 | *
|
---|
| 164 | * The algorithm here basically guesses for the first
|
---|
| 165 | * day of the month. Then finds the first day of the correct
|
---|
| 166 | * type. That is, if the first of the month is a Tuesday
|
---|
| 167 | * and it needs Wenesday then we simply increment by a day
|
---|
| 168 | * and then we can add the length of a week until we get
|
---|
| 169 | * to the 'nth kday'. There are probably more efficient
|
---|
| 170 | * algorithms based on using a mod 7, but this one works
|
---|
| 171 | * reasonably well for basic applications.
|
---|
| 172 | * \ingroup date_alg
|
---|
| 173 | */
|
---|
| 174 | template<class date_type>
|
---|
| 175 | class nth_kday_of_month : public year_based_generator<date_type>
|
---|
| 176 | {
|
---|
| 177 | public:
|
---|
| 178 | typedef typename date_type::calendar_type calendar_type;
|
---|
| 179 | typedef typename calendar_type::day_of_week_type day_of_week_type;
|
---|
| 180 | typedef typename calendar_type::month_type month_type;
|
---|
| 181 | typedef typename calendar_type::year_type year_type;
|
---|
| 182 | typedef typename date_type::duration_type duration_type;
|
---|
| 183 | enum week_num {first=1, second, third, fourth, fifth};
|
---|
| 184 | nth_kday_of_month(week_num week_no,
|
---|
| 185 | day_of_week_type dow,
|
---|
| 186 | month_type m) :
|
---|
| 187 | month_(m),
|
---|
| 188 | wn_(week_no),
|
---|
| 189 | dow_(dow)
|
---|
| 190 | {}
|
---|
| 191 | //! Return a concrete date when provided with a year specific year.
|
---|
| 192 | date_type get_date(year_type y) const
|
---|
| 193 | {
|
---|
| 194 | date_type d(y, month_, 1); //first day of month
|
---|
| 195 | duration_type one_day(1);
|
---|
| 196 | duration_type one_week(7);
|
---|
| 197 | while (dow_ != d.day_of_week()) {
|
---|
| 198 | d = d + one_day;
|
---|
| 199 | }
|
---|
| 200 | int week = 1;
|
---|
| 201 | while (week < wn_) {
|
---|
| 202 | d = d + one_week;
|
---|
| 203 | week++;
|
---|
| 204 | }
|
---|
| 205 | // remove wrapping to next month behavior
|
---|
| 206 | if(d.month() != month_) {
|
---|
| 207 | d = d - one_week;
|
---|
| 208 | }
|
---|
| 209 | return d;
|
---|
| 210 | }
|
---|
| 211 | // added for streaming
|
---|
| 212 | month_type month() const
|
---|
| 213 | {
|
---|
| 214 | return month_;
|
---|
| 215 | }
|
---|
| 216 | week_num nth_week() const
|
---|
| 217 | {
|
---|
| 218 | return wn_;
|
---|
| 219 | }
|
---|
| 220 | day_of_week_type day_of_week() const
|
---|
| 221 | {
|
---|
| 222 | return dow_;
|
---|
| 223 | }
|
---|
| 224 | const char* nth_week_as_str() const
|
---|
| 225 | {
|
---|
| 226 | return nth_as_str(wn_);
|
---|
| 227 | }
|
---|
| 228 | //! Returns string suitable for use in POSIX time zone string
|
---|
| 229 | /*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */
|
---|
| 230 | virtual std::string to_string() const
|
---|
| 231 | {
|
---|
| 232 | std::stringstream ss;
|
---|
| 233 | ss << 'M'
|
---|
| 234 | << static_cast<int>(month_) << '.'
|
---|
| 235 | << static_cast<int>(wn_) << '.'
|
---|
| 236 | << static_cast<int>(dow_);
|
---|
| 237 | return ss.str();
|
---|
| 238 | }
|
---|
| 239 | private:
|
---|
| 240 | month_type month_;
|
---|
| 241 | week_num wn_;
|
---|
| 242 | day_of_week_type dow_;
|
---|
| 243 | };
|
---|
| 244 |
|
---|
| 245 | //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5.
|
---|
| 246 | BOOST_DATE_TIME_DECL const char* nth_as_str(int n);
|
---|
| 247 |
|
---|
| 248 | //! Useful generator functor for finding holidays and daylight savings
|
---|
| 249 | /*! Similar to nth_kday_of_month, but requires less paramters
|
---|
| 250 | * \ingroup date_alg
|
---|
| 251 | */
|
---|
| 252 | template<class date_type>
|
---|
| 253 | class first_kday_of_month : public year_based_generator<date_type>
|
---|
| 254 | {
|
---|
| 255 | public:
|
---|
| 256 | typedef typename date_type::calendar_type calendar_type;
|
---|
| 257 | typedef typename calendar_type::day_of_week_type day_of_week_type;
|
---|
| 258 | typedef typename calendar_type::month_type month_type;
|
---|
| 259 | typedef typename calendar_type::year_type year_type;
|
---|
| 260 | typedef typename date_type::duration_type duration_type;
|
---|
| 261 | //!Specify the first 'Sunday' in 'April' spec
|
---|
| 262 | /*!@param dow The day of week, eg: Sunday, Monday, etc
|
---|
| 263 | * @param m The month of the year, eg: Jan, Feb, Mar, etc
|
---|
| 264 | */
|
---|
| 265 | first_kday_of_month(day_of_week_type dow, month_type m) :
|
---|
| 266 | month_(m),
|
---|
| 267 | dow_(dow)
|
---|
| 268 | {}
|
---|
| 269 | //! Return a concrete date when provided with a year specific year.
|
---|
| 270 | date_type get_date(year_type year) const
|
---|
| 271 | {
|
---|
| 272 | date_type d(year, month_,1);
|
---|
| 273 | duration_type one_day(1);
|
---|
| 274 | while (dow_ != d.day_of_week()) {
|
---|
| 275 | d = d + one_day;
|
---|
| 276 | }
|
---|
| 277 | return d;
|
---|
| 278 | }
|
---|
| 279 | // added for streaming
|
---|
| 280 | month_type month() const
|
---|
| 281 | {
|
---|
| 282 | return month_;
|
---|
| 283 | }
|
---|
| 284 | day_of_week_type day_of_week() const
|
---|
| 285 | {
|
---|
| 286 | return dow_;
|
---|
| 287 | }
|
---|
| 288 | //! Returns string suitable for use in POSIX time zone string
|
---|
| 289 | /*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */
|
---|
| 290 | virtual std::string to_string() const
|
---|
| 291 | {
|
---|
| 292 | std::stringstream ss;
|
---|
| 293 | ss << 'M'
|
---|
| 294 | << static_cast<int>(month_) << '.'
|
---|
| 295 | << 1 << '.'
|
---|
| 296 | << static_cast<int>(dow_);
|
---|
| 297 | return ss.str();
|
---|
| 298 | }
|
---|
| 299 | private:
|
---|
| 300 | month_type month_;
|
---|
| 301 | day_of_week_type dow_;
|
---|
| 302 | };
|
---|
| 303 |
|
---|
| 304 |
|
---|
| 305 |
|
---|
| 306 | //! Calculate something like Last Sunday of January
|
---|
| 307 | /*! Useful generator functor for finding holidays and daylight savings
|
---|
| 308 | * Get the last day of the month and then calculate the difference
|
---|
| 309 | * to the last previous day.
|
---|
| 310 | * @param date_type A date class that exports day_of_week, month_type, etc.
|
---|
| 311 | * \ingroup date_alg
|
---|
| 312 | */
|
---|
| 313 | template<class date_type>
|
---|
| 314 | class last_kday_of_month : public year_based_generator<date_type>
|
---|
| 315 | {
|
---|
| 316 | public:
|
---|
| 317 | typedef typename date_type::calendar_type calendar_type;
|
---|
| 318 | typedef typename calendar_type::day_of_week_type day_of_week_type;
|
---|
| 319 | typedef typename calendar_type::month_type month_type;
|
---|
| 320 | typedef typename calendar_type::year_type year_type;
|
---|
| 321 | typedef typename date_type::duration_type duration_type;
|
---|
| 322 | //!Specify the date spec like last 'Sunday' in 'April' spec
|
---|
| 323 | /*!@param dow The day of week, eg: Sunday, Monday, etc
|
---|
| 324 | * @param m The month of the year, eg: Jan, Feb, Mar, etc
|
---|
| 325 | */
|
---|
| 326 | last_kday_of_month(day_of_week_type dow, month_type m) :
|
---|
| 327 | month_(m),
|
---|
| 328 | dow_(dow)
|
---|
| 329 | {}
|
---|
| 330 | //! Return a concrete date when provided with a year specific year.
|
---|
| 331 | date_type get_date(year_type year) const
|
---|
| 332 | {
|
---|
| 333 | date_type d(year, month_, calendar_type::end_of_month_day(year,month_));
|
---|
| 334 | duration_type one_day(1);
|
---|
| 335 | while (dow_ != d.day_of_week()) {
|
---|
| 336 | d = d - one_day;
|
---|
| 337 | }
|
---|
| 338 | return d;
|
---|
| 339 | }
|
---|
| 340 | // added for streaming
|
---|
| 341 | month_type month() const
|
---|
| 342 | {
|
---|
| 343 | return month_;
|
---|
| 344 | }
|
---|
| 345 | day_of_week_type day_of_week() const
|
---|
| 346 | {
|
---|
| 347 | return dow_;
|
---|
| 348 | }
|
---|
| 349 | //! Returns string suitable for use in POSIX time zone string
|
---|
| 350 | /*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */
|
---|
| 351 | virtual std::string to_string() const
|
---|
| 352 | {
|
---|
| 353 | std::stringstream ss;
|
---|
| 354 | ss << 'M'
|
---|
| 355 | << static_cast<int>(month_) << '.'
|
---|
| 356 | << 5 << '.'
|
---|
| 357 | << static_cast<int>(dow_);
|
---|
| 358 | return ss.str();
|
---|
| 359 | }
|
---|
| 360 | private:
|
---|
| 361 | month_type month_;
|
---|
| 362 | day_of_week_type dow_;
|
---|
| 363 | };
|
---|
| 364 |
|
---|
| 365 |
|
---|
| 366 | //! Calculate something like "First Sunday after Jan 1,2002
|
---|
| 367 | /*! Date generator that takes a date and finds kday after
|
---|
| 368 | *@code
|
---|
| 369 | typedef boost::date_time::first_kday_after<date> firstkdayafter;
|
---|
| 370 | firstkdayafter fkaf(Monday);
|
---|
| 371 | fkaf.get_date(date(2002,Feb,1));
|
---|
| 372 | @endcode
|
---|
| 373 | * \ingroup date_alg
|
---|
| 374 | */
|
---|
| 375 | template<class date_type>
|
---|
| 376 | class first_kday_after
|
---|
| 377 | {
|
---|
| 378 | public:
|
---|
| 379 | typedef typename date_type::calendar_type calendar_type;
|
---|
| 380 | typedef typename calendar_type::day_of_week_type day_of_week_type;
|
---|
| 381 | typedef typename date_type::duration_type duration_type;
|
---|
| 382 | first_kday_after(day_of_week_type dow) :
|
---|
| 383 | dow_(dow)
|
---|
| 384 | {}
|
---|
| 385 | //! Return next kday given.
|
---|
| 386 | date_type get_date(date_type start_day) const
|
---|
| 387 | {
|
---|
| 388 | duration_type one_day(1);
|
---|
| 389 | date_type d = start_day + one_day;
|
---|
| 390 | while (dow_ != d.day_of_week()) {
|
---|
| 391 | d = d + one_day;
|
---|
| 392 | }
|
---|
| 393 | return d;
|
---|
| 394 | }
|
---|
| 395 | // added for streaming
|
---|
| 396 | day_of_week_type day_of_week() const
|
---|
| 397 | {
|
---|
| 398 | return dow_;
|
---|
| 399 | }
|
---|
| 400 | private:
|
---|
| 401 | day_of_week_type dow_;
|
---|
| 402 | };
|
---|
| 403 |
|
---|
| 404 | //! Calculate something like "First Sunday before Jan 1,2002
|
---|
| 405 | /*! Date generator that takes a date and finds kday after
|
---|
| 406 | *@code
|
---|
| 407 | typedef boost::date_time::first_kday_before<date> firstkdaybefore;
|
---|
| 408 | firstkdaybefore fkbf(Monday);
|
---|
| 409 | fkbf.get_date(date(2002,Feb,1));
|
---|
| 410 | @endcode
|
---|
| 411 | * \ingroup date_alg
|
---|
| 412 | */
|
---|
| 413 | template<class date_type>
|
---|
| 414 | class first_kday_before
|
---|
| 415 | {
|
---|
| 416 | public:
|
---|
| 417 | typedef typename date_type::calendar_type calendar_type;
|
---|
| 418 | typedef typename calendar_type::day_of_week_type day_of_week_type;
|
---|
| 419 | typedef typename date_type::duration_type duration_type;
|
---|
| 420 | first_kday_before(day_of_week_type dow) :
|
---|
| 421 | dow_(dow)
|
---|
| 422 | {}
|
---|
| 423 | //! Return next kday given.
|
---|
| 424 | date_type get_date(date_type start_day) const
|
---|
| 425 | {
|
---|
| 426 | duration_type one_day(1);
|
---|
| 427 | date_type d = start_day - one_day;
|
---|
| 428 | while (dow_ != d.day_of_week()) {
|
---|
| 429 | d = d - one_day;
|
---|
| 430 | }
|
---|
| 431 | return d;
|
---|
| 432 | }
|
---|
| 433 | // added for streaming
|
---|
| 434 | day_of_week_type day_of_week() const
|
---|
| 435 | {
|
---|
| 436 | return dow_;
|
---|
| 437 | }
|
---|
| 438 | private:
|
---|
| 439 | day_of_week_type dow_;
|
---|
| 440 | };
|
---|
| 441 |
|
---|
| 442 | //! Calculates the number of days until the next weekday
|
---|
| 443 | /*! Calculates the number of days until the next weekday.
|
---|
| 444 | * If the date given falls on a Sunday and the given weekday
|
---|
| 445 | * is Tuesday the result will be 2 days */
|
---|
| 446 | template<typename date_type, class weekday_type>
|
---|
| 447 | inline
|
---|
| 448 | typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd)
|
---|
| 449 | {
|
---|
| 450 | typedef typename date_type::duration_type duration_type;
|
---|
| 451 | duration_type wks(0);
|
---|
| 452 | duration_type dd(wd.as_number() - d.day_of_week().as_number());
|
---|
| 453 | if(dd.is_negative()){
|
---|
| 454 | wks = duration_type(7);
|
---|
| 455 | }
|
---|
| 456 | return dd + wks;
|
---|
| 457 | }
|
---|
| 458 |
|
---|
| 459 | //! Calculates the number of days since the previous weekday
|
---|
| 460 | /*! Calculates the number of days since the previous weekday
|
---|
| 461 | * If the date given falls on a Sunday and the given weekday
|
---|
| 462 | * is Tuesday the result will be 5 days. The answer will be a positive
|
---|
| 463 | * number because Tuesday is 5 days before Sunday, not -5 days before. */
|
---|
| 464 | template<typename date_type, class weekday_type>
|
---|
| 465 | inline
|
---|
| 466 | typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd)
|
---|
| 467 | {
|
---|
| 468 | typedef typename date_type::duration_type duration_type;
|
---|
| 469 | duration_type wks(0);
|
---|
| 470 | duration_type dd(wd.as_number() - d.day_of_week().as_number());
|
---|
| 471 | if(dd.days() > 0){
|
---|
| 472 | wks = duration_type(7);
|
---|
| 473 | }
|
---|
| 474 | // we want a number of days, not an offset. The value returned must
|
---|
| 475 | // be zero or larger.
|
---|
| 476 | return (-dd + wks);
|
---|
| 477 | }
|
---|
| 478 |
|
---|
| 479 | //! Generates a date object representing the date of the following weekday from the given date
|
---|
| 480 | /*! Generates a date object representing the date of the following
|
---|
| 481 | * weekday from the given date. If the date given is 2004-May-9
|
---|
| 482 | * (a Sunday) and the given weekday is Tuesday then the resulting date
|
---|
| 483 | * will be 2004-May-11. */
|
---|
| 484 | template<class date_type, class weekday_type>
|
---|
| 485 | inline
|
---|
| 486 | date_type next_weekday(const date_type& d, const weekday_type& wd)
|
---|
| 487 | {
|
---|
| 488 | return d + days_until_weekday(d, wd);
|
---|
| 489 | }
|
---|
| 490 |
|
---|
| 491 | //! Generates a date object representing the date of the previous weekday from the given date
|
---|
| 492 | /*! Generates a date object representing the date of the previous
|
---|
| 493 | * weekday from the given date. If the date given is 2004-May-9
|
---|
| 494 | * (a Sunday) and the given weekday is Tuesday then the resulting date
|
---|
| 495 | * will be 2004-May-4. */
|
---|
| 496 | template<class date_type, class weekday_type>
|
---|
| 497 | inline
|
---|
| 498 | date_type previous_weekday(const date_type& d, const weekday_type& wd)
|
---|
| 499 | {
|
---|
| 500 | return d - days_before_weekday(d, wd);
|
---|
| 501 | }
|
---|
| 502 |
|
---|
| 503 | } } //namespace date_time
|
---|
| 504 |
|
---|
| 505 |
|
---|
| 506 |
|
---|
| 507 |
|
---|
| 508 | #endif
|
---|
| 509 |
|
---|