diff options
Diffstat (limited to '3rdParty/Boost/src/boost/date_time/gregorian_calendar.ipp')
-rw-r--r-- | 3rdParty/Boost/src/boost/date_time/gregorian_calendar.ipp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/date_time/gregorian_calendar.ipp b/3rdParty/Boost/src/boost/date_time/gregorian_calendar.ipp new file mode 100644 index 0000000..b7628fc --- /dev/null +++ b/3rdParty/Boost/src/boost/date_time/gregorian_calendar.ipp @@ -0,0 +1,219 @@ +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $ + */ + +#ifndef NO_BOOST_DATE_TIME_INLINE + #undef BOOST_DATE_TIME_INLINE + #define BOOST_DATE_TIME_INLINE inline +#endif + +namespace boost { +namespace date_time { + //! Return the day of the week (0==Sunday, 1==Monday, etc) + /*! Converts a year-month-day into a day of the week number + */ + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base<ymd_type_,date_int_type_>::day_of_week(const ymd_type& ymd) { + unsigned short a = static_cast<unsigned short>((14-ymd.month)/12); + unsigned short y = static_cast<unsigned short>(ymd.year - a); + unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 2); + unsigned short d = static_cast<unsigned short>((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7); + //std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n"; + return d; + } + + //!Return the iso week number for the date + /*!Implements the rules associated with the iso 8601 week number. + Basically the rule is that Week 1 of the year is the week that contains + January 4th or the week that contains the first Thursday in January. + Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000. + */ + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + int + gregorian_calendar_base<ymd_type_,date_int_type_>::week_number(const ymd_type& ymd) { + unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1)); + unsigned long juliantoday = julian_day_number(ymd); + unsigned long day = (julianbegin + 3) % 7; + unsigned long week = (juliantoday + day - julianbegin + 4)/7; + + if ((week >= 1) && (week <= 52)) { + return week; + } + + if ((week == 53)) { + if((day==6) ||(day == 5 && is_leap_year(ymd.year))) { + return week; //under these circumstances week == 53. + } else { + return 1; //monday - wednesday is in week 1 of next year + } + } + //if the week is not in current year recalculate using the previous year as the beginning year + else if (week == 0) { + julianbegin = julian_day_number(ymd_type(static_cast<unsigned short>(ymd.year-1),1,1)); + juliantoday = julian_day_number(ymd); + day = (julianbegin + 3) % 7; + week = (juliantoday + day - julianbegin + 4)/7; + return week; + } + + return week; //not reachable -- well except if day == 5 and is_leap_year != true + + } + + //! Convert a ymd_type into a day number + /*! The day number is an absolute number of days since the start of count + */ + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + date_int_type_ + gregorian_calendar_base<ymd_type_,date_int_type_>::day_number(const ymd_type& ymd) + { + unsigned short a = static_cast<unsigned short>((14-ymd.month)/12); + unsigned short y = static_cast<unsigned short>(ymd.year + 4800 - a); + unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 3); + unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045; + return d; + } + + //! Convert a year-month-day into the julian day number + /*! Since this implementation uses julian day internally, this is the same as the day_number. + */ + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + date_int_type_ + gregorian_calendar_base<ymd_type_,date_int_type_>::julian_day_number(const ymd_type& ymd) + { + return day_number(ymd); + } + + //! Convert year-month-day into a modified julian day number + /*! The day number is an absolute number of days. + * MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC + */ + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + long + gregorian_calendar_base<ymd_type_,date_int_type_>::modjulian_day_number(const ymd_type& ymd) + { + return julian_day_number(ymd)-2400001; //prerounded + } + + //! Change a day number into a year-month-day + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base<ymd_type_,date_int_type_>::from_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a + 3)/146097; + date_int_type c = a-((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - (1461*d)/4; + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10)); + year_type year = static_cast<unsigned short>(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(static_cast<unsigned short>(year),month,day); + } + + //! Change a day number into a year-month-day + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base<ymd_type_,date_int_type_>::from_julian_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a+3)/146097; + date_int_type c = a - ((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - ((1461*d)/4); + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10)); + year_type year = static_cast<year_type>(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(year,month,day); + } + + //! Change a modified julian day number into a year-month-day + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base<ymd_type_,date_int_type_>::from_modjulian_day_number(long dayNumber) { + date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded + return from_julian_day_number(jd); + } + + //! Determine if the provided year is a leap year + /*! + *@return true if year is a leap year, false otherwise + */ + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + bool + gregorian_calendar_base<ymd_type_,date_int_type_>::is_leap_year(year_type year) + { + //divisible by 4, not if divisible by 100, but true if divisible by 400 + return (!(year % 4)) && ((year % 100) || (!(year % 400))); + } + + //! Calculate the last day of the month + /*! Find the day which is the end of the month given year and month + * No error checking is performed. + */ + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base<ymd_type_,date_int_type_>::end_of_month_day(year_type year, + month_type month) + { + switch (month) { + case 2: + if (is_leap_year(year)) { + return 29; + } else { + return 28; + }; + case 4: + case 6: + case 9: + case 11: + return 30; + default: + return 31; + }; + + } + + //! Provide the ymd_type specification for the calandar start + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base<ymd_type_,date_int_type_>::epoch() + { + return ymd_type(1400,1,1); + } + + //! Defines length of a week for week calculations + template<typename ymd_type_, typename date_int_type_> + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base<ymd_type_,date_int_type_>::days_in_week() + { + return 7; + } + + +} } //namespace gregorian + + |