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