/* * Copyright 2010-2014, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Oliver Tappe */ #include #include #include #include #include #include #include #include #include #include #include U_NAMESPACE_USE BDateTimeFormat::BDateTimeFormat(const BLocale* locale) : BFormat(locale) { } BDateTimeFormat::BDateTimeFormat(const BLanguage& language, const BFormattingConventions& conventions) : BFormat(language, conventions) { } BDateTimeFormat::BDateTimeFormat(const BDateTimeFormat &other) : BFormat(other) { } BDateTimeFormat::~BDateTimeFormat() { } void BDateTimeFormat::SetDateTimeFormat(BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle, int32 elements) { UErrorCode error = U_ZERO_ERROR; DateTimePatternGenerator* generator = DateTimePatternGenerator::createInstance( *BLanguage::Private(&fLanguage).ICULocale(), error); BString skeleton; if (elements & B_DATE_ELEMENT_YEAR) skeleton << "yyyy"; if (elements & B_DATE_ELEMENT_MONTH) skeleton << "MM"; if (elements & B_DATE_ELEMENT_WEEKDAY) skeleton << "eee"; if (elements & B_DATE_ELEMENT_DAY) skeleton << "dd"; if (elements & B_DATE_ELEMENT_AM_PM) skeleton << "a"; if (elements & B_DATE_ELEMENT_HOUR) { if (fConventions.Use24HourClock()) skeleton << "k"; else skeleton << "K"; } if (elements & B_DATE_ELEMENT_MINUTE) skeleton << "mm"; if (elements & B_DATE_ELEMENT_SECOND) skeleton << "ss"; if (elements & B_DATE_ELEMENT_TIMEZONE) skeleton << "z"; UnicodeString pattern = generator->getBestPattern( UnicodeString::fromUTF8(skeleton.String()), error); BString buffer; BStringByteSink stringConverter(&buffer); pattern.toUTF8(stringConverter); fConventions.SetExplicitDateTimeFormat(dateStyle, timeStyle, buffer); delete generator; } // #pragma mark - Formatting ssize_t BDateTimeFormat::Format(char* target, size_t maxSize, time_t time, BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const { BString format; fConventions.GetDateTimeFormat(dateStyle, timeStyle, format); ObjectDeleter dateFormatter(_CreateDateTimeFormatter(format)); if (!dateFormatter.IsSet()) return B_NO_MEMORY; UnicodeString icuString; dateFormatter->format((UDate)time * 1000, icuString); CheckedArrayByteSink stringConverter(target, maxSize); icuString.toUTF8(stringConverter); if (stringConverter.Overflowed()) return B_BAD_VALUE; return stringConverter.NumberOfBytesWritten(); } status_t BDateTimeFormat::Format(BString& target, const time_t time, BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle, const BTimeZone* timeZone) const { BString format; fConventions.GetDateTimeFormat(dateStyle, timeStyle, format); ObjectDeleter dateFormatter(_CreateDateTimeFormatter(format)); if (!dateFormatter.IsSet()) return B_NO_MEMORY; if (timeZone != NULL) { ObjectDeleter icuTimeZone( TimeZone::createTimeZone(timeZone->ID().String())); if (!icuTimeZone.IsSet()) return B_NO_MEMORY; dateFormatter->setTimeZone(*icuTimeZone.Get()); } UnicodeString icuString; dateFormatter->format((UDate)time * 1000, icuString); target.Truncate(0); BStringByteSink stringConverter(&target); icuString.toUTF8(stringConverter); return B_OK; } DateFormat* BDateTimeFormat::_CreateDateTimeFormatter(const BString& format) const { Locale* icuLocale = fConventions.UseStringsFromPreferredLanguage() ? BLanguage::Private(&fLanguage).ICULocale() : BFormattingConventions::Private(&fConventions).ICULocale(); icu::DateFormat* dateFormatter = icu::DateFormat::createDateTimeInstance( DateFormat::kDefault, DateFormat::kDefault, *icuLocale); if (dateFormatter == NULL) return NULL; SimpleDateFormat* dateFormatterImpl = static_cast(dateFormatter); UnicodeString pattern(format.String()); dateFormatterImpl->applyPattern(pattern); return dateFormatter; }