xref: /aoo41x/main/tools/source/datetime/datetime.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_tools.hxx"
30 
31 #include <tools/datetime.hxx>
32 #include <rtl/math.hxx>
33 
34 /*************************************************************************
35 |*
36 |*    DateTime::IsBetween()
37 |*
38 |*    Beschreibung      DATETIME.SDW
39 |*    Ersterstellung    TH 18.05.92
40 |*    Letzte Aenderung  TH 18.05.92
41 |*
42 *************************************************************************/
43 
44 sal_Bool DateTime::IsBetween( const DateTime& rFrom,
45                           const DateTime& rTo ) const
46 {
47     if ( (*this >= rFrom) && (*this <= rTo) )
48         return sal_True;
49     else
50         return sal_False;
51 }
52 
53 /*************************************************************************
54 |*
55 |*    DateTime::operator >()
56 |*
57 |*    Beschreibung      DATETIME.SDW
58 |*    Ersterstellung    TH 18.05.92
59 |*    Letzte Aenderung  TH 18.05.92
60 |*
61 *************************************************************************/
62 
63 sal_Bool DateTime::operator >( const DateTime& rDateTime ) const
64 {
65     if ( (Date::operator>( rDateTime )) ||
66          (Date::operator==( rDateTime ) && Time::operator>( rDateTime )) )
67         return sal_True;
68     else
69         return sal_False;
70 }
71 
72 /*************************************************************************
73 |*
74 |*    DateTime::operator <()
75 |*
76 |*    Beschreibung      DATETIME.SDW
77 |*    Ersterstellung    TH 18.05.92
78 |*    Letzte Aenderung  TH 18.05.92
79 |*
80 *************************************************************************/
81 
82 sal_Bool DateTime::operator <( const DateTime& rDateTime ) const
83 {
84     if ( (Date::operator<( rDateTime )) ||
85          (Date::operator==( rDateTime ) && Time::operator<( rDateTime )) )
86         return sal_True;
87     else
88         return sal_False;
89 }
90 
91 /*************************************************************************
92 |*
93 |*    DateTime::operator >=()
94 |*
95 |*    Beschreibung      DATETIME.SDW
96 |*    Ersterstellung    TH 18.05.92
97 |*    Letzte Aenderung  TH 18.05.92
98 |*
99 *************************************************************************/
100 
101 sal_Bool DateTime::operator >=( const DateTime& rDateTime ) const
102 {
103     if ( (Date::operator>( rDateTime )) ||
104          (Date::operator==( rDateTime ) && Time::operator>=( rDateTime )) )
105         return sal_True;
106     else
107         return sal_False;
108 }
109 
110 /*************************************************************************
111 |*
112 |*    DateTime::operator <=()
113 |*
114 |*    Beschreibung      DATETIME.SDW
115 |*    Ersterstellung    TH 18.05.92
116 |*    Letzte Aenderung  TH 18.05.92
117 |*
118 *************************************************************************/
119 
120 sal_Bool DateTime::operator <=( const DateTime& rDateTime ) const
121 {
122     if ( (Date::operator<( rDateTime )) ||
123          (Date::operator==( rDateTime ) && Time::operator<=( rDateTime )) )
124         return sal_True;
125     else
126         return sal_False;
127 }
128 
129 /*************************************************************************
130 |*
131 |*    DateTime::GetSecFromDateTime()
132 |*
133 |*    Beschreibung      DATETIME.SDW
134 |*    Ersterstellung    TH 02.10.96
135 |*    Letzte Aenderung  TH 02.10.96
136 |*
137 *************************************************************************/
138 
139 long DateTime::GetSecFromDateTime( const Date& rDate ) const
140 {
141     if ( Date::operator<( rDate ) )
142         return 0;
143     else
144     {
145         long nSec = Date( *this ) - rDate;
146         nSec *= 24UL*60*60;
147         long nHour = GetHour();
148         long nMin  = GetMin();
149         nSec += (nHour*3600)+(nMin*60)+GetSec();
150         return nSec;
151     }
152 }
153 
154 /*************************************************************************
155 |*
156 |*    DateTime::GetSecFromDateTime()
157 |*
158 |*    Beschreibung      DATETIME.SDW
159 |*    Ersterstellung    TH 02.10.96
160 |*    Letzte Aenderung  TH 02.10.96
161 |*
162 *************************************************************************/
163 
164 void DateTime::MakeDateTimeFromSec( const Date& rDate, sal_uIntPtr nSec )
165 {
166     long nDays = nSec / (24UL*60*60);
167 	((Date*)this)->operator=( rDate );
168     nSec -= nDays * (24UL*60*60);
169 	sal_uInt16 nMin = (sal_uInt16)(nSec / 60);
170 	nSec -= nMin * 60;
171     ((Time*)this)->operator=( Time( 0, nMin, (sal_uInt16)nSec ) );
172     operator+=( nDays );
173 }
174 
175 /*************************************************************************
176 |*
177 |*    DateTime::operator +=()
178 |*
179 |*    Beschreibung      DATETIME.SDW
180 |*    Ersterstellung    TH 02.10.96
181 |*    Letzte Aenderung  TH 02.10.96
182 |*
183 *************************************************************************/
184 
185 DateTime& DateTime::operator +=( const Time& rTime )
186 {
187     Time aTime = *this;
188     aTime += rTime;
189     sal_uInt16 nHours = aTime.GetHour();
190     if ( aTime.GetTime() > 0 )
191     {
192         while ( nHours >= 24 )
193         {
194             Date::operator++();
195             nHours -= 24;
196         }
197         aTime.SetHour( nHours );
198     }
199     else if ( aTime.GetTime() != 0 )
200     {
201         while ( nHours >= 24 )
202         {
203             Date::operator--();
204             nHours -= 24;
205         }
206         Date::operator--();
207         aTime = Time( 24, 0, 0 )+aTime;
208     }
209     Time::operator=( aTime );
210 
211     return *this;
212 }
213 
214 /*************************************************************************
215 |*
216 |*    DateTime::operator -=()
217 |*
218 |*    Beschreibung      DATETIME.SDW
219 |*    Ersterstellung    TH 02.10.96
220 |*    Letzte Aenderung  TH 02.10.96
221 |*
222 *************************************************************************/
223 
224 DateTime& DateTime::operator -=( const Time& rTime )
225 {
226     Time aTime = *this;
227     aTime -= rTime;
228     sal_uInt16 nHours = aTime.GetHour();
229     if ( aTime.GetTime() > 0 )
230     {
231         while ( nHours >= 24 )
232         {
233             Date::operator++();
234             nHours -= 24;
235         }
236         aTime.SetHour( nHours );
237     }
238     else if ( aTime.GetTime() != 0 )
239     {
240         while ( nHours >= 24 )
241         {
242             Date::operator--();
243             nHours -= 24;
244         }
245         Date::operator--();
246         aTime = Time( 24, 0, 0 )+aTime;
247     }
248     Time::operator=( aTime );
249 
250     return *this;
251 }
252 
253 /*************************************************************************
254 |*
255 |*    DateTime::operator+()
256 |*
257 |*    Beschreibung      DATETIME.SDW
258 |*    Ersterstellung    TH 02.10.96
259 |*    Letzte Aenderung  TH 02.10.96
260 |*
261 *************************************************************************/
262 
263 DateTime operator +( const DateTime& rDateTime, long nDays )
264 {
265     DateTime aDateTime( rDateTime );
266     aDateTime += nDays;
267     return aDateTime;
268 }
269 
270 /*************************************************************************
271 |*
272 |*    DateTime::operator-()
273 |*
274 |*    Beschreibung      DATETIME.SDW
275 |*    Ersterstellung    TH 02.10.96
276 |*    Letzte Aenderung  TH 02.10.96
277 |*
278 *************************************************************************/
279 
280 DateTime operator -( const DateTime& rDateTime, long nDays )
281 {
282     DateTime aDateTime( rDateTime );
283     aDateTime -= nDays;
284     return aDateTime;
285 }
286 
287 /*************************************************************************
288 |*
289 |*    DateTime::operator+()
290 |*
291 |*    Beschreibung      DATETIME.SDW
292 |*    Ersterstellung    TH 02.10.96
293 |*    Letzte Aenderung  TH 02.10.96
294 |*
295 *************************************************************************/
296 
297 DateTime operator +( const DateTime& rDateTime, const Time& rTime )
298 {
299     DateTime aDateTime( rDateTime );
300     aDateTime += rTime;
301     return aDateTime;
302 }
303 
304 /*************************************************************************
305 |*
306 |*    DateTime::operator-()
307 |*
308 |*    Beschreibung      DATETIME.SDW
309 |*    Ersterstellung    TH 02.10.96
310 |*    Letzte Aenderung  TH 02.10.96
311 |*
312 *************************************************************************/
313 
314 DateTime operator -( const DateTime& rDateTime, const Time& rTime )
315 {
316     DateTime aDateTime( rDateTime );
317     aDateTime -= rTime;
318     return aDateTime;
319 }
320 
321 /*************************************************************************
322 |*
323 |*    DateTime::operator +=( double )
324 |*
325 *************************************************************************/
326 
327 DateTime& DateTime::operator +=( double fTimeInDays )
328 {
329 	double fInt, fFrac;
330 	if ( fTimeInDays < 0.0 )
331 	{
332 		fInt = ::rtl::math::approxCeil( fTimeInDays );
333 		fFrac = fInt <= fTimeInDays ? 0.0 : fTimeInDays - fInt;
334 	}
335 	else
336 	{
337 		fInt = ::rtl::math::approxFloor( fTimeInDays );
338 		fFrac = fInt >= fTimeInDays ? 0.0 : fTimeInDays - fInt;
339 	}
340 	Date::operator+=( long(fInt) );		// full days
341 	if ( fFrac )
342 	{
343 		Time aTime(0);	// default ctor calls system time, we don't need that
344 		fFrac *= 24UL * 60 * 60 * 1000;		// time expressed in milliseconds
345 		aTime.MakeTimeFromMS( long(fFrac) );	// method handles negative ms
346 		operator+=( aTime );
347 	}
348 	return *this;
349 }
350 
351 /*************************************************************************
352 |*
353 |*    DateTime::operator +( double )
354 |*
355 *************************************************************************/
356 
357 DateTime operator +( const DateTime& rDateTime, double fTimeInDays )
358 {
359     DateTime aDateTime( rDateTime );
360 	aDateTime += fTimeInDays;
361 	return aDateTime;
362 }
363 
364 /*************************************************************************
365 |*
366 |*    DateTime::operator -()
367 |*
368 *************************************************************************/
369 
370 double operator -( const DateTime& rDateTime1, const DateTime& rDateTime2 )
371 {
372 	long nDays = (const Date&) rDateTime1 - (const Date&) rDateTime2;
373 	long nTime = rDateTime1.GetMSFromTime() - rDateTime2.GetMSFromTime();
374 	if ( nTime )
375 	{
376 		double fTime = double(nTime);
377 		fTime /= 24UL * 60 * 60 * 1000;	// convert from milliseconds to fraction
378 		if ( nDays < 0 && fTime > 0.0 )
379 			fTime = 1.0 - fTime;
380 		return double(nDays) + fTime;
381 	}
382 	return double(nDays);
383 }
384 
385 void DateTime::GetWin32FileDateTime( sal_uInt32 & rLower, sal_uInt32 & rUpper )
386 {
387     const sal_Int64 a100nPerSecond = SAL_CONST_INT64( 10000000 );
388     const sal_Int64 a100nPerDay = a100nPerSecond * sal_Int64( 60 * 60 * 24 );
389 
390     sal_Int64 nYears = GetYear() - 1601;
391     sal_Int64 nDays =
392         nYears * 365 +
393         nYears / 4 - nYears / 100 + nYears / 400 +
394         GetDayOfYear() - 1;
395 
396     sal_Int64 aTime =
397         a100nPerDay * nDays +
398         a100nPerSecond * (
399                 sal_Int64( GetSec() ) +
400                 60 * sal_Int64( GetMin() ) +
401                 60 * 60 * sal_Int64( GetHour() ) );
402 
403     rLower = sal_uInt32( aTime % SAL_CONST_UINT64( 0x100000000 ) );
404     rUpper = sal_uInt32( aTime / SAL_CONST_UINT64( 0x100000000 ) );
405 }
406 
407 DateTime DateTime::CreateFromWin32FileDateTime( const sal_uInt32 & rLower, const sal_uInt32 & rUpper )
408 {
409     const sal_Int64 a100nPerSecond = SAL_CONST_INT64( 10000000 );
410     const sal_Int64 a100nPerDay = a100nPerSecond * sal_Int64( 60 * 60 * 24 );
411 
412     sal_Int64 aTime = sal_Int64(
413             sal_uInt64( rUpper ) * SAL_CONST_UINT64( 0x100000000 ) +
414             sal_uInt64( rLower ) );
415 
416     sal_Int64 nDays = aTime / a100nPerDay;
417     sal_Int64 nYears =
418         ( nDays -
419           ( nDays / ( 4 * 365 ) ) +
420           ( nDays / ( 100 * 365 ) ) -
421           ( nDays / ( 400 * 365 ) ) ) / 365;
422     nDays -= nYears * 365 + nYears / 4 - nYears / 100 + nYears / 400;
423 
424     sal_uInt16 nMonths = 0;
425     for( sal_Int64 nDaysCount = nDays; nDaysCount >= 0; )
426     {
427         nDays = nDaysCount;
428         nMonths ++;
429         nDaysCount -= Date(
430             1, nMonths, sal::static_int_cast< sal_uInt16 >(1601 + nYears) ).
431             GetDaysInMonth();
432     }
433 
434     Date _aDate(
435         (sal_uInt16)( nDays + 1 ), nMonths,
436         sal::static_int_cast< sal_uInt16 >(nYears + 1601) );
437     Time _aTime( sal_uIntPtr( ( aTime / ( a100nPerSecond * 60 * 60 ) ) % sal_Int64( 24 ) ),
438             sal_uIntPtr( ( aTime / ( a100nPerSecond * 60 ) ) % sal_Int64( 60 ) ),
439             sal_uIntPtr( ( aTime / ( a100nPerSecond ) ) % sal_Int64( 60 ) ) );
440 
441     return DateTime( _aDate, _aTime );
442 }
443