sync with tizen_2.0
[platform/framework/native/appfw.git] / src / base / FBaseDateTime.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FBaseDateTime.cpp
20  * @brief               This file contains implementation of DateTime class
21  */
22
23 #include <stdlib.h>
24 #include <wchar.h>
25 #include <FBaseDateTime.h>
26 #include <FBaseResult.h>
27 #include <FBaseSysLog.h>
28 #include <unique_ptr.h>
29
30
31 namespace Tizen { namespace Base
32 {
33
34 enum DateTimeLimits
35 {
36         MIN_YEAR = 1,
37         MIN_MONTH = 1,
38         MIN_DAY = 1,
39         MIN_HOUR = 0,
40         MIN_MINUTE = 0,
41         MIN_SECOND = 0,
42         _MAX_YEAR = 9999,
43         MAX_MONTH = 12,
44         MAX_DAY = 31,
45         MAX_HOUR = 23,
46         MAX_MINUTE = 59,
47         MAX_SECOND = 59,
48         NUM_OF_SEC_IN_DAY = 86400,
49         NUM_OF_SEC_IN_HOUR = 3600,
50         NUM_OF_SEC_IN_MINUTE = 60,
51         NUM_OF_MILLISEC_IN_DAY = 86400000LL,
52         NUM_OF_MILLISEC_IN_HOUR = 3600000LL,
53         NUM_OF_MILLISEC_IN_MINUTE = 60000LL
54 };
55
56 static const long SEC_IN_A_DAY = (24L * 60L * 60L);
57 static const long long MINIMUM_VALUE_IN_SEC = 86400LL;
58 static const int DAYS_IN_LEAP_YEAR[] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
59 static const int DAYS[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
60
61 DateTime::DateTime(void)
62         : __pDateTimeImpl(null)
63 {
64         SetValue(MIN_YEAR, MIN_MONTH, MIN_DAY, MIN_HOUR, MIN_MINUTE, MIN_SECOND);
65 }
66
67 DateTime::DateTime(const DateTime& value)
68         : __pDateTimeImpl(null)
69 {
70         SetValue(value);
71 }
72
73 DateTime::~DateTime(void)
74 {
75 }
76
77 result
78 DateTime::SetValue(const TimeSpan& value)
79 {
80         long long total = (long long) (value.GetTicks() / 1000) + MINIMUM_VALUE_IN_SEC;
81         SysTryReturn(NID_BASE, total >= NUM_OF_SEC_IN_DAY, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
82                 "[%s] The value of the argument is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE));
83
84         long long maxSeconds = (long long) (DateTime::GetMaxValue().GetTime().GetTicks() / 1000) + MINIMUM_VALUE_IN_SEC;
85         SysTryReturn(NID_BASE, total <= maxSeconds, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
86                 "[%s] The value of the argument is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE));
87
88         return ConvertSecondsToDate(total, &__dateTime);
89 }
90
91 void
92 DateTime::SetValue(const DateTime& value)
93 {
94         __dateTime.year = value.__dateTime.year;
95         __dateTime.month = value.__dateTime.month;
96         __dateTime.day = value.__dateTime.day;
97         __dateTime.hour = value.__dateTime.hour;
98         __dateTime.minute = value.__dateTime.minute;
99         __dateTime.second = value.__dateTime.second;
100 }
101
102 result
103 DateTime::SetValue(int year, int month, int day, int hour, int minute, int second)
104 {
105         SysTryReturn(NID_BASE, 
106                 ((year >= MIN_YEAR && year <= _MAX_YEAR) &&
107                  (month >= MIN_MONTH && month <= MAX_MONTH) &&
108                  (hour >= MIN_HOUR && hour <= MAX_HOUR) &&
109                  (minute >= MIN_MINUTE && minute <= MAX_MINUTE) &&
110                  (second >= MIN_SECOND && second <= MAX_SECOND)),
111                 E_OUT_OF_RANGE, E_OUT_OF_RANGE,
112                 "[%s] One of the year(%d), month(%d), day(%d), hour(%d), minute(%d), and second(%d) is in out of allowable range.",
113                 GetErrorMessage(E_OUT_OF_RANGE), year, month, day, hour, minute, second);
114
115         int daysInMonth = 0;
116         result r = GetDaysInMonth(year, month, daysInMonth);
117         SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
118         SysTryReturn(NID_BASE, (day >= MIN_DAY && day <= daysInMonth), E_OUT_OF_RANGE, E_OUT_OF_RANGE,
119                 ("[%s] day is in out of allowable range."), GetErrorMessage(E_OUT_OF_RANGE));
120
121         __dateTime.year = year;
122         __dateTime.month = month;
123         __dateTime.day = day;
124         __dateTime.hour = hour;
125         __dateTime.minute = minute;
126         __dateTime.second = second;
127
128         return(E_SUCCESS);
129 }
130
131 DateTime&
132 DateTime::operator =(const DateTime& rhs)
133 {
134         if (&rhs != this)
135         {
136                 SetValue(rhs);
137         }
138
139         return(*this);
140 }
141
142 bool
143 DateTime::operator ==(const DateTime& rhs) const
144 {
145         return((__dateTime.year == rhs.__dateTime.year) && (__dateTime.month == rhs.__dateTime.month)
146                         && (__dateTime.day == rhs.__dateTime.day) && (__dateTime.hour == rhs.__dateTime.hour) &&
147                         (__dateTime.minute == rhs.__dateTime.minute) && (__dateTime.second == rhs.__dateTime.second));
148 }
149
150 bool
151 DateTime::operator !=(const DateTime& rhs) const
152 {
153         return !(*this == rhs);
154 }
155
156 bool
157 DateTime::operator <(const DateTime& rhs) const
158 {
159         if (__dateTime.year < rhs.__dateTime.year)
160         {
161                 return true;
162         }
163         if (__dateTime.year > rhs.__dateTime.year)
164         {
165                 return false;
166         }
167         if (__dateTime.month < rhs.__dateTime.month)
168         {
169                 return true;
170         }
171         if (__dateTime.month > rhs.__dateTime.month)
172         {
173                 return false;
174         }
175         if (__dateTime.day < rhs.__dateTime.day)
176         {
177                 return true;
178         }
179         if (__dateTime.day > rhs.__dateTime.day)
180         {
181                 return false;
182         }
183         if (__dateTime.hour < rhs.__dateTime.hour)
184         {
185                 return true;
186         }
187         if (__dateTime.hour > rhs.__dateTime.hour)
188         {
189                 return false;
190         }
191         if (__dateTime.minute < rhs.__dateTime.minute)
192         {
193                 return true;
194         }
195         if (__dateTime.minute > rhs.__dateTime.minute)
196         {
197                 return false;
198         }
199         if (__dateTime.second < rhs.__dateTime.second)
200         {
201                 return true;
202         }
203
204         return false;
205 }
206
207 bool
208 DateTime::operator >(const DateTime& rhs) const
209 {
210         if (__dateTime.year > rhs.__dateTime.year)
211         {
212                 return true;
213         }
214         if (__dateTime.year < rhs.__dateTime.year)
215         {
216                 return false;
217         }
218         if (__dateTime.month > rhs.__dateTime.month)
219         {
220                 return true;
221         }
222         if (__dateTime.month < rhs.__dateTime.month)
223         {
224                 return false;
225         }
226         if (__dateTime.day > rhs.__dateTime.day)
227         {
228                 return true;
229         }
230         if (__dateTime.day < rhs.__dateTime.day)
231         {
232                 return false;
233         }
234         if (__dateTime.hour > rhs.__dateTime.hour)
235         {
236                 return true;
237         }
238         if (__dateTime.hour < rhs.__dateTime.hour)
239         {
240                 return false;
241         }
242         if (__dateTime.minute > rhs.__dateTime.minute)
243         {
244                 return true;
245         }
246         if (__dateTime.minute < rhs.__dateTime.minute)
247         {
248                 return false;
249         }
250         if (__dateTime.second > rhs.__dateTime.second)
251         {
252                 return true;
253         }
254         return false;
255 }
256
257 bool
258 DateTime::operator <=(const DateTime& rhs) const
259 {
260         return((*this == rhs) || (*this < rhs));
261 }
262
263 bool
264 DateTime::operator >=(const DateTime& rhs) const
265 {
266         return((*this == rhs) || (*this > rhs));
267 }
268
269 result
270 DateTime::Add(const TimeSpan& t)
271 {
272
273         long long seconds = ConvertDateToSeconds(&__dateTime);
274         long long total = (long long) (t.GetTicks() / 1000) + seconds;
275
276         SysTryReturn(NID_BASE, total >= NUM_OF_SEC_IN_DAY, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
277                 "[%s] The value of the argument is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE));
278
279         long long maxSeconds = ConvertDateToSeconds(&(DateTime::GetMaxValue().__dateTime));
280         SysTryReturn(NID_BASE, total <= maxSeconds, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
281                 "[%s] The value of the argument is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE));
282
283         result r = ConvertSecondsToDate(total, &__dateTime);
284         if (r != E_SUCCESS)
285         {
286                 SysLogException(NID_BASE, r, "[%s] Propagating.", GetErrorMessage(r));
287         }
288
289         return r;
290 }
291
292 result
293 DateTime::AddDays(int days)
294 {
295         TimeSpan ts(days * NUM_OF_SEC_IN_DAY * 1000LL);
296
297         result r = Add(ts);
298         if (IsFailed(r))
299         {
300                 SysLogException(NID_BASE, r, "[%s] Propagating.", GetErrorMessage(r));
301         }
302
303         return r;
304 }
305
306 result
307 DateTime::AddHours(int hours)
308 {
309         TimeSpan ts(hours * NUM_OF_SEC_IN_HOUR * 1000LL);
310
311         result r = Add(ts);
312         if (IsFailed(r))
313         {
314                 SysLogException(NID_BASE, r, "[%s] Propagating.", GetErrorMessage(r));
315         }
316
317         return r;
318 }
319
320 result
321 DateTime::AddMinutes(int minutes)
322 {
323         TimeSpan ts(minutes * NUM_OF_SEC_IN_MINUTE * 1000LL);
324
325         result r = Add(ts);
326         if (IsFailed(r))
327         {
328                 SysLogException(NID_BASE, r, "[%s] Propagating.", GetErrorMessage(r));
329         }
330
331         return r;
332 }
333
334 result
335 DateTime::AddMonths(int months)
336 {
337         DateTime tmp;
338         tmp.SetValue(*this);
339
340         tmp.__dateTime.year += months / MAX_MONTH;
341
342         int tempMonth = tmp.__dateTime.month + months % MAX_MONTH;
343         if (tempMonth > MAX_MONTH)
344         {
345                 tmp.__dateTime.year++;
346                 tmp.__dateTime.month = tempMonth - MAX_MONTH;
347         }
348         else if (tempMonth < 0)
349         {
350                 tmp.__dateTime.year--;
351                 tmp.__dateTime.month = MAX_MONTH + tempMonth;
352         }
353         else if (tempMonth == 0)
354         {
355                 tmp.__dateTime.year--;
356                 tmp.__dateTime.month = MAX_MONTH;
357         }
358         else
359         {
360                 tmp.__dateTime.month += months % MAX_MONTH;
361         }
362
363         // Check the days in Month
364         if (tmp.__dateTime.month != 2)      // Not Feb
365         {
366                 if (tmp.__dateTime.day == 31)
367                 {
368                         result r = SetValue(tmp.__dateTime.year, tmp.__dateTime.month, tmp.__dateTime.day);
369                         if (IsFailed(r))
370                         {
371                                 r = tmp.AddDays(-1);
372                                 SysTryReturn(NID_BASE, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
373                         }
374                 }
375         }
376         else                                // Feb
377         {
378                 if (tmp.__dateTime.day > 28)
379                 {
380                         if (tmp.IsLeapYear())
381                         {
382                                 tmp.__dateTime.day = 29;
383                         }
384                         else
385                         {
386                                 tmp.__dateTime.day = 28;
387                         }
388                 }
389
390         }
391
392         SysTryReturn(NID_BASE, (tmp <= DateTime::GetMaxValue()) && (tmp >= DateTime::GetMinValue()), E_OUT_OF_RANGE,
393                 E_OUT_OF_RANGE, "[%s] The value of the argument is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE));
394
395         SetValue(tmp);
396
397         return E_SUCCESS;
398 }
399
400 result
401 DateTime::AddSeconds(int seconds)
402 {
403         TimeSpan ts(seconds * 1000LL);
404
405         result r = Add(ts);
406         if (IsFailed(r))
407         {
408                 SysLogException(NID_BASE, r, "[%s] Propagating.", GetErrorMessage(r));
409         }
410
411         return r;
412 }
413
414 result
415 DateTime::AddYears(int years)
416 {
417         DateTime tmp;
418         tmp.SetValue(*this);
419
420         int sum = years + tmp.__dateTime.year;
421
422         SysTryReturn(NID_BASE, (sum >= MIN_YEAR && sum <= _MAX_YEAR), E_OUT_OF_RANGE, E_OUT_OF_RANGE,
423                 "[%s] The years(%d) + current year(%d) MUST be within the %d and %d (inclusive).",
424                 GetErrorMessage(E_OUT_OF_RANGE), years, __dateTime.year, MIN_YEAR, _MAX_YEAR);
425
426         tmp.__dateTime.year = sum;
427
428         // Check the days in Month
429         if (tmp.__dateTime.month == 2)      // Feb
430         {
431                 if (tmp.__dateTime.day > 28)
432                 {
433                         if (tmp.IsLeapYear())       // Check the leap year
434                         {
435                                 tmp.__dateTime.day = 29;
436                         }
437                         else
438                         {
439                                 tmp.__dateTime.day = 28;
440                         }
441                 }
442         }
443
444         SetValue(tmp);
445
446         return E_SUCCESS;
447 }
448
449 int
450 DateTime::Compare(const DateTime& dt1, const DateTime& dt2)
451 {
452         if (dt1 > dt2)
453         {
454                 return 1;
455         }
456         else if (dt1 < dt2)
457         {
458                 return -1;
459         }
460         else
461         {
462                 return(0);
463         }
464 }
465
466 int
467 DateTime::CompareTo(const DateTime& value) const
468 {
469         return DateTime::Compare(*this, value);
470 }
471
472 bool
473 DateTime::Equals(const Object& obj) const
474 {
475         const DateTime* pOther = dynamic_cast <const DateTime*>(&obj);
476         if (pOther == null)
477         {
478                 return false;
479         }
480
481         return(*this == *pOther);
482 }
483
484 int
485 DateTime::GetHashCode(void) const
486 {
487         TimeSpan t = GetTime();
488         int hash = t.GetHashCode();
489         return(hash ^ (hash >> 16));
490 }
491
492 TimeSpan
493 DateTime::GetTimeOfDay(void) const
494 {
495         long long total = ConvertDateToSeconds(&__dateTime);
496
497         TmDateTime midnight;
498         midnight.year = __dateTime.year;
499         midnight.month = __dateTime.month;
500         midnight.day = __dateTime.day;
501         midnight.hour = MIN_HOUR;
502         midnight.minute = MIN_MINUTE;
503         midnight.second = MIN_SECOND;
504
505         long long since = ConvertDateToSeconds(&midnight);
506
507         long long span = total - since;
508
509         return(TimeSpan(span * 1000));
510 }
511
512 result
513 DateTime::GetDaysInMonth(int year, int month, int& days)
514 {
515         const static int daysInMonth[] = { 0xFF, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
516
517         SysTryReturn(NID_BASE, (year >= MIN_YEAR && year <= _MAX_YEAR), E_OUT_OF_RANGE, E_OUT_OF_RANGE,
518                 "[%s] The year(%d) MUST be within the %d and %d (inclusive).", GetErrorMessage(E_OUT_OF_RANGE),
519                 year, MIN_YEAR, _MAX_YEAR);
520         SysTryReturn(NID_BASE, (month >= MIN_MONTH && month <= MAX_MONTH), E_OUT_OF_RANGE, E_OUT_OF_RANGE,
521                 "[%s] The month(%d) MUST be within the %d and %d (inclusive).", GetErrorMessage(E_OUT_OF_RANGE),
522                 month, MIN_MONTH, MAX_MONTH);
523
524         if (DateTime::IsLeapYear(year) && month == 2)
525         {
526                 days = daysInMonth[month] + 1;
527         }
528         else
529         {
530                 days = (daysInMonth[month]);
531         }
532
533         return E_SUCCESS;
534 }
535
536 result
537 DateTime::Subtract(const TimeSpan& t)
538 {
539         long long total = ConvertDateToSeconds(&__dateTime);
540         long long span = total - (t.GetTicks() / 1000);
541
542         SysTryReturn(NID_BASE, span > 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE, "[%s] The arguments contain invalid values.",
543                 GetErrorMessage(E_OUT_OF_RANGE));
544
545         SysTryReturn(NID_BASE, span >= NUM_OF_SEC_IN_DAY, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
546                 "[%s] The arguments contain invalid values.", GetErrorMessage(E_OUT_OF_RANGE));
547
548         long long maxSeconds = ConvertDateToSeconds(&(DateTime::GetMaxValue().__dateTime));
549         SysTryReturn(NID_BASE, span <= maxSeconds, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
550                 "[%s] The value of the argument is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE));
551
552         result r = ConvertSecondsToDate(span, &__dateTime);
553         if (r != E_SUCCESS)
554         {
555                 SysLogException(NID_BASE, r, "[%s] Propagating.", GetErrorMessage(r));
556         }
557
558         return r;
559 }
560
561 String
562 DateTime::ToString(void) const
563 {
564         wchar_t date[] = L"01/01/1970 00:00:00";
565
566         swprintf(date, (sizeof(date) / sizeof(wchar_t)), L"%2d/%2d/%4d %2d:%2d:%2d",
567                          __dateTime.month, __dateTime.day, __dateTime.year, __dateTime.hour, __dateTime.minute,
568                          __dateTime.second);
569
570         if (__dateTime.month < 10)
571         {
572                 date[0] = L'0';
573         }
574
575         if (__dateTime.day < 10)
576         {
577                 date[3] = L'0';
578         }
579
580         if (__dateTime.year < 10)
581         {
582                 date[6] = L'0';
583                 date[7] = L'0';
584                 date[8] = L'0';
585         }
586         else if (__dateTime.year < 100)
587         {
588                 date[6] = L'0';
589                 date[7] = L'0';
590         }
591         else if (__dateTime.year < 1000)
592         {
593                 date[6] = L'0';
594         }
595
596         if (__dateTime.hour < 10)
597         {
598                 date[11] = L'0';
599         }
600
601         if (__dateTime.minute < 10)
602         {
603                 date[14] = L'0';
604         }
605
606         if (__dateTime.second < 10)
607         {
608                 date[17] = L'0';
609         }
610
611         String string(date);
612
613         return string;
614 }
615
616 result
617 DateTime::Parse(const String& str, DateTime& dt)
618 {
619         SysTryReturn(NID_BASE,
620                 (str.GetLength() == 19
621                 && str[2] == L'/' && str[5] == L'/' && str[10] == L' ' && str[13] == L':' && str[16] == L':'),
622                 E_INVALID_FORMAT, E_INVALID_FORMAT, ("[%s] The str(%s) is not formatted like 'mm/dd/yyyy hh:mm:ss'."),
623                 GetErrorMessage(E_INVALID_FORMAT), str.GetPointer());
624
625         std::unique_ptr<wchar_t []> pTmp(new (std::nothrow) wchar_t [5]);
626         SysTryReturn(NID_BASE, pTmp != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
627                 GetErrorMessage(E_OUT_OF_MEMORY));
628
629         wchar_t* pMchar = (wchar_t*) str.GetPointer();
630
631         // month
632         wcsncpy(pTmp.get(), pMchar, 2);
633         pTmp[2] = L'\0';
634
635         int month = (int) wcstol(pTmp.get(), null, 10);
636
637         // day
638         wcsncpy(pTmp.get(), pMchar + 3, 2);
639         pTmp[2] = L'\0';
640
641         int day = (int) wcstol(pTmp.get(), null, 10);
642
643         // year
644         wcsncpy(pTmp.get(), pMchar + 6, 4);
645         pTmp[4] = L'\0';
646
647         int year = (int) wcstol(pTmp.get(), null, 10);
648
649         // hour
650         wcsncpy(pTmp.get(), pMchar + 11, 2);
651         pTmp[2] = L'\0';
652
653         int hour = (int) wcstol(pTmp.get(), null, 10);
654
655         // minute
656         wcsncpy(pTmp.get(), pMchar + 14, 2);
657         pTmp[2] = L'\0';
658
659         int minute = (int) wcstol(pTmp.get(), null, 10);
660
661         // second
662         wcsncpy(pTmp.get(), pMchar + 17, 2);
663         pTmp[2] = L'\0';
664
665         int sec = (int) wcstol(pTmp.get(), null, 10);
666
667         // construct date time
668         DateTime tmpDt;
669         result r = tmpDt.SetValue(year, month, day, hour, minute, sec);
670         SysTryReturnResult(NID_BASE, !IsFailed(r), r, ("[%s] Propagating."), GetErrorMessage(r));
671
672         dt.SetValue(tmpDt);
673
674         return E_SUCCESS;
675 }
676
677 int
678 DateTime::GetYear(void) const
679 {
680         return __dateTime.year;
681 }
682
683 int
684 DateTime::GetMonth(void) const
685 {
686         return __dateTime.month;
687 }
688
689 int
690 DateTime::GetDay(void) const
691 {
692         return __dateTime.day;
693 }
694
695 int
696 DateTime::GetHour(void) const
697 {
698         return __dateTime.hour;
699 }
700
701 int
702 DateTime::GetMinute(void) const
703 {
704         return __dateTime.minute;
705 }
706
707 int
708 DateTime::GetSecond(void) const
709 {
710         return __dateTime.second;
711 }
712
713 TimeSpan
714 DateTime::GetTime(void) const
715 {
716         long long seconds = ConvertDateToSeconds(&__dateTime) - ConvertDateToSeconds(&(DateTime::GetMinValue().__dateTime));
717
718         return TimeSpan(seconds * 1000);
719 }
720
721 const DateTime&
722 DateTime::GetMaxValue(void)
723 {
724         static DateTime maxValue(_MAX_YEAR, MAX_MONTH, MAX_DAY, MAX_HOUR, MAX_MINUTE, MAX_SECOND);
725
726         return maxValue;
727 }
728
729 const DateTime&
730 DateTime::GetMinValue(void)
731 {
732         static DateTime minValue(MIN_YEAR, MIN_MONTH, MIN_DAY, MIN_HOUR, MIN_MINUTE, MIN_SECOND);
733
734         return minValue;
735 }
736
737 bool
738 DateTime::IsLeapYear(void) const
739 {
740         return DateTime::IsLeapYear(__dateTime.year);
741 }
742
743 bool
744 DateTime::IsLeapYear(int year)
745 {
746         return year >= 0 && (!(year % 4) && ((year % 100) || !(year % 400)));
747 }
748
749 DateTime::DateTime(int year, int month, int day, int hour, int minute, int second)
750         : __pDateTimeImpl(null)
751 {
752         SetValue(year, month, day, hour, minute, second);
753 }
754
755 result
756 DateTime::ConvertSecondsToDate(long long seconds, TmDateTime* pDateTime)
757 {
758         DateTime dt;
759
760         int year = 0;
761         int month = 0;
762         int day = 0;
763         int hour = 0;
764         int minute = 0;
765         int second = 0;
766         int totalDays = 0;
767         int tempDays = 0;
768         int tempSeconds = 0;
769         bool leapYear = false;
770
771         totalDays = (int) (seconds / SEC_IN_A_DAY);
772
773         // Get a year and leapYear
774         year = CountYears(totalDays);
775         SysTryReturn(NID_BASE, year >= MIN_YEAR && year <= _MAX_YEAR, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
776                 "[%s] The arguments (%d) contain invalid values.", GetErrorMessage(E_OUT_OF_RANGE), seconds);
777
778         // Check a leapYear
779         leapYear = DateTime::IsLeapYear(year);
780
781         // Get days without year;
782         tempDays = totalDays - CountDays(year);
783
784         // Check the boundary of days
785         if (leapYear)
786         {
787                 if (tempDays > 366)
788                 {
789                         year += 1;
790                         tempDays -= 366;
791                 }
792         }
793         else
794         {
795                 if (tempDays > 365)
796                 {
797                         year += 1;
798                         tempDays -= 365;
799                 }
800         }
801
802         // Get month
803         if (tempDays == 0)      //  month = 0 , day = 0
804         {
805                 dt.__dateTime.year = year;
806                 dt.__dateTime.month = 0;
807                 dt.__dateTime.day = 0;
808                 dt.__dateTime.hour = 0;
809                 dt.__dateTime.minute = 0;
810                 dt.__dateTime.second = 0;
811
812                 tempSeconds = (int) (seconds - ConvertDateToSeconds(&(dt.__dateTime)));
813
814                 // Get Hour
815                 hour = tempSeconds / NUM_OF_SEC_IN_HOUR;
816
817                 tempSeconds -= hour * NUM_OF_SEC_IN_HOUR;
818
819                 // Get Minute
820                 minute = tempSeconds / NUM_OF_SEC_IN_MINUTE;
821
822                 // Get Second
823                 second = tempSeconds - minute * NUM_OF_SEC_IN_MINUTE;
824
825                 SetValue(year, 1, 1, hour, minute, second);
826
827                 return E_SUCCESS;
828         }
829         else if (leapYear)
830         {
831                 int leapYearDaysCount = 0;
832
833                 for (; leapYearDaysCount < 12; leapYearDaysCount++)
834                 {
835                         if ((DAYS_IN_LEAP_YEAR[leapYearDaysCount] < tempDays) && (tempDays <= DAYS_IN_LEAP_YEAR[leapYearDaysCount + 1]))
836                         {
837                                 month = leapYearDaysCount + 1;
838                                 break;
839                         }
840                 }
841
842                 SysTryReturn(NID_BASE, leapYearDaysCount != 12, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
843                         "[%s] The arguments (%d) contain invalid values.", GetErrorMessage(E_OUT_OF_RANGE), seconds);
844
845                 day = tempDays - DAYS_IN_LEAP_YEAR[month - 1];
846         }
847         else
848         {
849                 int daysCount = 0;
850
851                 for (; daysCount < 12; daysCount++)
852                 {
853                         if ((DAYS[daysCount] < tempDays) && (tempDays <= DAYS[daysCount + 1]))
854                         {
855                                 month = daysCount + 1;
856                                 break;
857                         }
858                 }
859
860                 SysTryReturn(NID_BASE, daysCount != 12, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
861                         "[%s] The arguments (%d) contain invalid values.", GetErrorMessage(E_OUT_OF_RANGE), seconds);
862
863                 // Get day
864                 day = tempDays - DAYS[month - 1];
865         }
866
867         dt.SetValue(year, month, day, 0, 0, 0);
868
869         // Get Hour
870         tempSeconds = (int) (seconds - ConvertDateToSeconds(&(dt.__dateTime)));
871         hour = tempSeconds / NUM_OF_SEC_IN_HOUR;
872
873         // Get Minute
874         tempSeconds -= hour * NUM_OF_SEC_IN_HOUR;
875         minute = tempSeconds / NUM_OF_SEC_IN_MINUTE;
876
877         // Get Second
878         second = tempSeconds - minute * NUM_OF_SEC_IN_MINUTE;
879
880         SetValue(year, month, day, hour, minute, second);
881
882         return E_SUCCESS;
883 }
884
885 long long
886 DateTime::ConvertDateToSeconds(const TmDateTime* pDateTime) const
887 {
888         long long days = 0;
889         long long seconds = 0;
890
891         // Add year
892         days = CountDays(pDateTime->year);
893
894         // Add month
895         if (pDateTime->month != 0)
896         {
897                 if (DateTime::IsLeapYear(pDateTime->year))
898                 {
899                         days += DAYS_IN_LEAP_YEAR[pDateTime->month - 1];
900                 }
901                 else
902                 {
903                         days += DAYS[pDateTime->month - 1];
904                 }
905         }
906
907         // Add days
908         days += pDateTime->day;
909
910         // Convert to Seconds
911         seconds = days * NUM_OF_SEC_IN_DAY;
912
913         // Add hours
914         seconds += pDateTime->hour * NUM_OF_SEC_IN_HOUR;
915
916         // Add minutes
917         seconds += pDateTime->minute * NUM_OF_SEC_IN_MINUTE;
918
919         // Add minutes
920         seconds += pDateTime->second;
921
922         return seconds;
923 }
924
925 }} // Tizen::Base