]> git.stg.codes - stg.git/blob - libs/ibpp/date.cpp
Public interfaces: part 1
[stg.git] / libs / ibpp / date.cpp
1 ///////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 //      File    : $Id: date.cpp,v 1.1 2007/05/05 17:00:42 faust Exp $\r
4 //      Subject : IBPP, Date class implementation\r
5 //\r
6 ///////////////////////////////////////////////////////////////////////////////\r
7 //\r
8 //      (C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org)\r
9 //\r
10 //      The contents of this file are subject to the IBPP License (the "License");\r
11 //      you may not use this file except in compliance with the License.  You may\r
12 //      obtain a copy of the License at http://www.ibpp.org or in the 'license.txt'\r
13 //      file which must have been distributed along with this file.\r
14 //\r
15 //      This software, distributed under the License, is distributed on an "AS IS"\r
16 //      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the\r
17 //      License for the specific language governing rights and limitations\r
18 //      under the License.\r
19 //\r
20 ///////////////////////////////////////////////////////////////////////////////\r
21 //\r
22 //      COMMENTS\r
23 //      * Tabulations should be set every four characters when editing this file.\r
24 //\r
25 ///////////////////////////////////////////////////////////////////////////////\r
26 \r
27 #ifdef _MSC_VER\r
28 #pragma warning(disable: 4786 4996)\r
29 #ifndef _DEBUG\r
30 #pragma warning(disable: 4702)\r
31 #endif\r
32 #endif\r
33 \r
34 #include "_ibpp.h"\r
35 \r
36 #ifdef HAS_HDRSTOP\r
37 #pragma hdrstop\r
38 #endif\r
39 \r
40 #include <time.h>               // Can't use <ctime> thanks to MSVC6 buggy library\r
41 \r
42 using namespace ibpp_internals;\r
43 \r
44 void IBPP::Date::Today()\r
45 {\r
46         time_t systime = time(0);\r
47         tm* loctime = localtime(&systime);\r
48 \r
49         if (! IBPP::itod(&mDate, loctime->tm_year + 1900,\r
50                 loctime->tm_mon + 1, loctime->tm_mday))\r
51                         throw LogicExceptionImpl("Date::Today", _("Out of range"));\r
52 }\r
53 \r
54 void IBPP::Date::SetDate(int dt)\r
55 {\r
56         if (! IBPP::dtoi(dt, 0, 0, 0))\r
57                 throw LogicExceptionImpl("Date::SetDate", _("Out of range"));\r
58         mDate = dt;\r
59 }\r
60 \r
61 void IBPP::Date::SetDate(int year, int month, int day)\r
62 {\r
63         if (! IBPP::itod(&mDate, year, month, day))\r
64                 throw LogicExceptionImpl("Date::SetDate", _("Out of range"));\r
65 }\r
66 \r
67 void IBPP::Date::GetDate(int& year, int& month, int& day) const\r
68 {\r
69         if (! IBPP::dtoi(mDate, &year, &month, &day))\r
70                 throw LogicExceptionImpl("Date::GetDate", _("Out of range"));\r
71 }\r
72 \r
73 int IBPP::Date::Year() const\r
74 {\r
75         int year;\r
76         if (! IBPP::dtoi(mDate, &year, 0, 0))\r
77                 throw LogicExceptionImpl("Date::Year", _("Out of range"));\r
78         return year;\r
79 }\r
80 \r
81 int IBPP::Date::Month() const\r
82 {\r
83         int month;\r
84         if (! IBPP::dtoi(mDate, 0, &month, 0))\r
85                 throw LogicExceptionImpl("Date::Month", _("Out of range"));\r
86         return month;\r
87 }\r
88 \r
89 int IBPP::Date::Day() const\r
90 {\r
91         int day;\r
92         if (! IBPP::dtoi(mDate, 0, 0, &day))\r
93                 throw LogicExceptionImpl("Date::Day", _("Out of range"));\r
94         return day;\r
95 }\r
96 \r
97 void IBPP::Date::Add(int days)\r
98 {\r
99         int newdate = mDate + days;             // days can be signed\r
100         if (! IBPP::dtoi(newdate, 0, 0, 0))\r
101                 throw LogicExceptionImpl("Date::Add()", _("Out of range"));\r
102         mDate = newdate;\r
103 }\r
104 \r
105 void IBPP::Date::StartOfMonth()\r
106 {\r
107         int year, month;\r
108         if (! IBPP::dtoi(mDate, &year, &month, 0))\r
109                 throw LogicExceptionImpl("Date::StartOfMonth()", _("Out of range"));\r
110         if (! IBPP::itod(&mDate, year, month, 1))               // First of same month\r
111                 throw LogicExceptionImpl("Date::StartOfMonth()", _("Out of range"));\r
112 }\r
113 \r
114 void IBPP::Date::EndOfMonth()\r
115 {\r
116         int year, month;\r
117         if (! IBPP::dtoi(mDate, &year, &month, 0))\r
118                 throw LogicExceptionImpl("Date::EndOfMonth()", _("Out of range"));\r
119         if (++month > 12) { month = 1; year++; }\r
120         if (! IBPP::itod(&mDate, year, month, 1))       // First of next month\r
121                 throw LogicExceptionImpl("Date::EndOfMonth()", _("Out of range"));\r
122         mDate--;        // Last day of original month, all weird cases accounted for\r
123 }\r
124 \r
125 IBPP::Date::Date(int year, int month, int day)\r
126 {\r
127         SetDate(year, month, day);\r
128 }\r
129 \r
130 IBPP::Date::Date(const IBPP::Date& copied)\r
131 {\r
132         mDate = copied.mDate;\r
133 }\r
134 \r
135 IBPP::Date& IBPP::Date::operator=(const IBPP::Timestamp& assigned)\r
136 {\r
137         mDate = assigned.GetDate();\r
138         return *this;\r
139 }\r
140 \r
141 IBPP::Date& IBPP::Date::operator=(const IBPP::Date& assigned)\r
142 {\r
143         mDate = assigned.mDate;\r
144         return *this;\r
145 }\r
146 \r
147 // The following date calculations were inspired by web pages found on\r
148 // Peter Baum web homepage at 'http://www.capecod.net/~pbaum/'.\r
149 // His contact info is at : 'http://home.capecod.net/~pbaum/contact.htm'.\r
150 // Please, understand that Peter Baum is not related to this IBPP project.\r
151 // So __please__, do not contact him regarding IBPP matters.\r
152 \r
153 //      Take a date, in its integer format as used in IBPP internals and splits\r
154 //      it in year (4 digits), month (1-12), day (1-31)\r
155 \r
156 bool IBPP::dtoi (int date, int *y, int *m, int *d)\r
157 {\r
158     int RataDie, Z, H, A, B, C;\r
159     int year, month, day;\r
160 \r
161         // Validity control.\r
162         if (date < IBPP::MinDate || date > IBPP::MaxDate)\r
163                 return false;\r
164 \r
165         // The "Rata Die" is the date specified as the number of days elapsed since\r
166         // 31 Dec of year 0. So 1 Jan 0001 is 1.\r
167 \r
168         RataDie = date + ibpp_internals::consts::Dec31_1899;    // Because IBPP sets the '0' on 31 Dec 1899.\r
169 \r
170     Z = RataDie + 306;\r
171     H = 100*Z - 25;\r
172     A = H/3652425;\r
173     B = A - A/4;\r
174     year = (100*B + H) / 36525;\r
175     C = B + Z - 365*year - year / 4;\r
176     month = (5*C + 456) / 153;\r
177     day = C - (153*month - 457) / 5;\r
178     if (month > 12) { year += 1; month -= 12; }\r
179 \r
180         if (y != 0) *y = (int)year;\r
181         if (m != 0) *m = (int)month;\r
182         if (d != 0) *d = (int)day;\r
183 \r
184         return true;\r
185 }\r
186 \r
187 //      Take a date from its components year, month, day and convert it to the\r
188 //      integer representation used internally in IBPP.\r
189 \r
190 bool IBPP::itod (int *pdate, int year, int month, int day)\r
191 {\r
192     int RataDie, result;\r
193         int y, m, d;\r
194 \r
195         d = day;        m = month;              y = year;\r
196     if (m < 3) { m += 12; y -= 1; }\r
197     RataDie = d + (153*m - 457) / 5 + 365*y + y/4 - y/100 + y/400 - 306;\r
198 \r
199         result = RataDie - ibpp_internals::consts::Dec31_1899;   // Because IBPP sets the '0' on 31 Dec 1899\r
200 \r
201         // Validity control\r
202         if (result < IBPP::MinDate || result > IBPP::MaxDate)\r
203                 return false;\r
204 \r
205         *pdate = result;\r
206         return true;\r
207 }\r
208 \r
209 //      Eof\r