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