diff --git a/headers/os/locale/DurationFormat.h b/headers/os/locale/DurationFormat.h index 0cb6be8812..edaa2041f3 100644 --- a/headers/os/locale/DurationFormat.h +++ b/headers/os/locale/DurationFormat.h @@ -35,8 +35,9 @@ public: virtual status_t SetLanguage(const BLanguage& language); status_t SetTimeZone(const BTimeZone* timeZone); - status_t Format(bigtime_t startValue, - bigtime_t stopValue, BString* buffer, + status_t Format(BString& buffer, + const bigtime_t startValue, + const bigtime_t stopValue, time_unit_style style = B_TIME_UNIT_FULL ) const; diff --git a/headers/os/locale/Locale.h b/headers/os/locale/Locale.h index e4c26cf5b3..55b1639e64 100644 --- a/headers/os/locale/Locale.h +++ b/headers/os/locale/Locale.h @@ -69,27 +69,6 @@ public: BTimeFormatStyle timeStyle, const BTimeZone* timeZone = NULL) const; - // Time - - // TODO: drop some of these once BTimeFormat - // has been implemented! - ssize_t FormatTime(char* string, size_t maxSize, - time_t time, BTimeFormatStyle style) const; - ssize_t FormatTime(char* string, size_t maxSize, - time_t time, BString format) const; - status_t FormatTime(BString* string, time_t time, - BTimeFormatStyle style, - const BTimeZone* timeZone = NULL) const; - status_t FormatTime(BString* string, time_t time, - BString format, - const BTimeZone* timeZone) const; - status_t FormatTime(BString* string, - int*& fieldPositions, int& fieldCount, - time_t time, BTimeFormatStyle style) const; - status_t GetTimeFields(BDateElement*& fields, - int& fieldCount, BTimeFormatStyle style - ) const; - // numbers ssize_t FormatNumber(char* string, size_t maxSize, diff --git a/headers/os/locale/TimeFormat.h b/headers/os/locale/TimeFormat.h index 1556aa837b..df6bb8ff59 100644 --- a/headers/os/locale/TimeFormat.h +++ b/headers/os/locale/TimeFormat.h @@ -1,5 +1,5 @@ /* - * Copyright 2010, Haiku, Inc. + * Copyright 2010-2014, Haiku, Inc. * Distributed under the terms of the MIT Licence. */ #ifndef _B_TIME_FORMAT_H_ @@ -9,20 +9,41 @@ class BString; +class BTimeZone; -class BTimeFormat : public BDateTimeFormat { +class BTimeFormat : public BFormat { public: + BTimeFormat( + const BLanguage* const language = NULL, + const BFormattingConventions* const + format = NULL); BTimeFormat(const BTimeFormat &other); virtual ~BTimeFormat(); // formatting - // no-frills version: Simply appends the - // formatted date to the string buffer. - // Can fail only with B_NO_MEMORY or B_BAD_VALUE. - virtual status_t Format(bigtime_t value, BString* buffer) const; + ssize_t Format(char* string, size_t maxSize, + time_t time, BTimeFormatStyle style) const; + ssize_t Format(char* string, size_t maxSize, + time_t time, BString format) const; + status_t Format(BString& string, const time_t time, + const BTimeFormatStyle style, + const BTimeZone* timeZone = NULL) const; + status_t Format(BString& string, const time_t time, + const BString format, + const BTimeZone* timeZone) const; + status_t Format(BString& string, + int*& fieldPositions, int& fieldCount, + time_t time, BTimeFormatStyle style) const; - // TODO: ... basically, all of it! + status_t GetTimeFields(BDateElement*& fields, + int& fieldCount, BTimeFormatStyle style + ) const; + + // TODO parsing +private: + icu::DateFormat* _CreateTimeFormatter( + const BString& format) const; }; diff --git a/headers/os/locale/TimeUnitFormat.h b/headers/os/locale/TimeUnitFormat.h index 1c3f9a3b43..0aefbcd168 100644 --- a/headers/os/locale/TimeUnitFormat.h +++ b/headers/os/locale/TimeUnitFormat.h @@ -47,8 +47,9 @@ public: BTimeUnitFormat& operator=(const BTimeUnitFormat& other); virtual status_t SetLanguage(const BLanguage& locale); - status_t Format(int32 value, time_unit_element unit, - BString* buffer, + status_t Format(BString& buffer, + const int32 value, + const time_unit_element unit, time_unit_style style = B_TIME_UNIT_FULL ) const; diff --git a/src/apps/aboutsystem/AboutSystem.cpp b/src/apps/aboutsystem/AboutSystem.cpp index 58b0bfc5d0..38a59c9861 100644 --- a/src/apps/aboutsystem/AboutSystem.cpp +++ b/src/apps/aboutsystem/AboutSystem.cpp @@ -1612,7 +1612,7 @@ UptimeToString(char string[], size_t size) bigtime_t uptime = system_time(); bigtime_t now = (bigtime_t)time(NULL) * 1000000; - formatter.Format(now - uptime, now, &str); + formatter.Format(str, now - uptime, now); str.CopyInto(string, 0, size); string[std::min((size_t)str.Length(), size)] = '\0'; diff --git a/src/apps/deskbar/TimeView.cpp b/src/apps/deskbar/TimeView.cpp index 1e89ee5c95..e7d6003034 100644 --- a/src/apps/deskbar/TimeView.cpp +++ b/src/apps/deskbar/TimeView.cpp @@ -40,7 +40,6 @@ All rights reserved. #include #include -#include #include #include #include @@ -391,27 +390,27 @@ TTimeView::GetCurrentTime() if (fShowDayOfWeek) { BString timeFormat("eee "); - offset_dow = fLocale.FormatTime(fCurrentTimeStr, + offset_dow = fTimeFormat.Format(fCurrentTimeStr, sizeof(fCurrentTimeStr), fCurrentTime, timeFormat); if (offset_dow < 0) { // error occured, attempt to overwrite with current time // (this should not ever happen) - fLocale.FormatTime(fCurrentTimeStr, sizeof(fCurrentTimeStr), + fTimeFormat.Format(fCurrentTimeStr, sizeof(fCurrentTimeStr), fCurrentTime, fShowSeconds ? B_MEDIUM_TIME_FORMAT : B_SHORT_TIME_FORMAT); return; } } - offset_time = fLocale.FormatTime(fCurrentTimeStr + offset_dow, + offset_time = fTimeFormat.Format(fCurrentTimeStr + offset_dow, sizeof(fCurrentTimeStr) - offset_dow, fCurrentTime, fShowSeconds ? B_MEDIUM_TIME_FORMAT : B_SHORT_TIME_FORMAT); if (fShowTimeZone) { BString timeFormat(" V"); ssize_t offset = offset_dow + offset_time; - fLocale.FormatTime(fCurrentTimeStr + offset, + fTimeFormat.Format(fCurrentTimeStr + offset, sizeof(fCurrentTimeStr) - offset, fCurrentTime, timeFormat); } } @@ -490,6 +489,7 @@ TTimeView::Update() { fLocale = *BLocale::Default(); fDateFormat.SetLocale(fLocale); + fTimeFormat.SetLocale(fLocale); GetCurrentTime(); GetCurrentDate(); diff --git a/src/apps/deskbar/TimeView.h b/src/apps/deskbar/TimeView.h index 53285854e0..7dde15809f 100644 --- a/src/apps/deskbar/TimeView.h +++ b/src/apps/deskbar/TimeView.h @@ -40,6 +40,7 @@ All rights reserved. #include #include #include +#include #include @@ -150,6 +151,7 @@ private: // For date and time localization purposes BLocale fLocale; BDateFormat fDateFormat; + BTimeFormat fTimeFormat; }; diff --git a/src/bin/dstcheck.cpp b/src/bin/dstcheck.cpp index 135b84b030..a6cbf6efcc 100644 --- a/src/bin/dstcheck.cpp +++ b/src/bin/dstcheck.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -79,7 +80,8 @@ TimedAlert::GetLabel(BString &string) { string = B_TRANSLATE("Attention!\n\nBecause of the switch from daylight " "saving time, your computer's clock may be an hour off.\n" - "Your computer thinks it is"); + "Your computer thinks it is %current time%.\n\nIs this the correct " + "time?"); time_t t; struct tm tm; @@ -87,12 +89,9 @@ TimedAlert::GetLabel(BString &string) time(&t); localtime_r(&t, &tm); - BLocale::Default()->FormatTime(timestring, 15, t, B_SHORT_TIME_FORMAT); + BTimeFormat().Format(timestring, 15, t, B_SHORT_TIME_FORMAT); - string += " "; - string += timestring; - - string += B_TRANSLATE(".\n\nIs this the correct time?"); + string.ReplaceFirst("%current time%", timestring); } diff --git a/src/kits/locale/DurationFormat.cpp b/src/kits/locale/DurationFormat.cpp index 0e00de2a95..c8ac6d623d 100644 --- a/src/kits/locale/DurationFormat.cpp +++ b/src/kits/locale/DurationFormat.cpp @@ -130,12 +130,9 @@ BDurationFormat::SetTimeZone(const BTimeZone* timeZone) status_t -BDurationFormat::Format(bigtime_t startValue, bigtime_t stopValue, - BString* buffer, time_unit_style style) const +BDurationFormat::Format(BString& buffer, const bigtime_t startValue, + const bigtime_t stopValue, time_unit_style style) const { - if (buffer == NULL) - return B_BAD_VALUE; - UErrorCode icuStatus = U_ZERO_ERROR; fCalendar->setTime((UDate)startValue / 1000, icuStatus); if (!U_SUCCESS(icuStatus)) @@ -151,11 +148,11 @@ BDurationFormat::Format(bigtime_t startValue, bigtime_t stopValue, if (delta != 0) { if (needSeparator) - buffer->Append(fSeparator); + buffer.Append(fSeparator); else needSeparator = true; - status_t status = fTimeUnitFormat.Format(delta, - (time_unit_element)unit, buffer, style); + status_t status = fTimeUnitFormat.Format(buffer, delta, + (time_unit_element)unit, style); if (status != B_OK) return status; } diff --git a/src/kits/locale/Locale.cpp b/src/kits/locale/Locale.cpp index 061924aa67..9115db2dc9 100644 --- a/src/kits/locale/Locale.cpp +++ b/src/kits/locale/Locale.cpp @@ -265,239 +265,6 @@ BLocale::FormatDateTime(BString* target, time_t time, } -// #pragma mark - Time - - -ssize_t -BLocale::FormatTime(char* string, size_t maxSize, time_t time, - BTimeFormatStyle style) const -{ - BAutolock lock(fLock); - if (!lock.IsLocked()) - return B_ERROR; - - BString format; - fConventions.GetTimeFormat(style, format); - ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - UnicodeString icuString; - timeFormatter->format((UDate)time * 1000, icuString); - - CheckedArrayByteSink stringConverter(string, maxSize); - icuString.toUTF8(stringConverter); - - if (stringConverter.Overflowed()) - return B_BAD_VALUE; - - return stringConverter.NumberOfBytesWritten(); -} - - -ssize_t -BLocale::FormatTime(char* string, size_t maxSize, time_t time, - BString format) const -{ - BAutolock lock(fLock); - if (!lock.IsLocked()) - return B_ERROR; - - if (format == NULL || format.CountChars() <= 0) - return B_BAD_VALUE; - - ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - UnicodeString icuString; - timeFormatter->format((UDate)time * 1000, icuString); - - CheckedArrayByteSink stringConverter(string, maxSize); - icuString.toUTF8(stringConverter); - - if (stringConverter.Overflowed()) - return B_BAD_VALUE; - - return stringConverter.NumberOfBytesWritten(); -} - - -status_t -BLocale::FormatTime(BString* string, time_t time, BTimeFormatStyle style, - const BTimeZone* timeZone) const -{ - BAutolock lock(fLock); - if (!lock.IsLocked()) - return B_ERROR; - - BString format; - fConventions.GetTimeFormat(style, format); - ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - if (timeZone != NULL) { - ObjectDeleter icuTimeZone( - TimeZone::createTimeZone(timeZone->ID().String())); - if (icuTimeZone.Get() == NULL) - return B_NO_MEMORY; - timeFormatter->setTimeZone(*icuTimeZone.Get()); - } - - UnicodeString icuString; - timeFormatter->format((UDate)time * 1000, icuString); - - string->Truncate(0); - BStringByteSink stringConverter(string); - icuString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BLocale::FormatTime(BString* string, time_t time, BString format, - const BTimeZone* timeZone) const -{ - BAutolock lock(fLock); - if (!lock.IsLocked()) - return B_ERROR; - - if (format == NULL || format.CountChars() <= 0) - return B_BAD_VALUE; - - ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - if (timeZone != NULL) { - ObjectDeleter icuTimeZone( - TimeZone::createTimeZone(timeZone->ID().String())); - if (icuTimeZone.Get() == NULL) - return B_NO_MEMORY; - timeFormatter->setTimeZone(*icuTimeZone.Get()); - } - - UnicodeString icuString; - timeFormatter->format((UDate)time * 1000, icuString); - - string->Truncate(0); - BStringByteSink stringConverter(string); - icuString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BLocale::FormatTime(BString* string, int*& fieldPositions, int& fieldCount, - time_t time, BTimeFormatStyle style) const -{ - BAutolock lock(fLock); - if (!lock.IsLocked()) - return B_ERROR; - - BString format; - fConventions.GetTimeFormat(style, format); - ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - fieldPositions = NULL; - UErrorCode error = U_ZERO_ERROR; - icu::FieldPositionIterator positionIterator; - UnicodeString icuString; - timeFormatter->format((UDate)time * 1000, icuString, &positionIterator, - error); - - if (error != U_ZERO_ERROR) - return B_BAD_VALUE; - - icu::FieldPosition field; - std::vector fieldPosStorage; - fieldCount = 0; - while (positionIterator.next(field)) { - fieldPosStorage.push_back(field.getBeginIndex()); - fieldPosStorage.push_back(field.getEndIndex()); - fieldCount += 2; - } - - fieldPositions = (int*) malloc(fieldCount * sizeof(int)); - - for (int i = 0 ; i < fieldCount ; i++ ) - fieldPositions[i] = fieldPosStorage[i]; - - string->Truncate(0); - BStringByteSink stringConverter(string); - icuString.toUTF8(stringConverter); - - return B_OK; -} - - -status_t -BLocale::GetTimeFields(BDateElement*& fields, int& fieldCount, - BTimeFormatStyle style) const -{ - BAutolock lock(fLock); - if (!lock.IsLocked()) - return B_ERROR; - - BString format; - fConventions.GetTimeFormat(style, format); - ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); - if (timeFormatter.Get() == NULL) - return B_NO_MEMORY; - - fields = NULL; - UErrorCode error = U_ZERO_ERROR; - icu::FieldPositionIterator positionIterator; - UnicodeString icuString; - time_t now; - timeFormatter->format((UDate)time(&now) * 1000, icuString, - &positionIterator, error); - - if (error != U_ZERO_ERROR) - return B_BAD_VALUE; - - icu::FieldPosition field; - std::vector fieldPosStorage; - fieldCount = 0; - while (positionIterator.next(field)) { - fieldPosStorage.push_back(field.getField()); - fieldCount ++; - } - - fields = (BDateElement*) malloc(fieldCount * sizeof(BDateElement)); - - for (int i = 0 ; i < fieldCount ; i++ ) { - switch (fieldPosStorage[i]) { - case UDAT_HOUR_OF_DAY1_FIELD: - case UDAT_HOUR_OF_DAY0_FIELD: - case UDAT_HOUR1_FIELD: - case UDAT_HOUR0_FIELD: - fields[i] = B_DATE_ELEMENT_HOUR; - break; - case UDAT_MINUTE_FIELD: - fields[i] = B_DATE_ELEMENT_MINUTE; - break; - case UDAT_SECOND_FIELD: - fields[i] = B_DATE_ELEMENT_SECOND; - break; - case UDAT_AM_PM_FIELD: - fields[i] = B_DATE_ELEMENT_AM_PM; - break; - default: - fields[i] = B_DATE_ELEMENT_INVALID; - break; - } - } - - return B_OK; -} - - // #pragma mark - Numbers diff --git a/src/kits/locale/TimeFormat.cpp b/src/kits/locale/TimeFormat.cpp index c99c5c063a..2f7301c929 100644 --- a/src/kits/locale/TimeFormat.cpp +++ b/src/kits/locale/TimeFormat.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2010, Haiku, Inc. All Rights Reserved. + * Copyright 2010-2014, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -8,21 +8,293 @@ #include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + + +BTimeFormat::BTimeFormat(const BLanguage* const language, + const BFormattingConventions* const conventions) +{ + if (conventions != NULL) + fConventions = *conventions; + + if (language != NULL) + fLanguage = *language; +} + -// copy constructor BTimeFormat::BTimeFormat(const BTimeFormat &other) - : BDateTimeFormat(other) + : BFormat(other) { } -// destructor + BTimeFormat::~BTimeFormat() { } -// Format -status_t -BTimeFormat::Format(bigtime_t value, BString* buffer) const + +// #pragma mark - Formatting + + +ssize_t +BTimeFormat::Format(char* string, size_t maxSize, time_t time, + BTimeFormatStyle style) const { - return B_ERROR; + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + BString format; + fConventions.GetTimeFormat(style, format); + ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + UnicodeString icuString; + timeFormatter->format((UDate)time * 1000, icuString); + + CheckedArrayByteSink stringConverter(string, maxSize); + icuString.toUTF8(stringConverter); + + if (stringConverter.Overflowed()) + return B_BAD_VALUE; + + return stringConverter.NumberOfBytesWritten(); +} + + +ssize_t +BTimeFormat::Format(char* string, size_t maxSize, time_t time, + BString format) const +{ + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + if (format == NULL || format.CountChars() <= 0) + return B_BAD_VALUE; + + ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + UnicodeString icuString; + timeFormatter->format((UDate)time * 1000, icuString); + + CheckedArrayByteSink stringConverter(string, maxSize); + icuString.toUTF8(stringConverter); + + if (stringConverter.Overflowed()) + return B_BAD_VALUE; + + return stringConverter.NumberOfBytesWritten(); +} + + +status_t +BTimeFormat::Format(BString& string, const time_t time, + const BTimeFormatStyle style, const BTimeZone* timeZone) const +{ + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + BString format; + fConventions.GetTimeFormat(style, format); + ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + if (timeZone != NULL) { + ObjectDeleter icuTimeZone( + TimeZone::createTimeZone(timeZone->ID().String())); + if (icuTimeZone.Get() == NULL) + return B_NO_MEMORY; + timeFormatter->setTimeZone(*icuTimeZone.Get()); + } + + UnicodeString icuString; + timeFormatter->format((UDate)time * 1000, icuString); + + string.Truncate(0); + BStringByteSink stringConverter(&string); + icuString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BTimeFormat::Format(BString& string, const time_t time, + const BString format, const BTimeZone* timeZone) const +{ + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + if (format == NULL || format.CountChars() <= 0) + return B_BAD_VALUE; + + ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + if (timeZone != NULL) { + ObjectDeleter icuTimeZone( + TimeZone::createTimeZone(timeZone->ID().String())); + if (icuTimeZone.Get() == NULL) + return B_NO_MEMORY; + timeFormatter->setTimeZone(*icuTimeZone.Get()); + } + + UnicodeString icuString; + timeFormatter->format((UDate)time * 1000, icuString); + + string.Truncate(0); + BStringByteSink stringConverter(&string); + icuString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BTimeFormat::Format(BString& string, int*& fieldPositions, int& fieldCount, + time_t time, BTimeFormatStyle style) const +{ + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + BString format; + fConventions.GetTimeFormat(style, format); + ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + fieldPositions = NULL; + UErrorCode error = U_ZERO_ERROR; + icu::FieldPositionIterator positionIterator; + UnicodeString icuString; + timeFormatter->format((UDate)time * 1000, icuString, &positionIterator, + error); + + if (error != U_ZERO_ERROR) + return B_BAD_VALUE; + + icu::FieldPosition field; + std::vector fieldPosStorage; + fieldCount = 0; + while (positionIterator.next(field)) { + fieldPosStorage.push_back(field.getBeginIndex()); + fieldPosStorage.push_back(field.getEndIndex()); + fieldCount += 2; + } + + fieldPositions = (int*) malloc(fieldCount * sizeof(int)); + + for (int i = 0 ; i < fieldCount ; i++ ) + fieldPositions[i] = fieldPosStorage[i]; + + string.Truncate(0); + BStringByteSink stringConverter(&string); + icuString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BTimeFormat::GetTimeFields(BDateElement*& fields, int& fieldCount, + BTimeFormatStyle style) const +{ + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + BString format; + fConventions.GetTimeFormat(style, format); + ObjectDeleter timeFormatter(_CreateTimeFormatter(format)); + if (timeFormatter.Get() == NULL) + return B_NO_MEMORY; + + fields = NULL; + UErrorCode error = U_ZERO_ERROR; + icu::FieldPositionIterator positionIterator; + UnicodeString icuString; + time_t now; + timeFormatter->format((UDate)time(&now) * 1000, icuString, + &positionIterator, error); + + if (error != U_ZERO_ERROR) + return B_BAD_VALUE; + + icu::FieldPosition field; + std::vector fieldPosStorage; + fieldCount = 0; + while (positionIterator.next(field)) { + fieldPosStorage.push_back(field.getField()); + fieldCount ++; + } + + fields = (BDateElement*) malloc(fieldCount * sizeof(BDateElement)); + + for (int i = 0 ; i < fieldCount ; i++ ) { + switch (fieldPosStorage[i]) { + case UDAT_HOUR_OF_DAY1_FIELD: + case UDAT_HOUR_OF_DAY0_FIELD: + case UDAT_HOUR1_FIELD: + case UDAT_HOUR0_FIELD: + fields[i] = B_DATE_ELEMENT_HOUR; + break; + case UDAT_MINUTE_FIELD: + fields[i] = B_DATE_ELEMENT_MINUTE; + break; + case UDAT_SECOND_FIELD: + fields[i] = B_DATE_ELEMENT_SECOND; + break; + case UDAT_AM_PM_FIELD: + fields[i] = B_DATE_ELEMENT_AM_PM; + break; + default: + fields[i] = B_DATE_ELEMENT_INVALID; + break; + } + } + + return B_OK; +} + + +DateFormat* +BTimeFormat::_CreateTimeFormatter(const BString& format) const +{ + Locale* icuLocale + = fConventions.UseStringsFromPreferredLanguage() + ? BLanguage::Private(&fLanguage).ICULocale() + : BFormattingConventions::Private(&fConventions).ICULocale(); + + icu::DateFormat* timeFormatter + = icu::DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale); + if (timeFormatter == NULL) + return NULL; + + SimpleDateFormat* timeFormatterImpl + = static_cast(timeFormatter); + + UnicodeString pattern(format.String()); + timeFormatterImpl->applyPattern(pattern); + + return timeFormatter; } diff --git a/src/kits/locale/TimeUnitFormat.cpp b/src/kits/locale/TimeUnitFormat.cpp index eebc35efe9..51a65d4501 100644 --- a/src/kits/locale/TimeUnitFormat.cpp +++ b/src/kits/locale/TimeUnitFormat.cpp @@ -101,10 +101,10 @@ BTimeUnitFormat::SetLanguage(const BLanguage& language) status_t -BTimeUnitFormat::Format(int32 value, time_unit_element unit, - BString* buffer, time_unit_style style) const +BTimeUnitFormat::Format(BString& buffer, const int32 value, + const time_unit_element unit, time_unit_style style) const { - if (buffer == NULL || unit < 0 || unit > B_TIME_UNIT_LAST + if (unit < 0 || unit > B_TIME_UNIT_LAST || (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL)) return B_BAD_VALUE; @@ -127,7 +127,7 @@ BTimeUnitFormat::Format(int32 value, time_unit_element unit, if (!U_SUCCESS(icuStatus)) return B_ERROR; - BStringByteSink byteSink(buffer); + BStringByteSink byteSink(&buffer); unicodeResult.toUTF8(byteSink); return B_OK; diff --git a/src/kits/tracker/StatusWindow.cpp b/src/kits/tracker/StatusWindow.cpp index 68a2b3ea27..9c5a87630a 100644 --- a/src/kits/tracker/StatusWindow.cpp +++ b/src/kits/tracker/StatusWindow.cpp @@ -47,6 +47,7 @@ All rights reserved. #include #include #include +#include #include @@ -800,7 +801,7 @@ BStatusView::_TimeStatusString(float availableSpace, float* _width) locale->FormatDateTime(timeText, sizeof(timeText), finishTime, B_MEDIUM_DATE_FORMAT, B_MEDIUM_TIME_FORMAT); } else { - locale->FormatTime(timeText, sizeof(timeText), finishTime, + BTimeFormat().Format(timeText, sizeof(timeText), finishTime, B_MEDIUM_TIME_FORMAT); } @@ -840,10 +841,10 @@ BStatusView::_FullTimeRemainingString(time_t now, time_t finishTime, BString finishStr; if (finishTime - now > 60 * 60) { buffer.SetTo(B_TRANSLATE("Finish: %time - Over %finishtime left")); - formatter.Format(now * 1000000LL, finishTime * 1000000LL, &finishStr); + formatter.Format(finishStr, now * 1000000LL, finishTime * 1000000LL); } else { buffer.SetTo(B_TRANSLATE("Finish: %time - %finishtime left")); - formatter.Format(now * 1000000LL, finishTime * 1000000LL, &finishStr); + formatter.Format(finishStr, now * 1000000LL, finishTime * 1000000LL); } buffer.ReplaceFirst("%time", timeText); diff --git a/src/preferences/locale/FormatSettingsView.cpp b/src/preferences/locale/FormatSettingsView.cpp index a0c1dc287e..1abd32e2d4 100644 --- a/src/preferences/locale/FormatSettingsView.cpp +++ b/src/preferences/locale/FormatSettingsView.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "LocalePreflet.h" @@ -361,9 +362,10 @@ FormatSettingsView::_UpdateExamples() time_t timeValue = (time_t)time(NULL); BString result; - // Do NOT make this a class member. We do want to recreate it everytime, as + // Do NOT make these class members. We do want to recreate it everytime, as // to get the updated settings from the locale roster. BDateFormat dateFormat; + BTimeFormat timeFormat; dateFormat.Format(result, timeValue, B_FULL_DATE_FORMAT); fFullDateExampleView->SetText(result); @@ -377,16 +379,16 @@ FormatSettingsView::_UpdateExamples() dateFormat.Format(result, timeValue, B_SHORT_DATE_FORMAT); fShortDateExampleView->SetText(result); - BLocale::Default()->FormatTime(&result, timeValue, B_FULL_TIME_FORMAT); + timeFormat.Format(result, timeValue, B_FULL_TIME_FORMAT); fFullTimeExampleView->SetText(result); - BLocale::Default()->FormatTime(&result, timeValue, B_LONG_TIME_FORMAT); + timeFormat.Format(result, timeValue, B_LONG_TIME_FORMAT); fLongTimeExampleView->SetText(result); - BLocale::Default()->FormatTime(&result, timeValue, B_MEDIUM_TIME_FORMAT); + timeFormat.Format(result, timeValue, B_MEDIUM_TIME_FORMAT); fMediumTimeExampleView->SetText(result); - BLocale::Default()->FormatTime(&result, timeValue, B_SHORT_TIME_FORMAT); + timeFormat.Format(result, timeValue, B_SHORT_TIME_FORMAT); fShortTimeExampleView->SetText(result); status_t status = BLocale::Default()->FormatNumber(&result, 1234.5678); diff --git a/src/preferences/screensaver/ScreenSaverWindow.cpp b/src/preferences/screensaver/ScreenSaverWindow.cpp index 7c918ce65c..96eef3520c 100644 --- a/src/preferences/screensaver/ScreenSaverWindow.cpp +++ b/src/preferences/screensaver/ScreenSaverWindow.cpp @@ -256,7 +256,7 @@ void TimeSlider::_TimeToString(bigtime_t useconds, BString& string) { BDurationFormat formatter; - formatter.Format(0, useconds, &string); + formatter.Format(string, 0, useconds); } diff --git a/src/preferences/time/DateTimeEdit.cpp b/src/preferences/time/DateTimeEdit.cpp index 0391755db1..0614a2bb30 100644 --- a/src/preferences/time/DateTimeEdit.cpp +++ b/src/preferences/time/DateTimeEdit.cpp @@ -248,15 +248,14 @@ TTimeEdit::_UpdateFields() free(fFieldPositions); fFieldPositions = NULL; } - BLocale::Default()->FormatTime(&fText, fFieldPositions, - fFieldPosCount, time, B_MEDIUM_TIME_FORMAT); + fTimeFormat.Format(fText, fFieldPositions, fFieldPosCount, time, + B_MEDIUM_TIME_FORMAT); if (fFields != NULL) { free(fFields); fFields = NULL; } - BLocale::Default()->GetTimeFields(fFields, fFieldCount, - B_MEDIUM_TIME_FORMAT); + fTimeFormat.GetTimeFields(fFields, fFieldCount, B_MEDIUM_TIME_FORMAT); } diff --git a/src/preferences/time/DateTimeEdit.h b/src/preferences/time/DateTimeEdit.h index 2a0d62d6a1..b3ae28765c 100644 --- a/src/preferences/time/DateTimeEdit.h +++ b/src/preferences/time/DateTimeEdit.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "SectionEdit.h" @@ -51,6 +52,7 @@ private: int32 _SectionValue(int32 index) const; BDateTime fTime; + BTimeFormat fTimeFormat; bigtime_t fLastKeyDownTime; int32 fLastKeyDownInt; diff --git a/src/preferences/time/TimeZoneListView.cpp b/src/preferences/time/TimeZoneListView.cpp index ccc942f587..c0111eb5ec 100644 --- a/src/preferences/time/TimeZoneListView.cpp +++ b/src/preferences/time/TimeZoneListView.cpp @@ -47,7 +47,7 @@ TimeZoneListView::GetToolTipAt(BPoint point, BToolTip** _tip) BString nowInTimeZone; time_t now = time(NULL); - BLocale::Default()->FormatTime(&nowInTimeZone, now, B_SHORT_TIME_FORMAT, + fTimeFormat.Format(nowInTimeZone, now, B_SHORT_TIME_FORMAT, &item->TimeZone()); BString dateInTimeZone; diff --git a/src/preferences/time/TimeZoneListView.h b/src/preferences/time/TimeZoneListView.h index fbd9466bdc..b70764d1d8 100644 --- a/src/preferences/time/TimeZoneListView.h +++ b/src/preferences/time/TimeZoneListView.h @@ -11,6 +11,7 @@ #include #include +#include class TimeZoneListView : public BOutlineListView { @@ -23,6 +24,7 @@ protected: private: BDateFormat fDateFormat; + BTimeFormat fTimeFormat; }; diff --git a/src/preferences/time/ZoneView.cpp b/src/preferences/time/ZoneView.cpp index 8d3e4414c8..03ca2c9f41 100644 --- a/src/preferences/time/ZoneView.cpp +++ b/src/preferences/time/ZoneView.cpp @@ -567,8 +567,7 @@ TimeZoneView::_FormatTime(const BTimeZone& timeZone) : 0; now -= timeZone.OffsetFromGMT() - currentOffset; } - BLocale::Default()->FormatTime(&result, now, B_SHORT_TIME_FORMAT, - &timeZone); + fTimeFormat.Format(result, now, B_SHORT_TIME_FORMAT, &timeZone); return result; } diff --git a/src/preferences/time/ZoneView.h b/src/preferences/time/ZoneView.h index 9766263709..6aa627942a 100644 --- a/src/preferences/time/ZoneView.h +++ b/src/preferences/time/ZoneView.h @@ -12,6 +12,7 @@ #include +#include #include @@ -71,6 +72,8 @@ private: TimeZoneListItem* fCurrentZoneItem; TimeZoneListItem* fOldZoneItem; bool fInitialized; + + BTimeFormat fTimeFormat; }; diff --git a/src/tests/kits/locale/DurationFormatTest.cpp b/src/tests/kits/locale/DurationFormatTest.cpp index b7f283f3c3..8c88099a93 100644 --- a/src/tests/kits/locale/DurationFormatTest.cpp +++ b/src/tests/kits/locale/DurationFormatTest.cpp @@ -38,7 +38,7 @@ DurationFormatTest::TestDuration() format.SetFormattingConventions(englishFormat); format.SetLanguage(englishLanguage); - status_t result = format.Format(0, 800000000000ll, &buffer); + status_t result = format.Format(buffer, 0, 800000000000ll); expected << "1 week, 2 days, 6 hours, 13 minutes, 20 seconds"; CPPUNIT_ASSERT_EQUAL(B_OK, result); @@ -46,7 +46,7 @@ DurationFormatTest::TestDuration() format.SetFormattingConventions(frenchFormat); format.SetLanguage(frenchLanguage); - result = format.Format(0, 800000000000ll, &buffer); + result = format.Format(buffer, 0, 800000000000ll); // We check that the passed BString is not truncated. expected << "1 semaine, 2 jours, 6 heures, 13 minutes, 20 secondes"; @@ -69,14 +69,14 @@ DurationFormatTest::TestTimeUnit() format.SetFormattingConventions(englishFormat); format.SetLanguage(englishLanguage); - status_t result = format.Format(5, B_TIME_UNIT_HOUR, &buffer); + status_t result = format.Format(buffer, 5, B_TIME_UNIT_HOUR); CPPUNIT_ASSERT_EQUAL(B_OK, result); CPPUNIT_ASSERT_EQUAL(BString("5 hours"), buffer); format.SetFormattingConventions(frenchFormat); format.SetLanguage(frenchLanguage); - result = format.Format(5, B_TIME_UNIT_HOUR, &buffer); + result = format.Format(buffer, 5, B_TIME_UNIT_HOUR); CPPUNIT_ASSERT_EQUAL(B_OK, result); // We check that the passed BString is not truncated. This makes it easy