diff options
Diffstat (limited to 'mobile_src/TimeUtil/TZDate.cpp')
-rwxr-xr-x | mobile_src/TimeUtil/TZDate.cpp | 919 |
1 files changed, 919 insertions, 0 deletions
diff --git a/mobile_src/TimeUtil/TZDate.cpp b/mobile_src/TimeUtil/TZDate.cpp new file mode 100755 index 0000000..e2d36b6 --- /dev/null +++ b/mobile_src/TimeUtil/TZDate.cpp @@ -0,0 +1,919 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include <Commons/Exception.h> +#include <unicode/timezone.h> +#include <unicode/vtzone.h> +#include <unicode/smpdtfmt.h> +#include "TZDate.h" +#include "TimeUtilTools.h" +#include <vconf.h> +#include <Logger.h> + +using namespace WrtDeviceApis; + +namespace DeviceAPI { +namespace Time { + +TZDate::TZDate(const bool isNotNull) +{ + LoggerD("entered"); + + if (isNotNull == FALSE) { + myCalendar = NULL; + } else { + UErrorCode ec = U_ZERO_ERROR; +#if 0 + TimeUtilTools util; + TimeZone *tz = util.makeTimeZone(timezone); + if (timezone) + free(timezone); + + if (isAvailableTimezone(tz)) + myCalendar = Calendar::createInstance(tz, ec); + else + myCalendar = Calendar::createInstance(ec); + + if (tz) + delete tz; + + if (U_SUCCESS(ec)) { + util.printDate(myCalendar); + } + else { + myCalendar = NULL; + } +#else + myCalendar = Calendar::createInstance(ec); +#endif + } +} + +TZDate::TZDate(const std::string &timezone) +{ + LoggerD("entered"); + + myCalendar = _makeCalendar(timezone); +} + +TZDate::TZDate(const TZDateProperties &properties) +{ + LoggerD("entered"); + + TimeUtilTools util; + myCalendar = _makeCalendar(properties); +} + +TZDate::TZDate(const std::string &dateString, const double milliseconds, const std::string &timezone) { + myCalendar = NULL; + + UErrorCode ec = U_ZERO_ERROR; + Calendar *dateCalender = Calendar::createInstance(ec); + DateFormat *df = NULL; + try { + if (dateCalender == NULL || U_FAILURE(ec)) { + ThrowMsg(Commons::UnknownException, "Can't make calendar"); + } + df = new SimpleDateFormat("EEE MMM d uuuuuu HH:mm:ss", Locale::getEnglish(), ec); + + if (df == NULL || U_FAILURE(ec)) { + ThrowMsg(Commons::UnknownException, "Can't make DateFormat"); + } + ParsePosition pos; + pos.setIndex(0); + TimeUtilTools util; + UnicodeString text(dateString.c_str()); + UDate date = df->parse(text, ec); + + if (U_FAILURE(ec)) { + ThrowMsg(Commons::UnknownException, "parse fail"); + } + + dateCalender->setTime(date, ec); + + if (U_FAILURE(ec)) { + ThrowMsg(Commons::UnknownException, "setTime fail"); + } + + util.printDate(dateCalender); + TZDateProperties properties; + properties.year = _get(TZDATE_YEAR, dateCalender); + properties.month = _get(TZDATE_MONTH, dateCalender); + properties.day = _get(TZDATE_DATE, dateCalender); + properties.hours = _get(TZDATE_HOUR_OF_DAY, dateCalender); + properties.minutes = _get(TZDATE_MINUTE, dateCalender); + properties.seconds = _get(TZDATE_SECOND, dateCalender); + properties.milliseconds = milliseconds; + properties.timezone = timezone; + myCalendar = _makeCalendar(properties); + } catch (const WrtDeviceApis::Commons::Exception& err) { + LoggerE(err.GetClassName() << ":"<<err.GetMessage()); + if (myCalendar) + delete myCalendar; + myCalendar = NULL; + } + + if (dateCalender) + delete dateCalender; + if (df) + delete df; +} + +TZDate::~TZDate() +{ + LoggerD("entered"); + + if (myCalendar != NULL) + delete myCalendar; + + myCalendar = NULL; +} + +bool TZDate::isNull() +{ + if (myCalendar == NULL) + return TRUE; + + return FALSE; +} + +bool TZDate::isAvailableTimezone(const std::string &timezone) { + TimeUtilTools util; + TimeZone *tz = util.makeTimeZone(timezone); + + bool result = isAvailableTimezone(tz); + + if (tz) + delete tz; + return result; +} + +bool TZDate::isAvailableTimezone(TimeZone *tz) { + if (!tz) + return false; + + TimeUtilTools util; + bool result = true; + UnicodeString id; + tz->getID(id); + + if (util.toString(id) == "Etc/Unknown") + result = false; + + return result; +} + +Calendar *TZDate::_makeCalendar(const std::string &timezone) { + UErrorCode ec = U_ZERO_ERROR; + TimeUtilTools util; + Calendar *cal = NULL; + + TimeZone *tz = util.makeTimeZone(timezone); + + if (isAvailableTimezone(tz)) + cal = Calendar::createInstance(tz ,ec); + else { + if (tz) + delete tz; + cal = Calendar::createInstance(ec); + } + + if (U_SUCCESS(ec)) { + util.printDate(cal); + } else { + if (tz) + delete tz; + cal = NULL; + } + return cal; +} + +Calendar *TZDate::_makeCalendar(const TZDateProperties &properties) +{ + LoggerD("entered"); + UErrorCode ec = U_ZERO_ERROR; + TimeUtilTools util; + + Calendar *cal = NULL; + if (!isAvailableTimezone(properties.timezone)) + cal = Calendar::createInstance(ec); + else + cal = Calendar::createInstance(util.makeTimeZone(properties.timezone) ,ec); + + if ((cal != NULL) && U_SUCCESS(ec)) { + try { + cal->set(UCAL_DATE, 10); //set specific date because first date(1) or last date(31) can make changing of month because of timezone + + _set(TZDATE_YEAR, properties.year, cal); + _set(TZDATE_MONTH, properties.month, cal); + _set(TZDATE_DATE, properties.day, cal); + _set(TZDATE_HOUR_OF_DAY, properties.hours, cal); + _set(TZDATE_MINUTE, properties.minutes, cal); + _set(TZDATE_SECOND, properties.seconds, cal); + _set(TZDATE_MILLISECOND, properties.milliseconds, cal); + } catch (const WrtDeviceApis::Commons::Exception& err) { + LoggerE(err.GetClassName() << ":"<<err.GetMessage()); + if (cal) + delete cal; + cal = NULL; + } + return cal; + } + + if (cal) + delete cal; + return NULL; +} + +std::string TZDate::_getTimezoneName(Calendar *cal) +{ + if (cal == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UnicodeString id; + TimeUtilTools util; + + cal->getTimeZone().getID(id); + std::string s_result = util.toString(id); + LoggerD(s_result); + return s_result; +} + +const UCalendarDateFields TZDate::_convertDateField(const TZDateFields field) +{ + switch (field) { + case TZDATE_ERA: + return UCAL_ERA; + break; + case TZDATE_YEAR: + return UCAL_EXTENDED_YEAR; + break; + case TZDATE_MONTH: + return UCAL_MONTH; + break; + case TZDATE_WEEK_OF_YEAR: + return UCAL_WEEK_OF_YEAR; + break; + case TZDATE_WEEK_OF_MONTH: + return UCAL_WEEK_OF_MONTH; + break; + case TZDATE_DATE: + return UCAL_DATE; + break; + case TZDATE_DAY_OF_YEAR: + return UCAL_DAY_OF_YEAR; + break; + case TZDATE_DAY_OF_WEEK: + return UCAL_DAY_OF_WEEK; + break; + case TZDATE_DAY_OF_WEEK_IN_MONTH: + return UCAL_DAY_OF_WEEK_IN_MONTH; + break; + case TZDATE_AM_PM: + return UCAL_AM_PM; + break; + case TZDATE_HOUR: + return UCAL_HOUR; + break; + case TZDATE_HOUR_OF_DAY: + return UCAL_HOUR_OF_DAY; + break; + case TZDATE_MINUTE: + return UCAL_MINUTE; + break; + case TZDATE_SECOND: + return UCAL_SECOND; + break; + case TZDATE_MILLISECOND: + return UCAL_MILLISECOND; + break; + case TZDATE_ZONE_OFFSET: + return UCAL_ZONE_OFFSET; + break; + case TZDATE_DST_OFFSET: + return UCAL_DST_OFFSET; + break; + default: + return UCAL_FIELD_COUNT; + } +} + +TZDateProperties TZDate::_makeProperties(Calendar *cal) +{ + TZDateProperties result; + TimeUtilTools util; + + result.year = _get(TZDATE_YEAR, cal); + result.month = _get(TZDATE_MONTH,cal); + result.day = _get(TZDATE_DATE, cal); + result.hours = _get(TZDATE_HOUR_OF_DAY, cal); + result.minutes = _get(TZDATE_MINUTE, cal); + result.seconds = _get(TZDATE_SECOND, cal); + result.milliseconds = _get(TZDATE_MILLISECOND, cal); + result.timezone= _getTimezoneName(cal); + + return result; +} + +TZDateProperties TZDate::makeProperties() { + return _makeProperties(myCalendar); +} + +std::string TZDate::getTimezone() +{ + return _getTimezoneName(myCalendar); +} + +TZDateProperties TZDate::toTimezone(const std::string timezone) { + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + TimeUtilTools util; + Calendar *newCalendar = myCalendar->clone(); + if (newCalendar == NULL) + ThrowMsg(Commons::PlatformException, "Can't create new calendar"); + + newCalendar->setTimeZone(*(util.makeTimeZone(timezone))); + + TZDateProperties newProps = _makeProperties(newCalendar); + delete newCalendar; + + return newProps; +} + +long TZDate::_get(const TZDateFields field, Calendar *cal) +{ + LoggerD("<<<"); + + if (cal == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + if (_convertDateField(field) == UCAL_FIELD_COUNT){ + LoggerD(">>> UCAL_FIELD_COUNT"); + return -1; + } + + UErrorCode ec = U_ZERO_ERROR; + TimeUtilTools util; + int32_t value = cal->get(_convertDateField(field), ec); + if (U_SUCCESS(ec)) { + long result = util.tolong(value); + + LoggerD(">>> result:" << result); + return result; + } + ThrowMsg(Commons::PlatformException, "Can't get Calendar value"); +} +long TZDate::get(const TZDateFields field) +{ + LoggerD("<<<"); + + long result = _get(field, myCalendar); + if (field == TZDATE_DAY_OF_WEEK) + result--; + return result; +} + +void TZDate::set(const TZDateFields field, const long value) { + try { + _set(field, value, myCalendar); + } catch (Commons::PlatformException& err) { + LoggerE(err.GetMessage()); + if (myCalendar) + delete myCalendar; + myCalendar = NULL; + } + +} + +void TZDate::_set(const TZDateFields field, const long value, Calendar *cal) +{ + if (_convertDateField(field) == UCAL_FIELD_COUNT) + return; + + if (cal == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + TimeUtilTools util; + Calendar *originCal = cal->clone(); + cal->set(_convertDateField(field), util.toint32_t(value)); + + LoggerD("Field : " << field << " value : " << value<< " result:" <<_get(field, cal)); + try { + if (field == TZDATE_YEAR) { + if (value != _get(field, cal)) + ThrowMsg(Commons::PlatformException, "Out of range"); + } else if (field == TZDATE_MONTH) { + long yearDiff = value / 12; + long month = value % 12; + if (value < 0) { + yearDiff--; + month += 12; + } + + long originYear = _get(TZDATE_YEAR, originCal); + if (((originYear + yearDiff) != _get(TZDATE_YEAR, cal)) + || (month != _get(TZDATE_MONTH, cal))) { + LoggerD("originYear:"<<originYear<<" yearDiff:"<<yearDiff<<" TZDATE_YEAR:"<< _get(TZDATE_YEAR, cal)); + LoggerD(" month:"<<month<<" TZDATE_MONTH:"<< _get(TZDATE_MONTH, cal)); + ThrowMsg(Commons::PlatformException, "Out of range"); + } + } else { + UErrorCode ec = U_ZERO_ERROR; + double diff = value - _get(field, originCal); + if (field == TZDATE_DATE) + diff *= U_MILLIS_PER_DAY; + else if (field == TZDATE_HOUR_OF_DAY) + diff *= U_MILLIS_PER_HOUR; + else if (field == TZDATE_MINUTE) + diff *= U_MILLIS_PER_MINUTE; + else if (field == TZDATE_SECOND) + diff *= U_MILLIS_PER_SECOND; + + UDate originUDate = originCal->getTime(ec); + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "ICU Error"); + + LoggerD("originUDate :" << (double)originUDate << " diff : " << diff); + + if ((U_DATE_MAX - originUDate) < diff) + ThrowMsg(Commons::PlatformException, "Out of range"); + } + } catch (Commons::PlatformException& err) { + LoggerE(err.GetMessage()); + if (originCal) + delete originCal; + throw(err); + } + if (originCal) + delete originCal; +} + +long TZDate::getUTC(const TZDateFields field) +{ + if (_convertDateField(field) == UCAL_FIELD_COUNT) + return -1; + + UErrorCode ec = U_ZERO_ERROR; + Calendar *utcCalendar = NULL; + + try { + utcCalendar = Calendar::createInstance(*(TimeZone::getGMT()),ec); + if (!U_SUCCESS(ec) || (utcCalendar == NULL)) + ThrowMsg(Commons::PlatformException, "Can't create utcCalendar"); + + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UDate date = myCalendar->getTime(ec); + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "Can't get time of myCalendar"); + + utcCalendar->setTime(date, ec); + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "Can't set time of utcCalendar"); + + int32_t value = utcCalendar->get(_convertDateField(field), ec); + + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "Can't get data of utcCalendar"); + + if (utcCalendar) + delete utcCalendar; + utcCalendar = NULL; + + TimeUtilTools util; + long result = util.tolong(value); + if (field == TZDATE_DAY_OF_WEEK) + result--; + LoggerD("result : " << result); + + return result; + } catch (const Commons::PlatformException& err) { + LoggerE(err.GetMessage()); + } + + if (utcCalendar) + delete utcCalendar; + ThrowMsg(Commons::PlatformException, "Can't get UTC Calendar value"); +} + +void TZDate::setUTC(const TZDateFields field, const long value) +{ + if (_convertDateField(field) == UCAL_FIELD_COUNT) + return; + + TimeUtilTools util; + UErrorCode ec = U_ZERO_ERROR; + + long myValue = get(field); + long utcValue = getUTC(field); + if (field == TZDATE_DAY_OF_WEEK) + utcValue++; + set(field, myValue + value - utcValue); + + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "Can't set UTC Calendar value"); +} + +long long TZDate::difference(const TZDateProperties &prop) { + LoggerD("entered"); + + TimeUtilTools util; + UErrorCode ec = U_ZERO_ERROR; + + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + Calendar *otherCalendar = _makeCalendar(prop); + + if (otherCalendar == NULL) + ThrowMsg(Commons::PlatformException, "Other calendar is null"); + + if (!util.compareTimeZoneName(otherCalendar, prop.timezone)) { + delete otherCalendar; + ThrowMsg(Commons::InvalidArgumentException, "Unsupported Timezone."); + } + + UDate myTime = myCalendar->getTime(ec); + + if (U_SUCCESS(ec)) { + UDate otherTime = otherCalendar->getTime(ec); + if (U_SUCCESS(ec)) { + LoggerD("myCalendar"); + util.printDate(myCalendar); + LoggerD("otherCalendar"); + util.printDate(otherCalendar); + delete otherCalendar; + + LoggerD("myTime : " <<myTime); + LoggerD("otherTime : " << otherTime); + + return static_cast<long long>(myTime - otherTime); + } + } + delete otherCalendar; + ThrowMsg(Commons::PlatformException, "Calendar error in difference"); +} + +TZDateProperties TZDate::addDuration(const DurationProperties &duration) { + LoggerD("entered"); + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UErrorCode ec = U_ZERO_ERROR; + + TimeUtilTools util; + + Calendar *cal = myCalendar->clone(); + if (cal == NULL) + ThrowMsg(Commons::PlatformException, "Can't clone my calendar"); + + long long length = duration.length; + short unit = duration.unit; + int msec=0, sec=0, min=0, hour=0; + long long day=0; + + if (unit == MSECS_UNIT) { + msec = length % 1000; + length /= 1000; + unit = SECONDS_UNIT; + } + if ((length != 0) && (unit == SECONDS_UNIT)) { + sec = length % 60; + length /= 60; + unit = MINUTES_UNIT; + } + if ((length != 0) && (unit == MINUTES_UNIT)) { + min = length % 60; + length /= 60; + unit = HOURS_UNIT; + } + if ((length != 0) && (unit == HOURS_UNIT)) { + hour = length % 24; + length /= 24; + unit = DAYS_UNIT; + } + day = length; + LoggerD("day:"<<day<<" hour:"<<hour<<" min:"<<min<<" sec:"<<sec<<" msec:"<<msec); + try { + if (msec != 0) { + cal->add(UCAL_MILLISECOND, util.toint32_t(msec), ec); + if (!U_SUCCESS(ec)) + Throw(Commons::PlatformException); + } + if (sec != 0) { + cal->add(UCAL_SECOND, util.toint32_t(sec), ec); + if (!U_SUCCESS(ec)) + Throw(Commons::PlatformException); + } + if (min != 0) { + cal->add(UCAL_MINUTE, util.toint32_t(min), ec); + if (!U_SUCCESS(ec)) + Throw(Commons::PlatformException); + } + if (hour != 0) { + cal->add(UCAL_HOUR_OF_DAY, util.toint32_t(hour), ec); + if (!U_SUCCESS(ec)) + Throw(Commons::PlatformException); + } + + UDate oldValue = cal->getTime(ec); + if (!U_SUCCESS(ec)) + Throw(Commons::PlatformException); + + while (day != 0) { + LoggerD("1st day : " << day); + int amount = 0; + + if (day < INT_MIN) + amount = INT_MIN; + else if (day > INT_MAX) + amount = INT_MAX; + else + amount = day; + + day -= amount; + LoggerD("amount : " << amount); + LoggerD("2nd day : " << day); + cal->add(UCAL_DATE, util.toint32_t(amount), ec); + if (!U_SUCCESS(ec)) + Throw(Commons::PlatformException); + + UDate newValue = cal->getTime(ec); + if (!U_SUCCESS(ec)) + Throw(Commons::PlatformException); + + int diff = static_cast<int>((newValue - oldValue) / 24 / 60 / 60 / 1000); + LoggerD("diff : " << diff); + if (diff != amount) { + Throw(Commons::OutOfRangeException); + } + oldValue = newValue; + } ; + } catch (Commons::PlatformException) { + delete cal; + ThrowMsg(Commons::PlatformException, "Calendar error in addDuration"); + } catch (Commons::OutOfRangeException) { + delete cal; + ThrowMsg(Commons::OutOfRangeException, "The result is beyond the scope that TZDate can handle."); + } + + TZDateProperties result = _makeProperties(cal); + util.printDate(cal); + delete cal; + + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "Calendar error in addDuration"); + return result; +} + +std::string TZDate::getUTCTimezoneName() { + UnicodeString id; + TimeUtilTools util; + + TimeZone::getGMT()->getID(id); + std::string s_result = util.toString(id); + LoggerD(s_result); + return s_result; +} + +std::string TZDate::getLocalTimezoneName() { + UnicodeString id; + TimeUtilTools util; + + TimeZone::createDefault()->getID(id); + std::string s_result = util.toString(id); + LoggerD(s_result); + return s_result; +} + +double TZDate::getTime() { + LoggerD("entered"); + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UErrorCode ec = U_ZERO_ERROR; + + UDate date = myCalendar->getTime(ec); + if (U_SUCCESS(ec)) + return static_cast<double>(date); + + ThrowMsg(Commons::PlatformException, "can't get time"); +} + +bool TZDate::setTime(const double time) { + LoggerD("entered"); + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UErrorCode ec = U_ZERO_ERROR; + + myCalendar->setTime(static_cast<UDate>(time), ec); + if (U_SUCCESS(ec)) + return true; + + return false; +} + + std::string TZDate::toDateString(bool bLocale) { + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UErrorCode ec = U_ZERO_ERROR; + UnicodeString str; + TimeUtilTools util; + + Locale *defaultLocale = util.getDefaultLocale(); + UnicodeString patten = util.getDateTimeFormat(TimeUtilTools::DATE_FORMAT, bLocale); + patten.findAndReplace("Y", "u"); + patten.findAndReplace("y", "u"); + DateFormat *fmt = new SimpleDateFormat(patten, ((bLocale && defaultLocale) ? *defaultLocale : Locale::getEnglish()), ec); + if (U_SUCCESS(ec)) { + fmt->setCalendar(*myCalendar); + fmt->format(myCalendar->getTime(ec), str); + delete fmt; + + if (U_SUCCESS(ec)) { + std::string result = util.toString(str); + str.remove(); + + LoggerD (result); + return result; + } + } + + ThrowMsg(Commons::PlatformException, "can't make SimpleDateFormat or can't get time"); + } + + std::string TZDate::toTimeString(bool bLocale) { + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UErrorCode ec = U_ZERO_ERROR; + UnicodeString str; + TimeUtilTools util; + + Locale *defaultLocale = util.getDefaultLocale(); + DateFormat *fmt = new SimpleDateFormat(util.getDateTimeFormat(TimeUtilTools::TIME_FORMAT, bLocale), ((bLocale && defaultLocale) ? *defaultLocale : Locale::getEnglish()), ec); + if (U_SUCCESS(ec)) { + fmt->setCalendar(*myCalendar); + fmt->format(myCalendar->getTime(ec), str); + delete fmt; + + if (U_SUCCESS(ec)) { + std::string result = util.toString(str); + str.remove(); + LoggerD (result); + return result; + } + } + + ThrowMsg(Commons::PlatformException, "can't make SimpleDateFormat or can't get time"); + } + + std::string TZDate::toString(bool bLocale) { + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + LoggerD("entered"); + + UErrorCode ec = U_ZERO_ERROR; + UnicodeString str; + TimeUtilTools util; + + Locale *defaultLocale = util.getDefaultLocale(); + UnicodeString patten = util.getDateTimeFormat(TimeUtilTools::DATETIME_FORMAT, bLocale); + patten.findAndReplace("Y", "u"); + patten.findAndReplace("y", "u"); + DateFormat *fmt = new SimpleDateFormat(patten, ((bLocale && defaultLocale) ? *defaultLocale : Locale::getEnglish()), ec); + if (U_SUCCESS(ec)) { + fmt->setCalendar(*myCalendar); + fmt->format(myCalendar->getTime(ec), str); + delete fmt; + + if (U_SUCCESS(ec)) { + std::string result = util.toString(str); + str.remove(); + LoggerD (result); + return result; + } + } + ThrowMsg(Commons::PlatformException, "can't make SimpleDateFormat or can't get time"); +} + +std::string TZDate::getTimezoneAbbreviation() { + LoggerD("entered"); + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UnicodeString str; + TimeUtilTools util; + + myCalendar->getTimeZone().getDisplayName(isDST(), TimeZone::SHORT, Locale::getEnglish(), str); + if ((str != "GMT") && (str.length() > 3) && !str.compare(0, 3, "GMT")) + myCalendar->getTimeZone().getDisplayName(isDST(), TimeZone::LONG_GMT, Locale::getEnglish(), str); + std::string result = util.toString(str); + str.remove(); + LoggerD (result); + return result; +} + +long TZDate::secondsFromUTC() { + LoggerD("entered"); + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UErrorCode ec = U_ZERO_ERROR; + TimeUtilTools util; + + int32_t zoneOffset = myCalendar->get(UCAL_ZONE_OFFSET, ec); + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "can't get zone offset"); + + int32_t dstOffset = myCalendar->get(UCAL_DST_OFFSET, ec); + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "can't get dst offset"); + + long result = -((util.tolong(zoneOffset + dstOffset)) / MILLISTOSEC); + + LoggerD("result : " << result); + return result; +} + +bool TZDate::isDST() { + LoggerD("entered"); + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + UErrorCode ec = U_ZERO_ERROR; + TimeUtilTools util; + UBool result = myCalendar->inDaylightTime(ec); + + if (!U_SUCCESS(ec)) + ThrowMsg(Commons::PlatformException, "can't inDaylightTime value from ICU"); + + return static_cast<bool>(result); +} + +TZDateProperties TZDate::getDSTTransition(DSTTransition trans) { + LoggerD("entered"); + if (myCalendar == NULL) + ThrowMsg(Commons::UnknownException, "Invalid Date"); + + TimeUtilTools util; + UErrorCode ec = U_ZERO_ERROR; + TZDateProperties props; + UDate dstTransitionDate = myCalendar->getTime(ec); + UBool result = false; + + if (U_SUCCESS(ec)) { + UnicodeString *id = util.toUnicodeString(getTimezone()); + + VTimeZone *vtz = VTimeZone::createVTimeZoneByID(*id); + delete id; + + TimeZoneTransition tzTrans; + if (vtz->useDaylightTime() == TRUE) { + if (trans == NEXT_TRANSITION) + result = vtz->getNextTransition(dstTransitionDate, FALSE, tzTrans); + else + result = vtz->getPreviousTransition(dstTransitionDate, FALSE, tzTrans); + if (result == TRUE) { + LoggerD("result is TRUE"); + dstTransitionDate = tzTrans.getTime(); + } + } + delete vtz; + + if (result == false) + return props; + + Calendar *dstTransCalendar = myCalendar->clone(); + dstTransCalendar->setTime(dstTransitionDate, ec); + if (U_SUCCESS(ec)) { + props = _makeProperties(dstTransCalendar); + delete dstTransCalendar; + return props; + } + delete dstTransCalendar; + } + ThrowMsg(Commons::PlatformException, "can't getDSTTransition value from ICU"); +} + +} +} |