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