Merge "sync code for tizen_2.2" into devel_3.0_main
[platform/framework/native/appfw.git] / src / locales / FLcl_DateTimeFormatterImpl.cpp
index 0c3f4cd..87ae03e 100644 (file)
 
 // Includes
 #include <unique_ptr.h>
+#include <unicode/dtfmtsym.h>
+#include <unicode/smpdtfmt.h>
+#include <unicode/calendar.h>
+
 #include <FBaseSysLog.h>
 #include <FApp_AppInfo.h>
 #include <FLclDateTimeFormatter.h>
 #include "FLcl_DateTimeFormatterImpl.h"
 #include "FLcl_LocaleData.h"
 #include "FLcl_LocaleManagerImpl.h"
+#include "FLcl_CalendarImpl.h"
+#include "FLcl_IcuCalendarImpl.h"
+#include "FLcl_DateTimeSymbolsImpl.h"
 
 using namespace Tizen::Base;
 using namespace Tizen::Base::Collection;
@@ -36,15 +43,17 @@ namespace Tizen { namespace Locales
 {
 
 _DateTimeFormatterImpl::_DateTimeFormatterImpl(void)
-       : __pLocaleData(null)
-       , __pSymbols(null)
+       : __pSymbols(null)
+       , __pIcuDateFormatter(null)
+       , __pLocale(null)
 {
 }
 
 _DateTimeFormatterImpl::~_DateTimeFormatterImpl(void)
 {
-       delete __pLocaleData;
        delete __pSymbols;
+       delete __pIcuDateFormatter;
+       delete __pLocale;
 }
 
 // The DateTimeFormatter always use System Locale if not provided by the user.
@@ -77,93 +86,151 @@ _DateTimeFormatterImpl::CreateInstanceN(const Locale& locale, DateTimeStyle date
 {
        result r = (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat()) ? E_UNSUPPORTED_OPERATION : E_INVALID_ARG;
 
+       SysTryReturn(NID_LCL, locale.GetLanguageCode() != LANGUAGE_INVALID && locale.GetCountryCode() != COUNTRY_INVALID, null, r, "It is the invalid locale.");
        SysTryReturn(NID_LCL, ValidateDateTimeStyle(dateStyle), null, r, "[%s] Invalid argument is used. dateStyle is invalid", GetErrorMessage(r));
        SysTryReturn(NID_LCL, ValidateDateTimeStyle(timeStyle), null, r, "[%s] Invalid argument is used. timeStyle is invalid", GetErrorMessage(r));
 
        ClearLastResult();
 
-       // Create a DateTimeFormatter of the desired style.
        std::unique_ptr<DateTimeFormatter> pDateTimeFormatter(new (std::nothrow) DateTimeFormatter());
        SysTryReturn(NID_LCL, pDateTimeFormatter, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
 
        std::unique_ptr<_DateTimeFormatterImpl> pDateTimeFormatterImpl(new (std::nothrow) _DateTimeFormatterImpl);
        SysTryReturn(NID_LCL,pDateTimeFormatterImpl, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
 
-       std::unique_ptr<_LocaleData> pLocaleData(new (std::nothrow) _LocaleData);
-       SysTryReturn(NID_LCL, pLocaleData, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
+       std::unique_ptr< U_ICU_NAMESPACE::SimpleDateFormat> pIcuDateFormatter(pDateTimeFormatterImpl->GetIcuDateFormatterN(locale, dateStyle, timeStyle));
+       SysTryReturn(NID_LCL, pIcuDateFormatter, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
+
+       pDateTimeFormatterImpl->__pLocale = new (std::nothrow) Locale(locale);
+       SysTryReturn(NID_LCL, pDateTimeFormatterImpl->__pLocale, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
+       pDateTimeFormatterImpl->__pIcuDateFormatter = pIcuDateFormatter.release();
+       pDateTimeFormatter->__pDateTimeFormatterImpl = pDateTimeFormatterImpl.release();
+       return pDateTimeFormatter.release();      // Here as LastResult is already cleared, no need to set it to E_SUCCESS
+}
+
+U_ICU_NAMESPACE::SimpleDateFormat*
+_DateTimeFormatterImpl::GetIcuDateFormatterN(const Locale& locale, DateTimeStyle dateStyle, DateTimeStyle timeStyle)
+{
+       SysTryReturn(NID_LCL, dateStyle != DATE_TIME_STYLE_NONE || timeStyle != DATE_TIME_STYLE_NONE, null, E_INVALID_ARG, "It is an invalid argument.");
 
-       // This create and set ICU DateFormatter in _Locale data object for future use
-       r = pLocaleData->SetDateTimeFormatter(dateStyle, timeStyle, locale);
-       SysTryReturn(NID_LCL, !IsFailed(r), null, r, "[%s]",GetErrorMessage(r));
+       U_ICU_NAMESPACE::DateFormat* pIcuDateFormat = null;
+       U_ICU_NAMESPACE::DateFormat::EStyle icuDateStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) dateStyle;
+       U_ICU_NAMESPACE::DateFormat::EStyle icuTimeStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) timeStyle;
+       U_ICU_NAMESPACE::Locale icuLocale = _LocaleData::GetIcuLocale(locale);
 
-       // Create DateTimeSymbols and construct using locale
-       pDateTimeFormatterImpl->__pSymbols = new (std::nothrow) DateTimeSymbols;
-       if (pDateTimeFormatterImpl->__pSymbols)
+       if (dateStyle != DATE_TIME_STYLE_NONE && timeStyle != DATE_TIME_STYLE_NONE)
        {
-               pDateTimeFormatterImpl->__pSymbols->Construct(locale);
+               pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createDateTimeInstance(icuDateStyle, icuTimeStyle, icuLocale);
+       }
+       else if (dateStyle != DATE_TIME_STYLE_NONE && timeStyle == DATE_TIME_STYLE_NONE)
+       {
+               pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createDateInstance(icuDateStyle, icuLocale);
+       }
+       else if (dateStyle == DATE_TIME_STYLE_NONE && timeStyle != DATE_TIME_STYLE_NONE)
+       {
+               pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createTimeInstance(icuTimeStyle, icuLocale);
        }
 
-       pDateTimeFormatter->__pDateTimeFormatterImpl = pDateTimeFormatterImpl.release();
-       pDateTimeFormatter->__pDateTimeFormatterImpl->__pLocaleData = pLocaleData.release();
-       return pDateTimeFormatter.release();      // Here as LastResult is already cleared, no need to set it to E_SUCCESS
+       return dynamic_cast< U_ICU_NAMESPACE::SimpleDateFormat* >(pIcuDateFormat);
 }
 
+
 // This function will not have TimeZone informations and always print time zone as GMT+00:00
 result
 _DateTimeFormatterImpl::Format(const DateTime& date, String& strBuf) const
 {
-       SysAssertf(__pLocaleData != null, "Not yet constructed! Construct() should be called before use.");
-       return __pLocaleData->FormatDateTime(date, strBuf);   // Format date using ICU date formatter
+       SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
+
+       std::unique_ptr< Calendar > pCal(Calendar::CreateInstanceN());
+       SysTryReturnResult(NID_LCL, pCal, E_OUT_OF_MEMORY, "Memory allocation failed");
+
+       result r = pCal->SetTime(date);
+       SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar", GetErrorMessage(r));
+
+       r = pCal->Clear(TIME_FIELD_MILLISECOND);
+       SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar", GetErrorMessage(r));
+
+       return Format(*(pCal.get()), strBuf);
 }
 
 result
 _DateTimeFormatterImpl::Format(const Calendar& calendar, String& strBuf) const
 {
-       SysAssertf(__pLocaleData != null, "Not yet constructed! Construct() should be called before use.");
-       return __pLocaleData->FormatDateTime(calendar, strBuf);   // Format date using ICU date formatter
+       SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
+
+       const _IcuCalendarImpl* pIcuCalendarImpl = _CalendarImpl::GetImpl(calendar);
+       SysTryReturnResult(NID_LCL, pIcuCalendarImpl, E_SYSTEM, "It is failed to get icu calendar.");
+
+       IcuCalendar* pIcuCal = pIcuCalendarImpl->GetIcuCalendarCloneN();
+       SysTryReturnResult(NID_LCL, pIcuCal, E_SYSTEM, "It is failed to get icu calendar.");
+
+       IcuFieldPosition icuFp;
+       IcuUnicodeString icuStr = _LocaleData::GetIcuString(strBuf);
+       icuStr = __pIcuDateFormatter->format(*pIcuCal, icuStr, icuFp);
+       strBuf = _LocaleData::GetOspString(icuStr);
+       delete pIcuCal;
+
+       return E_SUCCESS;
 }
 
-// This function sets pattern used by DateTimeFormatter for formatting date.
-// Please check http://icu-project.org/apiref/icu4c/classSimpleDateFormat.html for possible letter and
-// their meaning in patter string.
 result
 _DateTimeFormatterImpl::ApplyPattern(const String& pattern)
 {
-       SysAssertf(__pLocaleData != null, "Not yet constructed! Construct() should be called before use.");
-       return __pLocaleData->SetDateTimePattern(pattern);      // Set pattern to ICU date formatter
+       SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
+       U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(pattern);
+       __pIcuDateFormatter->applyPattern(icuStr);
+       return E_SUCCESS;
 }
 
 String
 _DateTimeFormatterImpl::GetPattern(void) const
 {
-       return __pLocaleData->GetDateTimePattern();
+       SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
+       IcuUnicodeString icuPattern;
+       icuPattern = __pIcuDateFormatter->toPattern(icuPattern);
+       return _LocaleData::GetOspString(icuPattern);
 }
 
 const DateTimeSymbols*
-_DateTimeFormatterImpl::GetDateTimeSymbols(void) const
+_DateTimeFormatterImpl::GetDateTimeSymbols(void)
 {
+       SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
+       if (__pSymbols == null)
+       {
+               std::unique_ptr< DateTimeSymbols > pSymbols(new (std::nothrow) DateTimeSymbols);
+               SysTryReturn(NID_LCL, pSymbols, null, E_OUT_OF_MEMORY, "It is not enough memory.");
+               pSymbols->Construct(*__pLocale);
+               __pSymbols = pSymbols.release();
+       }
        return __pSymbols;
 }
 
 void
 _DateTimeFormatterImpl::SetDateTimeSymbols(const DateTimeSymbols& newSymbols)
 {
-       SysAssertf(__pLocaleData != null, "Not yet constructed! Construct() should be called before use.");
+       SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
+
+       std::unique_ptr< DateTimeSymbols > pSymbols(new (std::nothrow) DateTimeSymbols);
+       SysTryReturn(NID_LCL, pSymbols, , E_OUT_OF_MEMORY, "It is not enough memory.");
+       result r = pSymbols->Construct(newSymbols);
+       SysTryReturn(NID_LCL, r == E_SUCCESS, , r, "[%s] occured.", GetErrorMessage(r));
+
+       _DateTimeSymbolsImpl* pDateTimeSymbolsImpl = _DateTimeSymbolsImpl::GetDateTimeSymbolsImpl(pSymbols.get());
+       const U_ICU_NAMESPACE::DateFormatSymbols* pIcuSymbols = pDateTimeSymbolsImpl->GetIcuSymbols();
+
+       __pIcuDateFormatter->setDateFormatSymbols(*pIcuSymbols);
 
-       result r = __pLocaleData->SetDateTimeSymbols(newSymbols);                   // Set symbols to ICU date formatter
-       if (!IsFailed(r))
+       if (__pSymbols)
        {
-               if (__pSymbols)
-               {
-                       __pSymbols = __pLocaleData->GetDateTimeSymbolsN(__pSymbols);        // Set __pSymbols obtained from ICU date formatter
-               }
+               delete __pSymbols;
        }
+       __pSymbols = pSymbols.release();
 }
 
 bool
 _DateTimeFormatterImpl::ValidateDateTimeStyle(DateTimeStyle dateTimeStyle)
 {
-       return (dateTimeStyle < DATE_TIME_STYLE_NONE || dateTimeStyle > DATE_TIME_STYLE_SHORT)? false : true;
+       return (dateTimeStyle < DATE_TIME_STYLE_NONE || dateTimeStyle > DATE_TIME_STYLE_SHORT) ? false : true;
 }
 
 };