2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <dpl/log/log.h>
24 #include <Commons/Exception.h>
26 #include <unicode/timezone.h>
27 #include <unicode/vtzone.h>
28 #include <unicode/smpdtfmt.h>
31 #include "TimeUtilTools.h"
33 using namespace TizenApis::Api::TimeUtil;
34 using namespace WrtDeviceApis;
40 TZDate::TZDate(const bool isNotNull)
44 if (isNotNull == FALSE) {
47 UErrorCode ec = U_ZERO_ERROR;
48 myCalendar = Calendar::createInstance(ec);
52 Util.printDate(myCalendar);
56 ThrowMsg(Commons::PlatformException, "Can't make to ICU Calendar");
61 TZDate::TZDate(const std::string &timezone)
65 UErrorCode ec = U_ZERO_ERROR;
67 myCalendar = Calendar::createInstance(Util.makeTimeZone(timezone) ,ec);
71 Util.printDate(myCalendar);
75 ThrowMsg(Commons::PlatformException, "Can't make to ICU Calendar");
80 TZDate::TZDate(const TZDateProperties &properties)
84 UErrorCode ec = U_ZERO_ERROR;
86 if (properties.timezone == "") {
87 myCalendar = Calendar::createInstance(ec);
89 myCalendar->set(Util.toint32_t(properties.year), Util.toint32_t(properties.month),
90 Util.toint32_t(properties.day), Util.toint32_t(properties.hours), Util.toint32_t(properties.minutes), Util.toint32_t(properties.seconds));
91 set(TZDATE_MILLISECOND, properties.milliseconds);
96 myCalendar = _makeCalendar(properties);
99 if (myCalendar != NULL) {
100 Util.printDate(myCalendar);
103 ThrowMsg(Commons::PlatformException, "Can't make to ICU Calendar");
111 if (myCalendar != NULL)
118 bool TZDate::isNull()
120 if (myCalendar == NULL)
126 Calendar *TZDate::_makeCalendar(const TZDateProperties &properties)
129 UErrorCode ec = U_ZERO_ERROR;
132 Calendar *cal = Calendar::createInstance(Util.makeTimeZone(properties.timezone) ,ec);
134 cal->set(Util.toint32_t(properties.year), Util.toint32_t(properties.month),
135 Util.toint32_t(properties.day), Util.toint32_t(properties.hours), Util.toint32_t(properties.minutes), Util.toint32_t(properties.seconds));
136 cal->set(UCAL_MILLISECOND, Util.toint32_t(properties.milliseconds));
143 std::string TZDate::_getTimezoneName(Calendar *cal)
148 cal->getTimeZone().getID(ID);
149 std::string s_result = Util.toString(ID);
154 const UCalendarDateFields TZDate::_convertDateField(const TZDateFields field)
166 case TZDATE_WEEK_OF_YEAR:
167 return UCAL_WEEK_OF_YEAR;
169 case TZDATE_WEEK_OF_MONTH:
170 return UCAL_WEEK_OF_MONTH;
175 case TZDATE_DAY_OF_YEAR:
176 return UCAL_DAY_OF_YEAR;
178 case TZDATE_DAY_OF_WEEK:
179 return UCAL_DAY_OF_WEEK;
181 case TZDATE_DAY_OF_WEEK_IN_MONTH:
182 return UCAL_DAY_OF_WEEK_IN_MONTH;
190 case TZDATE_HOUR_OF_DAY:
191 return UCAL_HOUR_OF_DAY;
199 case TZDATE_MILLISECOND:
200 return UCAL_MILLISECOND;
202 case TZDATE_ZONE_OFFSET:
203 return UCAL_ZONE_OFFSET;
205 case TZDATE_DST_OFFSET:
206 return UCAL_DST_OFFSET;
209 return UCAL_FIELD_COUNT;
213 TZDateProperties TZDate::_makeProperties(Calendar *cal)
215 TZDateProperties result;
218 result.year = _get(TZDATE_YEAR, cal);
219 result.month = _get(TZDATE_MONTH,cal);
220 result.day = _get(TZDATE_DATE, cal);
221 result.hours = _get(TZDATE_HOUR_OF_DAY, cal);
222 result.minutes = _get(TZDATE_MINUTE, cal);
223 result.seconds = _get(TZDATE_SECOND, cal);
224 result.milliseconds = _get(TZDATE_MILLISECOND, cal);
225 result.timezone= _getTimezoneName(cal);
230 std::string TZDate::getTimezone()
232 return _getTimezoneName(myCalendar);
235 TZDateProperties TZDate::toTimezone(const std::string timezone) {
237 Calendar *newCalendar = myCalendar->clone();
238 newCalendar->setTimeZone(*(Util.makeTimeZone(timezone)));
240 TZDateProperties newProps = _makeProperties(newCalendar);
242 if ((newProps.timezone != timezone) && (newProps.timezone == "Etc/Unknown"))
243 ThrowMsg(Commons::InvalidArgumentException, "Unsupported Timezone.");
247 long TZDate::_get(const TZDateFields field, Calendar *cal)
251 if (_convertDateField(field) == UCAL_FIELD_COUNT){
252 LogDebug(">>> UCAL_FIELD_COUNT");
256 UErrorCode ec = U_ZERO_ERROR;
258 int32_t value = cal->get(_convertDateField(field), ec);
260 long result = Util.tolong(value);
262 LogDebug(">>> result:" << result);
265 ThrowMsg(Commons::PlatformException, "Can't get Calendar value");
268 long TZDate::get(const TZDateFields field)
272 long result = _get(field, myCalendar);
273 if (field == TZDATE_DAY_OF_WEEK)
278 void TZDate::set(const TZDateFields field, const long value)
280 if (_convertDateField(field) == UCAL_FIELD_COUNT)
284 myCalendar->set(_convertDateField(field), Util.toint32_t(value));
285 LogDebug("Field : " << field << " value : " << get(field));
288 long TZDate::getUTC(const TZDateFields field)
290 if (_convertDateField(field) == UCAL_FIELD_COUNT)
293 UErrorCode ec = U_ZERO_ERROR;
296 Calendar *UTCCalendar = myCalendar->clone();
297 UTCCalendar->setTimeZone(*(TimeZone::getGMT()));
299 int32_t value = UTCCalendar->get(_convertDateField(field), ec);
303 long result = Util.tolong(value);
304 if (field == TZDATE_DAY_OF_WEEK)
306 LogDebug("result : " << result);
311 ThrowMsg(Commons::PlatformException, "Can't get UTC Calendar value");
315 void TZDate::setUTC(const TZDateFields field, const long value)
317 if (_convertDateField(field) == UCAL_FIELD_COUNT)
321 UErrorCode ec = U_ZERO_ERROR;
323 long myValue = get(field);
324 long UTCValue = getUTC(field);
325 if (field == TZDATE_DAY_OF_WEEK)
327 set(field, myValue + value - UTCValue);
330 ThrowMsg(Commons::PlatformException, "Can't set UTC Calendar value");
333 long long TZDate::difference(const TZDateProperties &prop) {
337 UErrorCode ec = U_ZERO_ERROR;
339 Calendar *otherCalendar = _makeCalendar(prop);
341 UDate myTime = myCalendar->getTime(ec);
344 UDate otherTime = otherCalendar->getTime(ec);
346 LogDebug("myCalendar");
347 Util.printDate(myCalendar);
348 LogDebug("otherCalendar");
349 Util.printDate(otherCalendar);
350 delete otherCalendar;
352 LogDebug("myTime : " <<myTime);
353 LogDebug("otherTime : " << otherTime);
355 return static_cast<long long>(myTime - otherTime);
358 delete otherCalendar;
359 ThrowMsg(Commons::PlatformException, "Calendar error in difference");
363 TZDateProperties TZDate::addDuration(const DurationProperties &duration) {
365 UErrorCode ec = U_ZERO_ERROR;
369 Calendar *cal = myCalendar->clone();
370 if (duration.unit == DAYS_UNIT) {
371 cal->add(UCAL_DATE, Util.toint32_t(duration.length), ec);
372 } else if (duration.unit == MINUTES_UNIT) {
373 cal->add(UCAL_MINUTE, Util.toint32_t(duration.length), ec);
374 } else if (duration.unit == HOURS_UNIT) {
375 cal->add(UCAL_HOUR_OF_DAY, Util.toint32_t(duration.length), ec);
376 } else if (duration.unit == MSECS_UNIT) {
377 cal->add(UCAL_MILLISECOND, Util.toint32_t(duration.length), ec);
379 cal->add(UCAL_SECOND, Util.toint32_t(duration.length), ec);
381 TZDateProperties result = _makeProperties(cal);
386 ThrowMsg(Commons::PlatformException, "Calendar error in addDuration");
391 TZDateProperties TZDate::toUTC() {
394 TZDateProperties result;
395 Calendar *UTCCalendar = myCalendar->clone();
398 UTCCalendar->setTimeZone(*(TimeZone::getGMT()));
399 result = _makeProperties(UTCCalendar);
400 Util.printDate(UTCCalendar);
402 } catch (Commons::PlatformException) {
404 ThrowMsg(Commons::PlatformException, "Calendar error in toUTC");
410 TZDateProperties TZDate::toLocalTimezone() {
413 TZDateProperties result;
414 Calendar *localCalendar = myCalendar->clone();
417 localCalendar->setTimeZone(*(TimeZone::createDefault()));
418 result = _makeProperties(localCalendar);
419 Util.printDate(localCalendar);
420 delete localCalendar;
421 } catch (Commons::PlatformException) {
422 delete localCalendar;
423 ThrowMsg(Commons::PlatformException, "Calendar error in toLocalTimezone");
428 double TZDate::getTime() {
430 UErrorCode ec = U_ZERO_ERROR;
432 UDate date = myCalendar->getTime(ec);
434 return static_cast<double>(date);
436 ThrowMsg(Commons::PlatformException, "can't get time");
440 std::string TZDate::toDateString(bool bLocale) {
441 UErrorCode ec = U_ZERO_ERROR;
445 DateFormat *fmt = new SimpleDateFormat(Util.getDateTimeFormat(TimeUtilTools::DATE_FORMAT, bLocale), (bLocale ? Locale::getDefault() : Locale::getEnglish()), ec);
447 fmt->setCalendar(*myCalendar);
448 fmt->format(myCalendar->getTime(ec), str);
452 std::string result = Util.toString(str);
460 ThrowMsg(Commons::PlatformException, "can't make SimpleDateFormat or can't get time");
464 std::string TZDate::toTimeString(bool bLocale) {
466 UErrorCode ec = U_ZERO_ERROR;
470 DateFormat *fmt = new SimpleDateFormat(Util.getDateTimeFormat(TimeUtilTools::TIME_FORMAT, bLocale), (bLocale ? Locale::getDefault() : Locale::getEnglish()), ec);
472 fmt->setCalendar(*myCalendar);
473 fmt->format(myCalendar->getTime(ec), str);
477 std::string result = Util.toString(str);
484 ThrowMsg(Commons::PlatformException, "can't make SimpleDateFormat or can't get time");
488 std::string TZDate::toString(bool bLocale) {
491 UErrorCode ec = U_ZERO_ERROR;
495 DateFormat *fmt = new SimpleDateFormat(Util.getDateTimeFormat(TimeUtilTools::DATETIME_FORMAT, bLocale), (bLocale ? Locale::getDefault() : Locale::getEnglish()), ec);
497 fmt->setCalendar(*myCalendar);
498 fmt->format(myCalendar->getTime(ec), str);
502 std::string result = Util.toString(str);
508 ThrowMsg(Commons::PlatformException, "can't make SimpleDateFormat or can't get time");
512 std::string TZDate::getTimezoneAbbreviation() {
515 UErrorCode ec = U_ZERO_ERROR;
519 DateFormat *fmt = new SimpleDateFormat(UnicodeString("V"), Locale::getEnglish(), ec);
521 fmt->setCalendar(*myCalendar);
522 fmt->format(myCalendar->getTime(ec), str);
526 std::string result = Util.toString(str);
534 ThrowMsg(Commons::PlatformException, "can't make SimpleDateFormat or can't get time");
538 long TZDate::secondsFromUTC() {
540 UErrorCode ec = U_ZERO_ERROR;
543 int32_t zoneOffset = myCalendar->get(UCAL_ZONE_OFFSET, ec);
544 if (!U_SUCCESS(ec)) {
545 ThrowMsg(Commons::PlatformException, "can't get zone offset");
549 int32_t dstOffset = myCalendar->get(UCAL_DST_OFFSET, ec);
550 if (!U_SUCCESS(ec)) {
551 ThrowMsg(Commons::PlatformException, "can't get dst offset");
555 long result = ( Util.tolong(zoneOffset + dstOffset)) / MILLISTOSEC;
557 LogDebug("result : " << result);
561 bool TZDate::isDST() {
563 UErrorCode ec = U_ZERO_ERROR;
565 UBool result = myCalendar->inDaylightTime(ec);
567 if (!U_SUCCESS(ec)) {
568 ThrowMsg(Commons::PlatformException, "can't inDaylightTime value from ICU");
572 return static_cast<bool>(result);
575 TZDateProperties TZDate::getDSTTransition(DSTTransition trans) {
578 UErrorCode ec = U_ZERO_ERROR;
579 TZDateProperties props;
580 UDate DSTTransitionDate = myCalendar->getTime(ec);
581 UBool result = false;
584 UnicodeString *ID = Util.toUnicodeString(getTimezone());
586 VTimeZone *Vtz = VTimeZone::createVTimeZoneByID(*ID);
589 TimeZoneTransition tzTrans;
590 if (Vtz->useDaylightTime() == TRUE) {
591 if (trans == NEXT_TRANSITION)
592 result = Vtz->getNextTransition(DSTTransitionDate, FALSE, tzTrans);
594 result = Vtz->getPreviousTransition(DSTTransitionDate, FALSE, tzTrans);
595 if (result == TRUE) {
596 LogDebug("result is TRUE");
597 DSTTransitionDate = tzTrans.getTime();
605 Calendar *DSTTransCalendar = myCalendar->clone();
606 DSTTransCalendar->setTime(DSTTransitionDate, ec);
608 props = _makeProperties(DSTTransCalendar);
609 delete DSTTransCalendar;
612 delete DSTTransCalendar;
614 ThrowMsg(Commons::PlatformException, "can't getDSTTransition value from ICU");