source: XMLIO_V2/external/src/POCO/Foundation.save/DateTime.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 10.6 KB
Line 
1//
2// DateTime.cpp
3//
4// $Id: //poco/1.3/Foundation/src/DateTime.cpp#4 $
5//
6// Library: Foundation
7// Package: DateTime
8// Module:  DateTime
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include "Poco/DateTime.h"
38#include "Poco/Timespan.h"
39#include <algorithm>
40#include <cmath>
41
42
43namespace Poco {
44
45
46inline double DateTime::toJulianDay(Timestamp::UtcTimeVal utcTime)
47{
48        double utcDays = double(utcTime)/864000000000.0;
49        return utcDays + 2299160.5; // first day of Gregorian reform (Oct 15 1582)
50}
51
52
53inline Timestamp::UtcTimeVal DateTime::toUtcTime(double julianDay)
54{
55        return Timestamp::UtcTimeVal((julianDay - 2299160.5)*864000000000.0);
56}
57
58
59DateTime::DateTime()
60{
61        Timestamp now;
62        _utcTime = now.utcTime();
63        computeGregorian(julianDay());
64        computeDaytime();
65}
66
67
68DateTime::DateTime(const Timestamp& timestamp):
69        _utcTime(timestamp.utcTime())
70{
71        computeGregorian(julianDay());
72        computeDaytime();
73}
74
75       
76DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond):
77        _year(year),
78        _month(month),
79        _day(day),
80        _hour(hour),
81        _minute(minute),
82        _second(second),
83        _millisecond(millisecond),
84        _microsecond(microsecond)
85{
86        poco_assert (year >= 0 && year <= 9999);
87        poco_assert (month >= 1 && month <= 12);
88        poco_assert (day >= 1 && day <= daysOfMonth(year, month));
89        poco_assert (hour >= 0 && hour <= 23);
90        poco_assert (minute >= 0 && minute <= 59);
91        poco_assert (second >= 0 && second <= 59);
92        poco_assert (millisecond >= 0 && millisecond <= 999);
93        poco_assert (microsecond >= 0 && microsecond <= 999);
94       
95        _utcTime = toUtcTime(toJulianDay(year, month, day)) + 10*(hour*Timespan::HOURS + minute*Timespan::MINUTES + second*Timespan::SECONDS + millisecond*Timespan::MILLISECONDS + microsecond);
96}
97
98
99DateTime::DateTime(double julianDay):
100        _utcTime(toUtcTime(julianDay))
101{
102        computeGregorian(julianDay);
103}
104
105
106DateTime::DateTime(Timestamp::UtcTimeVal utcTime, Timestamp::TimeDiff diff):
107        _utcTime(utcTime + diff*10)
108{
109        computeGregorian(julianDay());
110        computeDaytime();
111}
112
113
114DateTime::DateTime(const DateTime& dateTime):
115        _utcTime(dateTime._utcTime),
116        _year(dateTime._year),
117        _month(dateTime._month),
118        _day(dateTime._day),
119        _hour(dateTime._hour),
120        _minute(dateTime._minute),
121        _second(dateTime._second),
122        _millisecond(dateTime._millisecond),
123        _microsecond(dateTime._microsecond)
124{
125}
126
127
128DateTime::~DateTime()
129{
130}
131
132
133DateTime& DateTime::operator = (const DateTime& dateTime)
134{
135        if (&dateTime != this)
136        {
137                _utcTime     = dateTime._utcTime;
138                _year        = dateTime._year;
139                _month       = dateTime._month;
140                _day         = dateTime._day;
141                _hour        = dateTime._hour;
142                _minute      = dateTime._minute;
143                _second      = dateTime._second;
144                _millisecond = dateTime._millisecond;
145                _microsecond = dateTime._microsecond;
146        }
147        return *this;
148}
149
150       
151DateTime& DateTime::operator = (const Timestamp& timestamp)
152{
153        _utcTime = timestamp.utcTime();
154        computeGregorian(julianDay());
155        computeDaytime();
156        return *this;
157}
158
159
160DateTime& DateTime::operator = (double julianDay)
161{
162        _utcTime = toUtcTime(julianDay);
163        computeGregorian(julianDay);
164        return *this;
165}
166
167
168DateTime& DateTime::assign(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
169{
170        poco_assert (year >= 0 && year <= 9999);
171        poco_assert (month >= 1 && month <= 12);
172        poco_assert (day >= 1 && day <= daysOfMonth(year, month));
173        poco_assert (hour >= 0 && hour <= 23);
174        poco_assert (minute >= 0 && minute <= 59);
175        poco_assert (second >= 0 && second <= 59);
176        poco_assert (millisecond >= 0 && millisecond <= 999);
177        poco_assert (microsecond >= 0 && microsecond <= 999);
178
179        _utcTime     = toUtcTime(toJulianDay(year, month, day)) + 10*(hour*Timespan::HOURS + minute*Timespan::MINUTES + second*Timespan::SECONDS + millisecond*Timespan::MILLISECONDS + microsecond);
180        _year        = year;
181        _month       = month;
182        _day         = day;
183        _hour        = hour;
184        _minute      = minute;
185        _second      = second;
186        _millisecond = millisecond;
187        _microsecond = microsecond;
188       
189        return *this;
190}
191
192
193void DateTime::swap(DateTime& dateTime)
194{
195        std::swap(_utcTime, dateTime._utcTime);
196        std::swap(_year, dateTime._year);
197        std::swap(_month, dateTime._month);
198        std::swap(_day, dateTime._day);
199        std::swap(_hour, dateTime._hour);
200        std::swap(_minute, dateTime._minute);
201        std::swap(_second, dateTime._second);
202        std::swap(_millisecond, dateTime._millisecond);
203        std::swap(_microsecond, dateTime._microsecond);
204}
205
206
207int DateTime::dayOfWeek() const
208{
209        return int((std::floor(julianDay() + 1.5))) % 7;
210}
211
212
213int DateTime::dayOfYear() const
214{
215        int doy = 0;
216        for (int month = 1; month < _month; ++month)
217                doy += daysOfMonth(_year, month);
218        doy += _day;
219        return doy;
220}
221
222
223int DateTime::daysOfMonth(int year, int month)
224{
225        poco_assert (month >= 1 && month <= 12);
226
227        static int daysOfMonthTable[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
228       
229        if (month == 2 && isLeapYear(year))
230                return 29;
231        else
232                return daysOfMonthTable[month];
233}
234
235
236bool DateTime::isValid(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
237{
238        return
239                (year >= 0 && year <= 9999) &&
240                (month >= 1 && month <= 12) &&
241                (day >= 1 && day <= daysOfMonth(year, month)) &&
242                (hour >= 0 && hour <= 23) &&
243                (minute >= 0 && minute <= 59) &&
244                (second >= 0 && second <= 59) &&
245                (millisecond >= 0 && millisecond <= 999) &&
246                (microsecond >= 0 && microsecond <= 999);
247}
248
249
250int DateTime::week(int firstDayOfWeek) const
251{
252        poco_assert (firstDayOfWeek >= 0 && firstDayOfWeek <= 6);
253
254        /// find the first firstDayOfWeek.
255        int baseDay = 1;
256        while (DateTime(_year, 1, baseDay).dayOfWeek() != firstDayOfWeek) ++baseDay;
257
258        int doy  = dayOfYear();
259        int offs = baseDay <= 4 ? 0 : 1; 
260        if (doy < baseDay)
261                return offs;
262        else
263                return (doy - baseDay)/7 + 1 + offs;
264}
265
266
267double DateTime::julianDay() const
268{
269        return toJulianDay(_utcTime);
270}
271
272
273DateTime DateTime::operator + (const Timespan& span) const
274{
275        return DateTime(_utcTime, span.totalMicroseconds());
276}
277
278
279DateTime DateTime::operator - (const Timespan& span) const
280{
281        return DateTime(_utcTime, -span.totalMicroseconds());
282}
283
284
285Timespan DateTime::operator - (const DateTime& dateTime) const
286{
287        return Timespan((_utcTime - dateTime._utcTime)/10);
288}
289
290
291DateTime& DateTime::operator += (const Timespan& span)
292{
293        _utcTime += span.totalMicroseconds()*10;
294        computeGregorian(julianDay());
295        computeDaytime();
296        return *this;
297}
298
299
300DateTime& DateTime::operator -= (const Timespan& span)
301{
302        _utcTime -= span.totalMicroseconds()*10;
303        computeGregorian(julianDay());
304        computeDaytime();
305        return *this;
306}
307
308
309void DateTime::makeUTC(int tzd)
310{
311        operator -= (Timespan(((Timestamp::TimeDiff) tzd)*Timespan::SECONDS));
312}
313
314       
315void DateTime::makeLocal(int tzd)
316{
317        operator += (Timespan(((Timestamp::TimeDiff) tzd)*Timespan::SECONDS));
318}
319
320
321double DateTime::toJulianDay(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
322{
323        // lookup table for (153*month - 457)/5 - note that 3 <= month <= 14.
324        static int lookup[] = {-91, -60, -30, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337};
325 
326        // day to double
327        double dday = double(day) + ((double((hour*60 + minute)*60 + second)*1000 + millisecond)*1000 + microsecond)/86400000000.0;
328        if (month < 3)
329        {
330                month += 12;
331                --year;
332        }
333        double dyear = double(year);
334        return dday + lookup[month] + 365*year + std::floor(dyear/4) - std::floor(dyear/100) + std::floor(dyear/400) + 1721118.5;
335}
336
337
338void DateTime::checkLimit(short& lower, short& higher, short limit)
339{
340        if (lower >= limit)
341        {
342                higher += short(lower / limit);
343                lower   = short(lower % limit);
344        }
345}
346
347
348void DateTime::normalize()
349{
350        checkLimit(_microsecond, _millisecond, 1000);
351        checkLimit(_millisecond, _second, 1000);
352        checkLimit(_second, _minute, 60);
353        checkLimit(_minute, _hour, 60);
354        checkLimit(_hour, _day, 24);
355
356        if (_day > daysOfMonth(_year, _month))
357        {
358                _day -= daysOfMonth(_year, _month);
359                if (++_month > 12)
360                {
361                        ++_year;
362                        _month -= 12;
363                }
364        }
365}
366
367
368void DateTime::computeGregorian(double julianDay)
369{
370        double z    = std::floor(julianDay - 1721118.5);
371        double r    = julianDay - 1721118.5 - z;
372        double g    = z - 0.25;
373        double a    = std::floor(g / 36524.25);
374        double b    = a - std::floor(a/4);
375        _year       = short(std::floor((b + g)/365.25));
376        double c    = b + z - std::floor(365.25*_year);
377        _month      = short(std::floor((5*c + 456)/153));
378        double dday = c - std::floor((153.0*_month - 457)/5) + r;
379        _day        = short(dday);
380        if (_month > 12)
381        {
382                ++_year;
383                _month -= 12;
384        }
385        r      *= 24;
386        _hour   = short(std::floor(r));
387        r      -= std::floor(r);
388        r      *= 60;
389        _minute = short(std::floor(r));
390        r      -= std::floor(r);
391        r      *= 60;
392        _second = short(std::floor(r));
393        r      -= std::floor(r);
394        r      *= 1000;
395        _millisecond = short(std::floor(r));
396        r      -= std::floor(r);
397        r      *= 1000;
398        _microsecond = short(r + 0.5);
399
400        normalize();
401
402        poco_assert_dbg (_month >= 1 && _month <= 12);
403        poco_assert_dbg (_day >= 1 && _day <= daysOfMonth(_year, _month));
404        poco_assert_dbg (_hour >= 0 && _hour <= 23);
405        poco_assert_dbg (_minute >= 0 && _minute <= 59);
406        poco_assert_dbg (_second >= 0 && _second <= 59);
407        poco_assert_dbg (_millisecond >= 0 && _millisecond <= 999);
408        poco_assert_dbg (_microsecond >= 0 && _microsecond <= 999);
409}
410
411
412void DateTime::computeDaytime()
413{
414        Timespan span(_utcTime/10);
415        _hour        = span.hours();
416        _minute      = span.minutes();
417        _second      = span.seconds();
418        _millisecond = span.milliseconds();
419        _microsecond = span.microseconds();
420}
421
422
423} // namespace Poco
Note: See TracBrowser for help on using the repository browser.