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