diff options
author | Hoa V. DINH <dinh.viet.hoa@gmail.com> | 2013-04-28 15:57:20 -0700 |
---|---|---|
committer | Hoa V. DINH <dinh.viet.hoa@gmail.com> | 2013-04-28 15:57:51 -0700 |
commit | 3e01b4e601a509aa54fa59f6391dcb99d9286de3 (patch) | |
tree | e4d0c1ad80071fc8af144f44d8584cff81861a5b /src/core/renderer | |
parent | 7960dcf785f9e3db796c2029e1900a0b065ff6dd (diff) |
Workaround ICU issue on iOS by implementing date formatter using CoreFoundation on Apple platforms
Diffstat (limited to 'src/core/renderer')
-rw-r--r-- | src/core/renderer/MCDateFormatter.cpp | 89 | ||||
-rw-r--r-- | src/core/renderer/MCDateFormatter.h | 5 |
2 files changed, 92 insertions, 2 deletions
diff --git a/src/core/renderer/MCDateFormatter.cpp b/src/core/renderer/MCDateFormatter.cpp index 5d4ab2fb..065224d3 100644 --- a/src/core/renderer/MCDateFormatter.cpp +++ b/src/core/renderer/MCDateFormatter.cpp @@ -10,6 +10,14 @@ #include <stdlib.h> #include <unicode/udat.h> +#if defined(__APPLE__) +#define USE_COREFOUNDATION 1 +#endif + +#if USE_COREFOUNDATION +#include <CoreFoundation/CoreFoundation.h> +#endif + using namespace mailcore; DateFormatter::DateFormatter() @@ -20,10 +28,16 @@ DateFormatter::DateFormatter() mDateFormat = NULL; mTimezone = NULL; mLocale = NULL; + mAppleDateFormatter = NULL; } DateFormatter::~DateFormatter() { +#if USE_COREFOUNDATION + if (mAppleDateFormatter != NULL) { + CFRelease(mAppleDateFormatter); + } +#endif if (mDateFormatter != NULL) { udat_close(mDateFormatter); } @@ -93,6 +107,21 @@ String * DateFormatter::dateFormat() String * DateFormatter::stringFromDate(time_t date) { prepare(); +#if USE_COREFOUNDATION + if (mAppleDateFormatter == NULL) + return NULL; + + CFDateRef dateRef = CFDateCreate(NULL, (CFAbsoluteTime) date - kCFAbsoluteTimeIntervalSince1970); + CFStringRef string = CFDateFormatterCreateStringWithDate(NULL, (CFDateFormatterRef) mAppleDateFormatter, dateRef); + CFIndex len = CFStringGetLength(string); + UniChar * buffer = (UniChar *) malloc(sizeof(* buffer) * len); + CFStringGetCharacters(string, CFRangeMake(0, len), buffer); + String * result = String::stringWithCharacters(buffer, (unsigned int) len); + free(buffer); + CFRelease(string); + CFRelease(dateRef); + return result; +#else if (mDateFormatter == NULL) return NULL; @@ -112,11 +141,31 @@ String * DateFormatter::stringFromDate(time_t date) result->autorelease(); return result; +#endif } time_t DateFormatter::dateFromString(String * dateString) { prepare(); +#if USE_COREFOUNDATION + if (mAppleDateFormatter == NULL) + return (time_t) -1; + + CFAbsoluteTime absoluteTime; + bool r; + time_t result; + CFStringRef dateCFString = CFStringCreateWithCharacters(NULL, (const UniChar *) dateString->unicodeCharacters(), + dateString->length()); + r = CFDateFormatterGetAbsoluteTimeFromString((CFDateFormatterRef) mAppleDateFormatter, dateCFString, + NULL, &absoluteTime); + result = (time_t) -1; + if (r) { + result = (time_t) absoluteTime + kCFAbsoluteTimeIntervalSince1970; + } + CFRelease(dateCFString); + + return result; +#else if (mDateFormatter == NULL) return (time_t) -1; @@ -128,7 +177,27 @@ time_t DateFormatter::dateFromString(String * dateString) } return date / 1000.; +#endif +} + +#if USE_COREFOUNDATION +static CFDateFormatterStyle toAppleStyle(DateFormatStyle style) +{ + switch (style) { + case DateFormatStyleFull: + return kCFDateFormatterFullStyle; + case DateFormatStyleLong: + return kCFDateFormatterLongStyle; + case DateFormatStyleMedium: + return kCFDateFormatterMediumStyle; + case DateFormatStyleShort: + return kCFDateFormatterShortStyle; + case DateFormatStyleNone: + return kCFDateFormatterNoStyle; + } + return kCFDateFormatterMediumStyle; } +#endif void DateFormatter::prepare() { @@ -154,9 +223,29 @@ void DateFormatter::prepare() locale = mLocale->UTF8Characters(); } +#if USE_COREFOUNDATION + CFStringRef localeIdentifier = NULL; + CFLocaleRef localeRef = NULL; + if (mLocale != NULL) { + localeIdentifier = CFStringCreateWithCharacters(NULL, (const UniChar *) mLocale->unicodeCharacters(), + mLocale->length()); + localeRef = CFLocaleCreate(NULL, localeIdentifier); + } + if (localeRef == NULL) { + localeRef = CFLocaleCopyCurrent(); + } + mAppleDateFormatter = CFDateFormatterCreate(NULL, localeRef, toAppleStyle(mDateStyle), toAppleStyle(mTimeStyle)); + if (localeIdentifier != NULL) { + CFRelease(localeIdentifier); + } + if (locale != NULL) { + CFRelease(locale); + } +#else mDateFormatter = udat_open((UDateFormatStyle) mTimeStyle, (UDateFormatStyle) mDateStyle, locale, tzID, tzIDLength, pattern, patternLength, &err); +#endif } diff --git a/src/core/renderer/MCDateFormatter.h b/src/core/renderer/MCDateFormatter.h index eb33fe52..4c5a7140 100644 --- a/src/core/renderer/MCDateFormatter.h +++ b/src/core/renderer/MCDateFormatter.h @@ -6,8 +6,8 @@ // Copyright (c) 2013 MailCore. All rights reserved. // -#ifndef __testUI__MCDateFormatter__ -#define __testUI__MCDateFormatter__ +#ifndef __MAILCORE_MCDATEFORMATTER_H_ +#define __MAILCORE_MCDATEFORMATTER_H_ #include <MailCore/MCBaseTypes.h> @@ -62,6 +62,7 @@ namespace mailcore { String * mDateFormat; String * mTimezone; String * mLocale; + void * mAppleDateFormatter; void prepare(); }; |