b311480e |
1 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
15 | // ------------------------------------------------------------- |
7fd59977 |
16 | // C matra datavision 1993 |
7fd59977 |
17 | // Updated : |
7fd59977 |
18 | // ------------------------------------------------------------- |
42cf5bc1 |
19 | |
20 | #include <Quantity_Date.hxx> |
7fd59977 |
21 | #include <Quantity_DateDefinitionError.hxx> |
42cf5bc1 |
22 | #include <Quantity_Period.hxx> |
7fd59977 |
23 | #include <Standard_OutOfRange.hxx> |
7fd59977 |
24 | |
25 | static int month_table[12] = { |
26 | 31, // January |
27 | 28, // February |
28 | 31, // March |
29 | 30, // April |
30 | 31, // May |
31 | 30, // June |
32 | 31, // July |
33 | 31, // August |
34 | 30, // September |
35 | 31, // October |
36 | 30, // November |
37 | 31}; // December |
38 | |
39 | static int SecondsByYear = 365 * 24 * 3600 ; // Normal Year |
40 | static int SecondsByLeapYear = 366 * 24 * 3600 ; // Leap Year |
41 | |
42 | // ----------------------------------------- |
43 | // Initialize a date to January,1 1979 00:00 |
44 | // ----------------------------------------- |
45 | |
46 | Quantity_Date::Quantity_Date(): mySec(0),myUSec(0) {} |
47 | |
48 | |
49 | |
50 | // ----------------------------------------------------------- |
51 | // IsValid : Checks the validity of a date |
52 | // This is the complete way month, day, year, ... micro second |
53 | // ----------------------------------------------------------- |
54 | |
55 | |
56 | Standard_Boolean Quantity_Date::IsValid(const Standard_Integer mm, |
57 | const Standard_Integer dd, |
58 | const Standard_Integer yy, |
59 | const Standard_Integer hh, |
60 | const Standard_Integer mn, |
61 | const Standard_Integer ss, |
62 | const Standard_Integer mis, |
63 | const Standard_Integer mics){ |
64 | |
65 | if (mm < 1 || mm > 12) return Standard_False; |
66 | |
67 | |
68 | if (yy < 1979 ) return Standard_False; |
69 | |
70 | |
71 | if ( Quantity_Date::IsLeap (yy) ) month_table[1] = 29; |
72 | else month_table[1] = 28; |
73 | |
74 | if (dd < 1 || dd > month_table[mm-1]) return Standard_False; |
75 | |
76 | |
77 | if (hh < 0 || hh > 23) return Standard_False; |
78 | |
79 | |
80 | if (mn < 0 || mn > 59) return Standard_False; |
81 | |
82 | |
83 | if (ss < 0 || ss > 59) return Standard_False; |
84 | |
85 | |
86 | if (mis < 0 || mis > 999) return Standard_False; |
87 | |
88 | |
89 | if (mics < 0 || mics > 999) return Standard_False; |
90 | |
91 | return Standard_True; |
92 | |
93 | } |
94 | |
95 | // ----------------------------------------------------------- |
96 | // Initialize a Date : |
97 | // This is the complete way month, day, year, ... micro second |
98 | // ----------------------------------------------------------- |
99 | |
100 | |
101 | Quantity_Date::Quantity_Date(const Standard_Integer mm, |
102 | const Standard_Integer dd, |
103 | const Standard_Integer yy, |
104 | const Standard_Integer hh, |
105 | const Standard_Integer mn, |
106 | const Standard_Integer ss, |
107 | const Standard_Integer mis, |
108 | const Standard_Integer mics){ |
109 | |
110 | SetValues (mm,dd,yy,hh,mn,ss,mis,mics); |
111 | } |
112 | |
113 | // ------------------------------------------------------------ |
114 | // Set values of a Date : |
115 | // This is the complete way month, day, year, ... micro second |
116 | // ------------------------------------------------------------ |
117 | |
118 | void Quantity_Date::SetValues(const Standard_Integer mm, |
119 | const Standard_Integer dd, |
120 | const Standard_Integer yy, |
121 | const Standard_Integer hh, |
122 | const Standard_Integer mn, |
123 | const Standard_Integer ss, |
124 | const Standard_Integer mis, |
125 | const Standard_Integer mics){ |
126 | |
127 | Standard_Integer i; |
128 | |
129 | if ( ! Quantity_Date::IsValid (mm,dd,yy,hh,mn,ss,mis,mics)) |
9775fa61 |
130 | throw Quantity_DateDefinitionError("Quantity_Date::Quantity_Date invalid parameters"); |
7fd59977 |
131 | |
132 | if ( Quantity_Date::IsLeap (yy) ) month_table[1] = 29; |
133 | else month_table[1] = 28; |
134 | |
135 | mySec = 0; |
136 | myUSec = 0; |
137 | for(i = 1979; i < yy; i++) { |
138 | if ( ! Quantity_Date::IsLeap (i) ) mySec += SecondsByYear; |
139 | else mySec += SecondsByLeapYear; |
140 | } |
141 | |
142 | for(i = 1; i< mm; i++) { |
143 | mySec += month_table[i-1] * 3600 * 24 ; |
144 | } |
145 | |
146 | |
147 | mySec += 3600 * 24 * (dd-1); |
148 | |
149 | mySec += 3600 * hh; |
150 | |
151 | mySec += 60 * mn; |
152 | |
153 | mySec += ss; |
154 | |
155 | myUSec += mis * 1000; |
156 | |
157 | myUSec += mics; |
158 | |
159 | } |
160 | |
161 | |
162 | // --------------------------------------------- |
163 | // Values : Returns the values of a date |
164 | // ~~~~~~ |
165 | // --------------------------------------------- |
166 | |
167 | void Quantity_Date::Values(Standard_Integer& mm, |
168 | Standard_Integer& dd, |
169 | Standard_Integer& yy, |
170 | Standard_Integer& hh, |
171 | Standard_Integer& mn, |
172 | Standard_Integer& ss, |
173 | Standard_Integer& mis, |
174 | Standard_Integer& mics)const{ |
175 | |
176 | |
177 | Standard_Integer i,carry; |
178 | |
179 | |
180 | for(yy = 1979, carry = mySec ;; yy++) { |
181 | if ( ! Quantity_Date::IsLeap (yy) ) |
182 | { |
183 | month_table[1] = 28; // normal year |
184 | if (carry >= SecondsByYear ) carry -= SecondsByYear; |
185 | else break; |
186 | } |
187 | else |
188 | { |
189 | month_table[1] = 29; // Leap year |
190 | if (carry >= SecondsByLeapYear) carry -= SecondsByLeapYear; |
191 | else break; |
192 | } |
193 | } |
194 | |
195 | |
196 | for(mm = 1 ; ; mm++) { |
197 | i = month_table[mm-1] * 3600 * 24; |
198 | if ( carry >= i ) carry -= i; |
199 | else break; |
200 | } |
201 | |
202 | i = 3600 * 24; |
203 | for(dd = 1 ; ; dd++) { |
204 | if ( carry >= i ) carry -= i; |
205 | else break; |
206 | } |
207 | |
208 | for(hh = 0 ; ; hh++) { |
209 | if ( carry >= 3600 ) carry -= 3600; |
210 | else break; |
211 | } |
212 | |
213 | for(mn = 0 ; ; mn++) { |
214 | if ( carry >= 60 ) carry -= 60; |
215 | else break; |
216 | } |
217 | |
218 | ss = carry; |
219 | |
220 | mis = myUSec / 1000; |
221 | mics = myUSec - ( mis * 1000); |
222 | } |
223 | |
224 | |
225 | // --------------------------------------------------------------------- |
226 | // Difference : Subtract a date to a given date; the result is a period |
227 | // ~~~~~~~~~~ of time |
228 | // --------------------------------------------------------------------- |
229 | |
230 | Quantity_Period Quantity_Date::Difference(const Quantity_Date& OtherDate){ |
231 | |
232 | Standard_Integer i1,i2; |
233 | |
234 | if (mySec == 0 && myUSec == 0) |
235 | { |
236 | i1 = OtherDate.mySec; |
237 | i2 = OtherDate.myUSec; |
238 | } |
239 | else { |
240 | i1 = mySec - OtherDate.mySec ; |
241 | i2 = myUSec - OtherDate.myUSec; |
242 | } |
243 | |
244 | if ( i1 >= 0 && i2 < 0 ) { |
245 | i1--; |
246 | i2 = 1000000 + i2 ; |
247 | } |
248 | else if ( i1 <0 && i2 >= 0 ) { |
249 | i1 = Abs(i1); |
250 | if ( i2 > 0 ){ |
251 | i1--; |
252 | i2 = 1000000 - i2 ; |
253 | } |
254 | } |
255 | else if ( i1 <0 && i2 < 0 ) { |
256 | i1 = Abs(i1); |
257 | i2 = Abs(i2); |
258 | } |
259 | |
260 | Quantity_Period result ( i1 , i2 ); |
261 | |
262 | return (result); |
263 | } |
264 | |
265 | |
266 | // ------------------------------------------------------------------ |
267 | // Subtract : subtracts a period to a date and returns a date. |
268 | // ~~~~~~~~ |
269 | // ------------------------------------------------------------------ |
270 | |
271 | Quantity_Date Quantity_Date::Subtract(const Quantity_Period& During){ |
272 | |
273 | Standard_Integer ss,mics; |
274 | Quantity_Date result; |
275 | result.mySec = mySec; |
276 | result.myUSec = myUSec; |
277 | During.Values (ss,mics); |
278 | |
279 | result.mySec -= ss; |
280 | result.myUSec -= mics; |
281 | |
282 | if ( result.mySec >= 0 && result.myUSec < 0 ) { |
283 | result.mySec--; |
284 | result.myUSec = 1000000 + result.myUSec ; |
285 | } |
286 | |
287 | |
288 | if ( result.mySec <0 ) |
9775fa61 |
289 | throw Quantity_DateDefinitionError( |
7fd59977 |
290 | "Quantity_Date::Subtract : The result date is anterior to Jan,1 1979"); |
291 | |
292 | return (result); |
293 | |
294 | } |
295 | |
296 | |
297 | // ---------------------------------------------------------------------- |
298 | // Add : Adds a period of time to a date |
299 | // ~~~ |
300 | // ---------------------------------------------------------------------- |
301 | Quantity_Date Quantity_Date::Add(const Quantity_Period& During){ |
302 | |
303 | Quantity_Date result; |
304 | During.Values (result.mySec,result.myUSec); |
305 | result.mySec += mySec; |
306 | result.myUSec += myUSec; |
307 | if ( result.myUSec >= 1000000 ) { |
308 | result.mySec++; |
309 | result.myUSec -= 1000000; |
310 | } |
311 | return (result); |
312 | } |
313 | |
314 | |
315 | // ---------------------------------------------------------------------- |
316 | // Year : Return the year of a date |
317 | // ~~~~ |
318 | // ---------------------------------------------------------------------- |
319 | Standard_Integer Quantity_Date::Year(){ |
320 | Standard_Integer dummy, year; |
321 | Values(dummy, dummy, year, dummy, dummy, dummy, dummy, dummy); |
322 | return (year); |
323 | } |
324 | |
325 | |
326 | // ---------------------------------------------------------------------- |
327 | // Month : Return the month of a date |
328 | // ~~~~~ |
329 | // ---------------------------------------------------------------------- |
330 | Standard_Integer Quantity_Date::Month(){ |
331 | Standard_Integer dummy, month; |
332 | Values(month, dummy, dummy, dummy, dummy, dummy, dummy, dummy); |
333 | return(month); |
334 | } |
335 | |
336 | // ---------------------------------------------------------------------- |
337 | // Day : Return the day of a date |
338 | // ~~~ |
339 | // ---------------------------------------------------------------------- |
340 | |
341 | Standard_Integer Quantity_Date::Day(){ |
342 | Standard_Integer dummy, day; |
343 | Values(dummy, day, dummy, dummy, dummy, dummy, dummy, dummy); |
344 | return(day); |
345 | } |
346 | |
347 | // ---------------------------------------------------------------------- |
348 | // hour : Return the hour of a date |
349 | // ~~~~ |
350 | // ---------------------------------------------------------------------- |
351 | |
352 | Standard_Integer Quantity_Date::Hour(){ |
353 | Standard_Integer dummy, hour; |
354 | Values(dummy, dummy, dummy, hour, dummy, dummy, dummy, dummy); |
355 | return(hour); |
356 | } |
357 | |
358 | // ---------------------------------------------------------------------- |
359 | // Minute : Return the minute of a date |
360 | // ~~~~~~ |
361 | // ---------------------------------------------------------------------- |
362 | |
363 | Standard_Integer Quantity_Date::Minute(){ |
364 | Standard_Integer dummy, min; |
365 | Values(dummy, dummy, dummy, dummy, min, dummy, dummy, dummy); |
366 | return(min); |
367 | } |
368 | |
369 | // ---------------------------------------------------------------------- |
370 | // Second : Return the second of a date |
371 | // ~~~~~~ |
372 | // ---------------------------------------------------------------------- |
373 | |
374 | Standard_Integer Quantity_Date::Second(){ |
375 | Standard_Integer dummy, sec; |
376 | Values(dummy, dummy, dummy, dummy, dummy, sec , dummy, dummy); |
377 | return(sec); |
378 | } |
379 | |
380 | // ---------------------------------------------------------------------- |
381 | // millisecond : Return the millisecond of a date |
382 | // ~~~~~~~~~~~ |
383 | // ---------------------------------------------------------------------- |
384 | |
385 | Standard_Integer Quantity_Date::MilliSecond(){ |
386 | Standard_Integer dummy, msec; |
387 | Values(dummy, dummy, dummy, dummy, dummy, dummy, msec, dummy); |
388 | return(msec); |
389 | } |
390 | |
391 | // ---------------------------------------------------------------------- |
392 | // Day : Return the day of a date |
393 | // ~~~ |
394 | // ---------------------------------------------------------------------- |
395 | |
396 | Standard_Integer Quantity_Date::MicroSecond(){ |
397 | Standard_Integer dummy, msec; |
398 | Values(dummy, dummy, dummy, dummy, dummy, dummy, dummy, msec); |
399 | return(msec); |
400 | } |
401 | |
402 | // ---------------------------------------------------------------------- |
403 | // IsEarlier : Return true if the date is earlier than an other date |
404 | // ~~~~~~~~~ |
405 | // ---------------------------------------------------------------------- |
406 | |
407 | Standard_Boolean Quantity_Date::IsEarlier(const Quantity_Date& other)const{ |
408 | if (mySec < other.mySec) return Standard_True; |
409 | else if (mySec > other.mySec) return Standard_False; |
410 | else return ( ( myUSec < other.myUSec ) ? Standard_True : Standard_False); |
411 | } |
412 | |
413 | // ---------------------------------------------------------------------- |
414 | // IsLater : Return true if the date is later than an other date |
415 | // ~~~~~~~ |
416 | // ---------------------------------------------------------------------- |
417 | |
418 | Standard_Boolean Quantity_Date::IsLater(const Quantity_Date& other)const{ |
419 | if (mySec > other.mySec) return Standard_True; |
420 | else if (mySec < other.mySec) return Standard_False; |
421 | else return ( ( myUSec > other.myUSec ) ? Standard_True : Standard_False); |
422 | } |
423 | |
424 | |
425 | // ---------------------------------------------------------------------- |
426 | // IsEqual : Return true if the date is the same than an other date |
427 | // ~~~~~~~ |
428 | // ---------------------------------------------------------------------- |
429 | |
430 | Standard_Boolean Quantity_Date::IsEqual(const Quantity_Date& other)const{ |
431 | return ( ( myUSec == other.myUSec && |
432 | mySec == other.mySec ) ? Standard_True : Standard_False); |
433 | } |
434 | |