Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

date.cpp

Go to the documentation of this file.
00001 #include ".\date.h"
00002 #include <time.h>
00003 
00004 Date::Date(void)
00005 :_serialNumber(LongInteger(0)){
00006 }
00007 
00008 Date::Date(LongInteger serialNumber)
00009 : _serialNumber(serialNumber) {
00010 }
00011 
00012 Date::Date(Day d, Month m, Year y){
00013         bool leap = isLeap(y);
00014         Day len = monthLength(m,leap), offset = monthOffset(m,leap);
00015         _serialNumber = d + offset + yearOffset(y);
00016 }
00017 
00018 Date::Date(Day d, ShortNatural m, Year y) {
00019         switch (m) {
00020                         case 1:
00021                                 Date(d,January,y);
00022                         case 2:
00023                                 Date(d,February,y);
00024                         case 3:
00025                                 Date(d,March,y);
00026                         case 4:
00027                                 Date(d,April,y);
00028                         case 5:
00029                                 Date(d,May,y);
00030                         case 6:
00031                                 Date(d,June,y);
00032                         case 7:
00033                                 Date(d,July,y);
00034                         case 8:
00035                                 Date(d,August,y);
00036                         case 9:
00037                                 Date(d,September,y);
00038                         case 10:
00039                                 Date(d,October,y);
00040                         case 11:
00041                                 Date(d,November,y);
00042                         case 12:
00043                                 Date(d,December,y);
00044         }
00045 
00046 }
00047 
00048 Weekday Date::weekday() const {
00049         Integer w = _serialNumber % 7;
00050         return Weekday(w == 0 ? 7 : w);
00051 }
00052 
00053 Day Date::dayOfMonth() const {
00054         return dayOfYear() - monthOffset(month(),isLeap(year()));
00055 }
00056 
00057 Day Date::dayOfYear() const {
00058         return (Day)(_serialNumber - yearOffset(year()));
00059 }
00060 
00061 Month Date::month() const {
00062         Day d = dayOfYear();
00063         Integer m = d/30 + 1;
00064         bool leap = isLeap(year());
00065         while (d <= monthOffset(Month(m),leap))
00066                 m--;
00067         while (d > monthOffset(Month(m+1),leap))
00068                 m++;
00069         return Month(m);
00070 }
00071 
00072 Year Date::year() const {
00073         Year y = (Year)(1900+(_serialNumber / 365));
00074         if (_serialNumber <= yearOffset(y))
00075                 y--;
00076         return y;
00077 }
00078 
00079 LongInteger Date::serialNumber() const {
00080         return _serialNumber;
00081 }
00082 
00083 bool Date::isEndOfMonth() const {
00084         return isEOM(*this);
00085 }
00086 
00087 Day Date::lastDayOfMonth() const {
00088         return endOfMonth(*this).dayOfMonth();
00089 }
00090 
00091 void Date::setDateToToday() {
00092         time_t tval = time(0);
00093         struct tm *tmp= localtime(&tval);
00094         bool leap = isLeap(tmp->tm_year + 1900);
00095         Day len = monthLength(Month(tmp->tm_mon+1),leap), offset = monthOffset(Month(tmp->tm_mon+1),leap);
00096         _serialNumber = tmp->tm_mday + offset + yearOffset(tmp->tm_year + 1900);
00097 }
00098 
00099 Date& Date::operator+=(LongInteger days) {
00100         LongInteger serial = _serialNumber + days;
00101         _serialNumber = serial;
00102         return *this;
00103 }
00104 
00105 Date& Date::operator-=(LongInteger days) {
00106         LongInteger serial = _serialNumber - days;
00107         _serialNumber = serial;
00108         return *this;
00109 }
00110 
00111 Date& Date::operator++() {
00112         LongInteger serial = _serialNumber + 1;
00113         _serialNumber = serial;
00114         return *this;
00115 }
00116 
00117 Date Date::operator++(int ) {
00118         Date temp = *this;
00119         LongInteger serial = _serialNumber + 1;
00120         _serialNumber = serial;
00121         return temp;
00122 }
00123 
00124 Date& Date::operator--() {
00125         LongInteger serial = _serialNumber - 1;
00126         _serialNumber = serial;
00127         return *this;
00128 }
00129 
00130 Date Date::operator--(int ) {
00131         Date temp = *this;
00132         LongInteger serial = _serialNumber - 1;
00133         _serialNumber = serial;
00134         return temp;
00135 }
00136 
00137 Date Date::operator+(LongInteger days) const {
00138         return Date(_serialNumber+days);
00139 }
00140 
00141 Date Date::operator-(LongInteger days) const {
00142         return Date(_serialNumber-days);
00143 }
00144 
00145 Date Date::plusDays(Integer days) const {
00146         return advance(*this,days,Days);
00147 }
00148 
00149 Date Date::plusWeeks(Integer weeks) const {
00150         return advance(*this,weeks,Weeks);
00151 }
00152 
00153 Date Date::plusMonths(Integer months) const {
00154         return advance(*this,months,Months);
00155 }
00156 
00157 Date Date::plusYears(Integer years) const {
00158         return advance(*this,years,Years);
00159 }
00160 
00161 Date Date::plus(Integer n, TimeUnit units) const {
00162         return advance(*this,n,units);
00163 }
00164 
00165 Date Date::minDate() {
00166         static const Date minimumDate(minimumSerialNumber());
00167         return minimumDate;
00168 }
00169 
00170 Date Date::maxDate() {
00171         static const Date maximumDate(maximumSerialNumber());
00172         return maximumDate;
00173 }
00174 
00175 Date Date::advance(const Date& date, Integer n, TimeUnit units) {
00176         switch (units) {
00177                   case Days:
00178                           return date + n;
00179                   case Weeks:
00180                           return date + 7*n;
00181                   case Months: {
00182                           Day d = date.dayOfMonth();
00183                           Integer m = Integer(date.month())+n;
00184                           Year y = date.year();
00185                           while (m > 12) {
00186                                   m -= 12;
00187                                   y += 1;
00188                           }
00189                           while (m < 1) {
00190                                   m += 12;
00191                                   y -= 1;
00192                           }
00193 
00194                           Integer length = monthLength(Month(m), isLeap(y));
00195                           if (d > length)
00196                                   d = length;
00197 
00198                           return Date(d, Month(m), y);
00199                                            }
00200                   case Years: {
00201                           Day d = date.dayOfMonth();
00202                           Month m = date.month();
00203                           Year y = date.year()+n;
00204 
00205                           if (d == 29 && m == February && !isLeap(y))
00206                                   d = 28;
00207 
00208                           return Date(d,m,y);
00209                                           }
00210                   //default:
00211 
00212         }
00213 }
00214 
00215 bool Date::isLeap(Year y) {
00216         static const bool YearIsLeap[] = {
00217                         // 1900-1909
00218                         true,false,false,false, true,false,false,false, true,false,
00219                         // 1910-1919
00220                         false,false, true,false,false,false, true,false,false,false,
00221                         // 1920-1929
00222                         true,false,false,false, true,false,false,false, true,false,
00223                         // 1930-1939
00224                         false,false, true,false,false,false, true,false,false,false,
00225                         // 1940-1949
00226                         true,false,false,false, true,false,false,false, true,false,
00227                         // 1950-1959
00228                         false,false, true,false,false,false, true,false,false,false,
00229                         // 1960-1969
00230                         true,false,false,false, true,false,false,false, true,false,
00231                         // 1970-1979
00232                         false,false, true,false,false,false, true,false,false,false,
00233                         // 1980-1989
00234                         true,false,false,false, true,false,false,false, true,false,
00235                         // 1990-1999
00236                         false,false, true,false,false,false, true,false,false,false,
00237                         // 2000-2009
00238                         true,false,false,false, true,false,false,false, true,false,
00239                         // 2010-2019
00240                         false,false, true,false,false,false, true,false,false,false,
00241                         // 2020-2029
00242                         true,false,false,false, true,false,false,false, true,false,
00243                         // 2030-2039
00244                         false,false, true,false,false,false, true,false,false,false,
00245                         // 2040-2049
00246                         true,false,false,false, true,false,false,false, true,false,
00247                         // 2050-2059
00248                         false,false, true,false,false,false, true,false,false,false,
00249                         // 2060-2069
00250                         true,false,false,false, true,false,false,false, true,false,
00251                         // 2070-2079
00252                         false,false, true,false,false,false, true,false,false,false,
00253                         // 2080-2089
00254                         true,false,false,false, true,false,false,false, true,false,
00255                         // 2090-2099
00256                         false,false, true,false,false,false, true,false,false,false,
00257                         // 2100
00258                         false
00259         };
00260         return YearIsLeap[y-1900];
00261 }
00262 
00263 Date Date::endOfMonth(const Date& d) {
00264         Month m = d.month();
00265         Year y = d.year();
00266         return Date(monthLength(m, isLeap(y)), m, y);
00267 }
00268 
00269 bool Date::isEOM(const Date& d) {
00270         return (d.dayOfMonth() == monthLength(d.month(), isLeap(d.year())));
00271 }
00272 
00273 Date Date::nextWeekday(const Date& d, Weekday dayOfWeek) {
00274         Weekday wd = d.weekday();
00275         return d + ((wd>dayOfWeek ? 7 : 0) - wd + dayOfWeek);
00276 }
00277 
00278 Date Date::nthWeekday(ShortInteger nth, Weekday dayOfWeek, Month m, Year y) 
00279 {
00280         Weekday first = Date(1, m, y).weekday();
00281         ShortInteger skip = nth - (dayOfWeek>=first ? 1 : 0);
00282         return Date(1 + dayOfWeek-first + skip*7, m, y);
00283 }
00284 
00285 Integer Date::monthLength(Month m, bool leapYear) {
00286         static const Integer MonthLength[] = {
00287                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00288         };
00289         static const Integer MonthLeapLength[] = {
00290                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00291         };
00292         return (leapYear? MonthLeapLength[m-1] : MonthLength[m-1]);
00293 }
00294 
00295 Integer Date::monthOffset(Month m, bool leapYear) {
00296         static const Integer MonthOffset[] = {
00297                 0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334,
00298                         365     // used in dayOfMonth to bracket day
00299         };
00300         static const Integer MonthLeapOffset[] = {
00301                 0,  31,  60,  91, 121, 152,     182, 213, 244, 274, 305, 335,
00302                         366     // used in dayOfMonth to bracket day
00303         };
00304         return (leapYear? MonthLeapOffset[m-1] : MonthOffset[m-1]);
00305 }
00306 LongInteger Date::yearOffset(Year y) {
00307         static const LongInteger YearOffset[] = {
00308                         // 1900-1909
00309                         0,  366,  731, 1096, 1461, 1827, 2192, 2557, 2922, 3288,
00310                         // 1910-1919
00311                         3653, 4018, 4383, 4749, 5114, 5479, 5844, 6210, 6575, 6940,
00312                         // 1920-1929
00313                         7305, 7671, 8036, 8401, 8766, 9132, 9497, 9862,10227,10593,
00314                         // 1930-1939
00315                         10958,11323,11688,12054,12419,12784,13149,13515,13880,14245,
00316                         // 1940-1949
00317                         14610,14976,15341,15706,16071,16437,16802,17167,17532,17898,
00318                         // 1950-1959
00319                         18263,18628,18993,19359,19724,20089,20454,20820,21185,21550,
00320                         // 1960-1969
00321                         21915,22281,22646,23011,23376,23742,24107,24472,24837,25203,
00322                         // 1970-1979
00323                         25568,25933,26298,26664,27029,27394,27759,28125,28490,28855,
00324                         // 1980-1989
00325                         29220,29586,29951,30316,30681,31047,31412,31777,32142,32508,
00326                         // 1990-1999
00327                         32873,33238,33603,33969,34334,34699,35064,35430,35795,36160,
00328                         // 2000-2009
00329                         36525,36891,37256,37621,37986,38352,38717,39082,39447,39813,
00330                         // 2010-2019
00331                         40178,40543,40908,41274,41639,42004,42369,42735,43100,43465,
00332                         // 2020-2029
00333                         43830,44196,44561,44926,45291,45657,46022,46387,46752,47118,
00334                         // 2030-2039
00335                         47483,47848,48213,48579,48944,49309,49674,50040,50405,50770,
00336                         // 2040-2049
00337                         51135,51501,51866,52231,52596,52962,53327,53692,54057,54423,
00338                         // 2050-2059
00339                         54788,55153,55518,55884,56249,56614,56979,57345,57710,58075,
00340                         // 2060-2069
00341                         58440,58806,59171,59536,59901,60267,60632,60997,61362,61728,
00342                         // 2070-2079
00343                         62093,62458,62823,63189,63554,63919,64284,64650,65015,65380,
00344                         // 2080-2089
00345                         65745,66111,66476,66841,67206,67572,67937,68302,68667,69033,
00346                         // 2090-2099
00347                         69398,69763,70128,70494,70859,71224,71589,71955,72320,72685,
00348                         // 2100
00349                         73050
00350         };
00351         return YearOffset[y-1900];
00352 }
00353 
00354 LongInteger Date::minimumSerialNumber() {
00355         return 367;
00356 }
00357 
00358 LongInteger Date::maximumSerialNumber() {
00359         return 73050;    // Dec 31, 2099
00360 }
00361 
00362 bool Date::isBusinessDay() {
00363         return 1;
00364 }
00365 
00366 void Date::applyConvention(BusinessDayConvention convention) {
00367         switch (convention) {
00368                 case Preceding:
00369                         while (!isBusinessDay()) {_serialNumber--;};
00370                 case ModifiedPreceding: {
00371                         LongInteger ser=_serialNumber;
00372                         while (!isBusinessDay()) {_serialNumber--;};
00373                         if (Date(ser).month()!=month()) {
00374                                 _serialNumber=ser;
00375                                 while (!isBusinessDay()) {_serialNumber++;};
00376                         }
00377                 }
00378                 case Following:
00379                         while (!isBusinessDay()) {_serialNumber++;};
00380                 case ModifiedFollowing: {
00381                         LongInteger ser=_serialNumber;
00382                         while (!isBusinessDay()) {_serialNumber++;};
00383                         if (Date(ser).month()!=month()) {
00384                                 _serialNumber=ser;
00385                                 while (!isBusinessDay()) {_serialNumber--;};
00386                         }
00387                 }
00388         }
00389 }               
00390 
00391 Date Date::returnDateConvention(const Date& date, BusinessDayConvention convention) {
00392         Date d1=Date(date.serialNumber());
00393         d1.applyConvention(convention);
00394         return d1;
00395 }
00396 
00397 Real Date::dayCount(const Date& d,DayCountConvention dayconvention) const {
00398         switch (dayconvention) {
00399                 case ACT_365:
00400                         return (TN_REAL(d.serialNumber()-_serialNumber)/365);
00401                 case ACT_360:
00402                         return (TN_REAL(d.serialNumber()-_serialNumber)/360);
00403                 case Day30_365:
00404                         return (TN_REAL(d.dayOfMonth()+30-dayOfMonth()+30*(12*(d.year()-year())+d.month()-month()))/365);
00405                 case Day30_360:
00406                         return (TN_REAL(d.dayOfMonth()+30-dayOfMonth()+30*(12*(d.year()-year())+d.month()-month()))/360);
00407                 default:
00408                         return (TN_REAL(d.serialNumber()-_serialNumber)/365);
00409         }
00410 }
00411 
00412 char* Date::toString() const {
00413         char* strDate=new char[10];
00414         sprintf(strDate,"%d/%d/%d",month(),dayOfMonth(),year());
00415         return strDate;
00416 }
00417 
00418 Date::~Date(void)
00419 {
00420 }

Note: Generated nightly - reload for latest version
Generated on Thu Dec 22 23:12:36 2005 for terreneuve by doxygen 1.3.6