annotate DEPENDENCIES/generic/include/boost/date_time/gregorian_calendar.ipp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /* Copyright (c) 2002,2003 CrystalClear Software, Inc.
Chris@16 2 * Use, modification and distribution is subject to the
Chris@16 3 * Boost Software License, Version 1.0. (See accompanying
Chris@16 4 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5 * Author: Jeff Garland, Bart Garst
Chris@101 6 * $Date$
Chris@16 7 */
Chris@16 8
Chris@16 9 #ifndef NO_BOOST_DATE_TIME_INLINE
Chris@16 10 #undef BOOST_DATE_TIME_INLINE
Chris@16 11 #define BOOST_DATE_TIME_INLINE inline
Chris@16 12 #endif
Chris@16 13
Chris@16 14 namespace boost {
Chris@16 15 namespace date_time {
Chris@16 16 //! Return the day of the week (0==Sunday, 1==Monday, etc)
Chris@16 17 /*! Converts a year-month-day into a day of the week number
Chris@16 18 */
Chris@16 19 template<typename ymd_type_, typename date_int_type_>
Chris@16 20 BOOST_DATE_TIME_INLINE
Chris@16 21 unsigned short
Chris@16 22 gregorian_calendar_base<ymd_type_,date_int_type_>::day_of_week(const ymd_type& ymd) {
Chris@16 23 unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
Chris@16 24 unsigned short y = static_cast<unsigned short>(ymd.year - a);
Chris@16 25 unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 2);
Chris@16 26 unsigned short d = static_cast<unsigned short>((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7);
Chris@16 27 //std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n";
Chris@16 28 return d;
Chris@16 29 }
Chris@16 30
Chris@16 31 //!Return the iso week number for the date
Chris@16 32 /*!Implements the rules associated with the iso 8601 week number.
Chris@16 33 Basically the rule is that Week 1 of the year is the week that contains
Chris@16 34 January 4th or the week that contains the first Thursday in January.
Chris@16 35 Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000.
Chris@16 36 */
Chris@16 37 template<typename ymd_type_, typename date_int_type_>
Chris@16 38 BOOST_DATE_TIME_INLINE
Chris@16 39 int
Chris@16 40 gregorian_calendar_base<ymd_type_,date_int_type_>::week_number(const ymd_type& ymd) {
Chris@16 41 unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1));
Chris@16 42 unsigned long juliantoday = julian_day_number(ymd);
Chris@16 43 unsigned long day = (julianbegin + 3) % 7;
Chris@16 44 unsigned long week = (juliantoday + day - julianbegin + 4)/7;
Chris@16 45
Chris@16 46 if ((week >= 1) && (week <= 52)) {
Chris@16 47 return week;
Chris@16 48 }
Chris@16 49
Chris@16 50 if (week == 53) {
Chris@16 51 if((day==6) ||(day == 5 && is_leap_year(ymd.year))) {
Chris@16 52 return week; //under these circumstances week == 53.
Chris@16 53 } else {
Chris@16 54 return 1; //monday - wednesday is in week 1 of next year
Chris@16 55 }
Chris@16 56 }
Chris@16 57 //if the week is not in current year recalculate using the previous year as the beginning year
Chris@16 58 else if (week == 0) {
Chris@16 59 julianbegin = julian_day_number(ymd_type(static_cast<unsigned short>(ymd.year-1),1,1));
Chris@16 60 juliantoday = julian_day_number(ymd);
Chris@16 61 day = (julianbegin + 3) % 7;
Chris@16 62 week = (juliantoday + day - julianbegin + 4)/7;
Chris@16 63 return week;
Chris@16 64 }
Chris@16 65
Chris@16 66 return week; //not reachable -- well except if day == 5 and is_leap_year != true
Chris@16 67
Chris@16 68 }
Chris@16 69
Chris@16 70 //! Convert a ymd_type into a day number
Chris@16 71 /*! The day number is an absolute number of days since the start of count
Chris@16 72 */
Chris@16 73 template<typename ymd_type_, typename date_int_type_>
Chris@16 74 BOOST_DATE_TIME_INLINE
Chris@16 75 date_int_type_
Chris@16 76 gregorian_calendar_base<ymd_type_,date_int_type_>::day_number(const ymd_type& ymd)
Chris@16 77 {
Chris@16 78 unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
Chris@16 79 unsigned short y = static_cast<unsigned short>(ymd.year + 4800 - a);
Chris@16 80 unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 3);
Chris@16 81 unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045;
Chris@16 82 return d;
Chris@16 83 }
Chris@16 84
Chris@16 85 //! Convert a year-month-day into the julian day number
Chris@16 86 /*! Since this implementation uses julian day internally, this is the same as the day_number.
Chris@16 87 */
Chris@16 88 template<typename ymd_type_, typename date_int_type_>
Chris@16 89 BOOST_DATE_TIME_INLINE
Chris@16 90 date_int_type_
Chris@16 91 gregorian_calendar_base<ymd_type_,date_int_type_>::julian_day_number(const ymd_type& ymd)
Chris@16 92 {
Chris@16 93 return day_number(ymd);
Chris@16 94 }
Chris@16 95
Chris@16 96 //! Convert year-month-day into a modified julian day number
Chris@16 97 /*! The day number is an absolute number of days.
Chris@16 98 * MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC
Chris@16 99 */
Chris@16 100 template<typename ymd_type_, typename date_int_type_>
Chris@16 101 BOOST_DATE_TIME_INLINE
Chris@16 102 date_int_type_
Chris@16 103 gregorian_calendar_base<ymd_type_,date_int_type_>::modjulian_day_number(const ymd_type& ymd)
Chris@16 104 {
Chris@16 105 return julian_day_number(ymd)-2400001; //prerounded
Chris@16 106 }
Chris@16 107
Chris@16 108 //! Change a day number into a year-month-day
Chris@16 109 template<typename ymd_type_, typename date_int_type_>
Chris@16 110 BOOST_DATE_TIME_INLINE
Chris@16 111 ymd_type_
Chris@16 112 gregorian_calendar_base<ymd_type_,date_int_type_>::from_day_number(date_int_type dayNumber)
Chris@16 113 {
Chris@16 114 date_int_type a = dayNumber + 32044;
Chris@16 115 date_int_type b = (4*a + 3)/146097;
Chris@16 116 date_int_type c = a-((146097*b)/4);
Chris@16 117 date_int_type d = (4*c + 3)/1461;
Chris@16 118 date_int_type e = c - (1461*d)/4;
Chris@16 119 date_int_type m = (5*e + 2)/153;
Chris@16 120 unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
Chris@16 121 unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
Chris@16 122 year_type year = static_cast<unsigned short>(100*b + d - 4800 + (m/10));
Chris@16 123 //std::cout << year << "-" << month << "-" << day << "\n";
Chris@16 124
Chris@16 125 return ymd_type(static_cast<unsigned short>(year),month,day);
Chris@16 126 }
Chris@16 127
Chris@16 128 //! Change a day number into a year-month-day
Chris@16 129 template<typename ymd_type_, typename date_int_type_>
Chris@16 130 BOOST_DATE_TIME_INLINE
Chris@16 131 ymd_type_
Chris@16 132 gregorian_calendar_base<ymd_type_,date_int_type_>::from_julian_day_number(date_int_type dayNumber)
Chris@16 133 {
Chris@16 134 date_int_type a = dayNumber + 32044;
Chris@16 135 date_int_type b = (4*a+3)/146097;
Chris@16 136 date_int_type c = a - ((146097*b)/4);
Chris@16 137 date_int_type d = (4*c + 3)/1461;
Chris@16 138 date_int_type e = c - ((1461*d)/4);
Chris@16 139 date_int_type m = (5*e + 2)/153;
Chris@16 140 unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
Chris@16 141 unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
Chris@16 142 year_type year = static_cast<year_type>(100*b + d - 4800 + (m/10));
Chris@16 143 //std::cout << year << "-" << month << "-" << day << "\n";
Chris@16 144
Chris@16 145 return ymd_type(year,month,day);
Chris@16 146 }
Chris@16 147
Chris@16 148 //! Change a modified julian day number into a year-month-day
Chris@16 149 template<typename ymd_type_, typename date_int_type_>
Chris@16 150 BOOST_DATE_TIME_INLINE
Chris@16 151 ymd_type_
Chris@16 152 gregorian_calendar_base<ymd_type_,date_int_type_>::from_modjulian_day_number(date_int_type dayNumber) {
Chris@16 153 date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded
Chris@16 154 return from_julian_day_number(jd);
Chris@16 155 }
Chris@16 156
Chris@16 157 //! Determine if the provided year is a leap year
Chris@16 158 /*!
Chris@16 159 *@return true if year is a leap year, false otherwise
Chris@16 160 */
Chris@16 161 template<typename ymd_type_, typename date_int_type_>
Chris@16 162 BOOST_DATE_TIME_INLINE
Chris@16 163 bool
Chris@16 164 gregorian_calendar_base<ymd_type_,date_int_type_>::is_leap_year(year_type year)
Chris@16 165 {
Chris@16 166 //divisible by 4, not if divisible by 100, but true if divisible by 400
Chris@16 167 return (!(year % 4)) && ((year % 100) || (!(year % 400)));
Chris@16 168 }
Chris@16 169
Chris@16 170 //! Calculate the last day of the month
Chris@16 171 /*! Find the day which is the end of the month given year and month
Chris@16 172 * No error checking is performed.
Chris@16 173 */
Chris@16 174 template<typename ymd_type_, typename date_int_type_>
Chris@16 175 BOOST_DATE_TIME_INLINE
Chris@16 176 unsigned short
Chris@16 177 gregorian_calendar_base<ymd_type_,date_int_type_>::end_of_month_day(year_type year,
Chris@16 178 month_type month)
Chris@16 179 {
Chris@16 180 switch (month) {
Chris@16 181 case 2:
Chris@16 182 if (is_leap_year(year)) {
Chris@16 183 return 29;
Chris@16 184 } else {
Chris@16 185 return 28;
Chris@16 186 };
Chris@16 187 case 4:
Chris@16 188 case 6:
Chris@16 189 case 9:
Chris@16 190 case 11:
Chris@16 191 return 30;
Chris@16 192 default:
Chris@16 193 return 31;
Chris@16 194 };
Chris@16 195
Chris@16 196 }
Chris@16 197
Chris@16 198 //! Provide the ymd_type specification for the calandar start
Chris@16 199 template<typename ymd_type_, typename date_int_type_>
Chris@16 200 BOOST_DATE_TIME_INLINE
Chris@16 201 ymd_type_
Chris@16 202 gregorian_calendar_base<ymd_type_,date_int_type_>::epoch()
Chris@16 203 {
Chris@16 204 return ymd_type(1400,1,1);
Chris@16 205 }
Chris@16 206
Chris@16 207 //! Defines length of a week for week calculations
Chris@16 208 template<typename ymd_type_, typename date_int_type_>
Chris@16 209 BOOST_DATE_TIME_INLINE
Chris@16 210 unsigned short
Chris@16 211 gregorian_calendar_base<ymd_type_,date_int_type_>::days_in_week()
Chris@16 212 {
Chris@16 213 return 7;
Chris@16 214 }
Chris@16 215
Chris@16 216
Chris@16 217 } } //namespace gregorian
Chris@16 218
Chris@16 219