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