1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 // -------------------------------------------------------------
16 // C matra datavision 1993
17 // Updated :
18 // -------------------------------------------------------------
19
20 #include <Quantity_Date.hxx>
21 #include <Quantity_DateDefinitionError.hxx>
22 #include <Quantity_Period.hxx>
23 #include <Standard_OutOfRange.hxx>
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
Quantity_Date()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
IsValid(const Standard_Integer mm,const Standard_Integer dd,const Standard_Integer yy,const Standard_Integer hh,const Standard_Integer mn,const Standard_Integer ss,const Standard_Integer mis,const Standard_Integer mics)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
Quantity_Date(const Standard_Integer mm,const Standard_Integer dd,const Standard_Integer yy,const Standard_Integer hh,const Standard_Integer mn,const Standard_Integer ss,const Standard_Integer mis,const Standard_Integer mics)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
SetValues(const Standard_Integer mm,const Standard_Integer dd,const Standard_Integer yy,const Standard_Integer hh,const Standard_Integer mn,const Standard_Integer ss,const Standard_Integer mis,const Standard_Integer mics)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))
130 throw Quantity_DateDefinitionError("Quantity_Date::Quantity_Date invalid parameters");
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
Values(Standard_Integer & mm,Standard_Integer & dd,Standard_Integer & yy,Standard_Integer & hh,Standard_Integer & mn,Standard_Integer & ss,Standard_Integer & mis,Standard_Integer & mics) const167 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
Difference(const Quantity_Date & OtherDate)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
Subtract(const Quantity_Period & During)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 )
289 throw Quantity_DateDefinitionError(
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 // ----------------------------------------------------------------------
Add(const Quantity_Period & During)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 // ----------------------------------------------------------------------
Year()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 // ----------------------------------------------------------------------
Month()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
Day()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
Hour()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
Minute()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
Second()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
MilliSecond()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
MicroSecond()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
IsEarlier(const Quantity_Date & other) const407 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
IsLater(const Quantity_Date & other) const418 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
IsEqual(const Quantity_Date & other) const430 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
435