Move date formatting from BLocale to BDateFormat
* There is a little code duplication. This will be moved to BFormat once the time and datetime formatting is also moved out of BLocale * The way to create a BDateFormat from a BLocale is still open for discussion. I'm undecided between making BDateFormat a member of BLocale, or adding a BDateFormat(const BLocale&) constructor. * Adjust all users of the API.
This commit is contained in:
parent
a122146848
commit
2a5e33a980
@ -1,29 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku, Inc.
|
||||
* Copyright 2010-2014, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT Licence.
|
||||
*/
|
||||
#ifndef _B_DATE_FORMAT_H_
|
||||
#define _B_DATE_FORMAT_H_
|
||||
|
||||
|
||||
#include <DateTimeFormat.h>
|
||||
#include <FormattingConventions.h>
|
||||
#include <Language.h>
|
||||
#include <Locker.h>
|
||||
|
||||
|
||||
class BString;
|
||||
class BTimeZone;
|
||||
|
||||
class BDateFormat : public BDateTimeFormat {
|
||||
|
||||
enum BWeekday {
|
||||
B_WEEKDAY_MONDAY = 1,
|
||||
B_WEEKDAY_TUESDAY,
|
||||
B_WEEKDAY_WEDNESDAY,
|
||||
B_WEEKDAY_THURSDAY,
|
||||
B_WEEKDAY_FRIDAY,
|
||||
B_WEEKDAY_SATURDAY,
|
||||
B_WEEKDAY_SUNDAY,
|
||||
};
|
||||
|
||||
|
||||
class BDateFormat {
|
||||
public:
|
||||
BDateFormat();
|
||||
BDateFormat(const BLanguage* const,
|
||||
const BFormattingConventions* const);
|
||||
BDateFormat(const BDateFormat &other);
|
||||
virtual ~BDateFormat();
|
||||
|
||||
static const BDateFormat* Default();
|
||||
|
||||
// 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, BDateFormatStyle style) const;
|
||||
status_t Format(BString* string, time_t time,
|
||||
BDateFormatStyle style,
|
||||
const BTimeZone* timeZone = NULL) const;
|
||||
status_t Format(BString* string,
|
||||
int*& fieldPositions, int& fieldCount,
|
||||
time_t time, BDateFormatStyle style) const;
|
||||
|
||||
// TODO: ... all, basically!
|
||||
status_t GetFields(BDateElement*& fields,
|
||||
int& fieldCount, BDateFormatStyle style
|
||||
) const;
|
||||
|
||||
status_t GetStartOfWeek(BWeekday* weekday) const;
|
||||
|
||||
// TODO parsing
|
||||
|
||||
private:
|
||||
icu::DateFormat* _CreateDateFormatter(
|
||||
const BString& format) const;
|
||||
|
||||
mutable BLocker fLock;
|
||||
BFormattingConventions fConventions;
|
||||
BLanguage fLanguage;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,16 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku, Inc.
|
||||
* Copyright 2010-2014, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT Licence.
|
||||
*/
|
||||
#ifndef _B_DATE_TIME_FORMAT_H_
|
||||
#define _B_DATE_TIME_FORMAT_H_
|
||||
|
||||
|
||||
#include <Format.h>
|
||||
#include <FormatParameters.h>
|
||||
|
||||
|
||||
class BString;
|
||||
|
||||
|
||||
enum BDateElement {
|
||||
B_DATE_ELEMENT_INVALID = B_BAD_DATA,
|
||||
B_DATE_ELEMENT_YEAR = 0,
|
||||
B_DATE_ELEMENT_MONTH,
|
||||
B_DATE_ELEMENT_DAY,
|
||||
B_DATE_ELEMENT_AM_PM,
|
||||
B_DATE_ELEMENT_HOUR,
|
||||
B_DATE_ELEMENT_MINUTE,
|
||||
B_DATE_ELEMENT_SECOND
|
||||
};
|
||||
|
||||
|
||||
class BDateTimeFormat : public BFormat {
|
||||
public:
|
||||
BDateTimeFormat();
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
#include <Collator.h>
|
||||
#include <DateTimeFormat.h>
|
||||
#include <FormattingConventions.h>
|
||||
#include <Language.h>
|
||||
#include <Locker.h>
|
||||
@ -18,21 +19,11 @@ namespace icu {
|
||||
|
||||
|
||||
class BCatalog;
|
||||
class BDateFormat;
|
||||
class BString;
|
||||
class BTimeZone;
|
||||
|
||||
|
||||
enum BDateElement {
|
||||
B_DATE_ELEMENT_INVALID = B_BAD_DATA,
|
||||
B_DATE_ELEMENT_YEAR = 0,
|
||||
B_DATE_ELEMENT_MONTH,
|
||||
B_DATE_ELEMENT_DAY,
|
||||
B_DATE_ELEMENT_AM_PM,
|
||||
B_DATE_ELEMENT_HOUR,
|
||||
B_DATE_ELEMENT_MINUTE,
|
||||
B_DATE_ELEMENT_SECOND
|
||||
};
|
||||
|
||||
enum BNumberElement {
|
||||
B_NUMBER_ELEMENT_INVALID = B_BAD_DATA,
|
||||
B_NUMBER_ELEMENT_INTEGER = 0,
|
||||
@ -41,18 +32,6 @@ enum BNumberElement {
|
||||
};
|
||||
|
||||
|
||||
// TODO: move this to BCalendar (should we ever have that) or BDate
|
||||
enum BWeekday {
|
||||
B_WEEKDAY_MONDAY = 1,
|
||||
B_WEEKDAY_TUESDAY,
|
||||
B_WEEKDAY_WEDNESDAY,
|
||||
B_WEEKDAY_THURSDAY,
|
||||
B_WEEKDAY_FRIDAY,
|
||||
B_WEEKDAY_SATURDAY,
|
||||
B_WEEKDAY_SUNDAY,
|
||||
};
|
||||
|
||||
|
||||
class BLocale {
|
||||
public:
|
||||
BLocale(const BLanguage* language = NULL,
|
||||
@ -78,11 +57,6 @@ public:
|
||||
// see definitions in LocaleStrings.h
|
||||
const char* GetString(uint32 id) const;
|
||||
|
||||
void FormatString(char* target, size_t maxSize,
|
||||
char* fmt, ...) const;
|
||||
void FormatString(BString* buffer, char* fmt,
|
||||
...) const;
|
||||
|
||||
// DateTime
|
||||
|
||||
// TODO: drop some of these once BDateTimeFormat
|
||||
@ -95,24 +69,6 @@ public:
|
||||
BTimeFormatStyle timeStyle,
|
||||
const BTimeZone* timeZone = NULL) const;
|
||||
|
||||
// Date
|
||||
|
||||
// TODO: drop some of these once BDateFormat
|
||||
// has been implemented!
|
||||
ssize_t FormatDate(char* string, size_t maxSize,
|
||||
time_t time, BDateFormatStyle style) const;
|
||||
status_t FormatDate(BString* string, time_t time,
|
||||
BDateFormatStyle style,
|
||||
const BTimeZone* timeZone = NULL) const;
|
||||
status_t FormatDate(BString* string,
|
||||
int*& fieldPositions, int& fieldCount,
|
||||
time_t time, BDateFormatStyle style) const;
|
||||
status_t GetDateFields(BDateElement*& fields,
|
||||
int& fieldCount, BDateFormatStyle style
|
||||
) const;
|
||||
|
||||
status_t GetStartOfWeek(BWeekday* weekday) const;
|
||||
|
||||
// Time
|
||||
|
||||
// TODO: drop some of these once BTimeFormat
|
||||
|
@ -16,6 +16,7 @@ class BBitmap;
|
||||
class BCatalog;
|
||||
class BCollator;
|
||||
class BCountry;
|
||||
class BDateFormat;
|
||||
class BFormattingConventions;
|
||||
class BLanguage;
|
||||
class BLocale;
|
||||
@ -78,6 +79,7 @@ public:
|
||||
// (that needs to link with liblocalestub.a)
|
||||
|
||||
const BLocale* GetDefaultLocale() const;
|
||||
const BDateFormat* GetDefaultDateFormat() const;
|
||||
|
||||
bool IsFilesystemTranslationPreferred() const;
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
#include <Collator.h>
|
||||
#include <DateFormat.h>
|
||||
#include <FormattingConventions.h>
|
||||
#include <image.h>
|
||||
#include <Language.h>
|
||||
@ -37,6 +38,7 @@ struct LocaleRosterData {
|
||||
|
||||
BLocale fDefaultLocale;
|
||||
BTimeZone fDefaultTimeZone;
|
||||
BDateFormat fDefaultDateFormat;
|
||||
|
||||
bool fIsFilesystemTranslationPreferred;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "DateTime.h"
|
||||
|
||||
|
||||
#include <DateFormat.h>
|
||||
#include <Invoker.h>
|
||||
#include <List.h>
|
||||
#include <Locale.h>
|
||||
|
@ -40,6 +40,7 @@ All rights reserved.
|
||||
|
||||
#include <Application.h>
|
||||
#include <Catalog.h>
|
||||
#include <DateFormat.h>
|
||||
#include <Debug.h>
|
||||
#include <Locale.h>
|
||||
#include <MenuItem.h>
|
||||
@ -421,7 +422,7 @@ TTimeView::GetCurrentDate()
|
||||
{
|
||||
char tmp[sizeof(fCurrentDateStr)];
|
||||
|
||||
fLocale.FormatDate(tmp, sizeof(fCurrentDateStr), fCurrentTime,
|
||||
BDateFormat::Default()->Format(tmp, sizeof(fCurrentDateStr), fCurrentTime,
|
||||
B_FULL_DATE_FORMAT);
|
||||
|
||||
// remove leading 0 from date when month is less than 10 (MM/DD/YY)
|
||||
|
@ -8,27 +8,291 @@
|
||||
|
||||
#include <DateFormat.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <Autolock.h>
|
||||
#include <FormattingConventionsPrivate.h>
|
||||
#include <LanguagePrivate.h>
|
||||
#include <Locale.h>
|
||||
#include <LocaleRoster.h>
|
||||
#include <TimeZone.h>
|
||||
|
||||
#include <ICUWrapper.h>
|
||||
|
||||
#include <unicode/datefmt.h>
|
||||
#include <unicode/smpdtfmt.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
// default constructor
|
||||
BDateFormat::BDateFormat()
|
||||
: BDateTimeFormat()
|
||||
BDateFormat::BDateFormat(const BLanguage* const language,
|
||||
const BFormattingConventions* const conventions)
|
||||
{
|
||||
if (conventions != NULL)
|
||||
fConventions = *conventions;
|
||||
else
|
||||
BLocale::Default()->GetFormattingConventions(&fConventions);
|
||||
|
||||
if (language != NULL)
|
||||
fLanguage = *language;
|
||||
else
|
||||
BLocale::Default()->GetLanguage(&fLanguage);
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
BDateFormat::BDateFormat(const BDateFormat &other)
|
||||
: BDateTimeFormat(other)
|
||||
: fConventions(other.fConventions),
|
||||
fLanguage(other.fLanguage)
|
||||
{
|
||||
}
|
||||
|
||||
/*static*/ const BDateFormat*
|
||||
BDateFormat::Default()
|
||||
{
|
||||
return BLocaleRoster::Default()->GetDefaultDateFormat();
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
BDateFormat::~BDateFormat()
|
||||
{
|
||||
}
|
||||
|
||||
// Format
|
||||
status_t
|
||||
BDateFormat::Format(bigtime_t value, BString* buffer) const
|
||||
ssize_t
|
||||
BDateFormat::Format(char* string, size_t maxSize, time_t time,
|
||||
BDateFormatStyle style) const
|
||||
{
|
||||
return B_ERROR;
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
UnicodeString icuString;
|
||||
dateFormatter->format((UDate)time * 1000, icuString);
|
||||
|
||||
CheckedArrayByteSink stringConverter(string, maxSize);
|
||||
icuString.toUTF8(stringConverter);
|
||||
|
||||
if (stringConverter.Overflowed())
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return stringConverter.NumberOfBytesWritten();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDateFormat::Format(BString *string, time_t time, BDateFormatStyle style,
|
||||
const BTimeZone* timeZone) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (timeZone != NULL) {
|
||||
ObjectDeleter<TimeZone> icuTimeZone(
|
||||
TimeZone::createTimeZone(timeZone->ID().String()));
|
||||
if (icuTimeZone.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
dateFormatter->setTimeZone(*icuTimeZone.Get());
|
||||
}
|
||||
|
||||
UnicodeString icuString;
|
||||
dateFormatter->format((UDate)time * 1000, icuString);
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
icuString.toUTF8(stringConverter);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDateFormat::Format(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
time_t time, BDateFormatStyle style) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fieldPositions = NULL;
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
icu::FieldPositionIterator positionIterator;
|
||||
UnicodeString icuString;
|
||||
dateFormatter->format((UDate)time * 1000, icuString, &positionIterator,
|
||||
error);
|
||||
|
||||
if (error != U_ZERO_ERROR)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
icu::FieldPosition field;
|
||||
std::vector<int> 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
|
||||
BDateFormat::GetFields(BDateElement*& fields, int& fieldCount,
|
||||
BDateFormatStyle style) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fields = NULL;
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
icu::FieldPositionIterator positionIterator;
|
||||
UnicodeString icuString;
|
||||
time_t now;
|
||||
dateFormatter->format((UDate)time(&now) * 1000, icuString,
|
||||
&positionIterator, error);
|
||||
|
||||
if (U_FAILURE(error))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
icu::FieldPosition field;
|
||||
std::vector<int> 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_YEAR_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_YEAR;
|
||||
break;
|
||||
case UDAT_MONTH_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_MONTH;
|
||||
break;
|
||||
case UDAT_DATE_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_DAY;
|
||||
break;
|
||||
default:
|
||||
fields[i] = B_DATE_ELEMENT_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDateFormat::GetStartOfWeek(BWeekday* startOfWeek) const
|
||||
{
|
||||
if (startOfWeek == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
ObjectDeleter<Calendar> calendar = Calendar::createInstance(
|
||||
*BFormattingConventions::Private(&fConventions).ICULocale(), err);
|
||||
|
||||
if (U_FAILURE(err))
|
||||
return B_ERROR;
|
||||
|
||||
UCalendarDaysOfWeek icuWeekStart = calendar->getFirstDayOfWeek(err);
|
||||
if (U_FAILURE(err))
|
||||
return B_ERROR;
|
||||
|
||||
switch (icuWeekStart) {
|
||||
case UCAL_SUNDAY:
|
||||
*startOfWeek = B_WEEKDAY_SUNDAY;
|
||||
break;
|
||||
case UCAL_MONDAY:
|
||||
*startOfWeek = B_WEEKDAY_MONDAY;
|
||||
break;
|
||||
case UCAL_TUESDAY:
|
||||
*startOfWeek = B_WEEKDAY_TUESDAY;
|
||||
break;
|
||||
case UCAL_WEDNESDAY:
|
||||
*startOfWeek = B_WEEKDAY_WEDNESDAY;
|
||||
break;
|
||||
case UCAL_THURSDAY:
|
||||
*startOfWeek = B_WEEKDAY_THURSDAY;
|
||||
break;
|
||||
case UCAL_FRIDAY:
|
||||
*startOfWeek = B_WEEKDAY_FRIDAY;
|
||||
break;
|
||||
case UCAL_SATURDAY:
|
||||
*startOfWeek = B_WEEKDAY_SATURDAY;
|
||||
break;
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
DateFormat*
|
||||
BDateFormat::_CreateDateFormatter(const BString& format) const
|
||||
{
|
||||
Locale* icuLocale
|
||||
= fConventions.UseStringsFromPreferredLanguage()
|
||||
? BLanguage::Private(&fLanguage).ICULocale()
|
||||
: BFormattingConventions::Private(&fConventions).ICULocale();
|
||||
|
||||
icu::DateFormat* dateFormatter
|
||||
= icu::DateFormat::createDateInstance(DateFormat::kShort, *icuLocale);
|
||||
if (dateFormatter == NULL)
|
||||
return NULL;
|
||||
|
||||
SimpleDateFormat* dateFormatterImpl
|
||||
= static_cast<SimpleDateFormat*>(dateFormatter);
|
||||
|
||||
UnicodeString pattern(format.String());
|
||||
dateFormatterImpl->applyPattern(pattern);
|
||||
|
||||
return dateFormatter;
|
||||
}
|
||||
|
||||
|
||||
|
@ -188,220 +188,6 @@ BLocale::SetLanguage(const BLanguage& newLanguage)
|
||||
// #pragma mark - Date
|
||||
|
||||
|
||||
ssize_t
|
||||
BLocale::FormatDate(char* string, size_t maxSize, time_t time,
|
||||
BDateFormatStyle style) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
UnicodeString icuString;
|
||||
dateFormatter->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::FormatDate(BString *string, time_t time, BDateFormatStyle style,
|
||||
const BTimeZone* timeZone) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (timeZone != NULL) {
|
||||
ObjectDeleter<TimeZone> icuTimeZone(
|
||||
TimeZone::createTimeZone(timeZone->ID().String()));
|
||||
if (icuTimeZone.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
dateFormatter->setTimeZone(*icuTimeZone.Get());
|
||||
}
|
||||
|
||||
UnicodeString icuString;
|
||||
dateFormatter->format((UDate)time * 1000, icuString);
|
||||
|
||||
string->Truncate(0);
|
||||
BStringByteSink stringConverter(string);
|
||||
icuString.toUTF8(stringConverter);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BLocale::FormatDate(BString* string, int*& fieldPositions, int& fieldCount,
|
||||
time_t time, BDateFormatStyle style) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fieldPositions = NULL;
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
icu::FieldPositionIterator positionIterator;
|
||||
UnicodeString icuString;
|
||||
dateFormatter->format((UDate)time * 1000, icuString, &positionIterator,
|
||||
error);
|
||||
|
||||
if (error != U_ZERO_ERROR)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
icu::FieldPosition field;
|
||||
std::vector<int> 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::GetDateFields(BDateElement*& fields, int& fieldCount,
|
||||
BDateFormatStyle style) const
|
||||
{
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
BString format;
|
||||
fConventions.GetDateFormat(style, format);
|
||||
ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
|
||||
if (dateFormatter.Get() == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fields = NULL;
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
icu::FieldPositionIterator positionIterator;
|
||||
UnicodeString icuString;
|
||||
time_t now;
|
||||
dateFormatter->format((UDate)time(&now) * 1000, icuString,
|
||||
&positionIterator, error);
|
||||
|
||||
if (U_FAILURE(error))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
icu::FieldPosition field;
|
||||
std::vector<int> 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_YEAR_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_YEAR;
|
||||
break;
|
||||
case UDAT_MONTH_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_MONTH;
|
||||
break;
|
||||
case UDAT_DATE_FIELD:
|
||||
fields[i] = B_DATE_ELEMENT_DAY;
|
||||
break;
|
||||
default:
|
||||
fields[i] = B_DATE_ELEMENT_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BLocale::GetStartOfWeek(BWeekday* startOfWeek) const
|
||||
{
|
||||
if (startOfWeek == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BAutolock lock(fLock);
|
||||
if (!lock.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
ObjectDeleter<Calendar> calendar = Calendar::createInstance(
|
||||
*BFormattingConventions::Private(&fConventions).ICULocale(), err);
|
||||
|
||||
if (U_FAILURE(err))
|
||||
return B_ERROR;
|
||||
|
||||
UCalendarDaysOfWeek icuWeekStart = calendar->getFirstDayOfWeek(err);
|
||||
if (U_FAILURE(err))
|
||||
return B_ERROR;
|
||||
|
||||
switch (icuWeekStart) {
|
||||
case UCAL_SUNDAY:
|
||||
*startOfWeek = B_WEEKDAY_SUNDAY;
|
||||
break;
|
||||
case UCAL_MONDAY:
|
||||
*startOfWeek = B_WEEKDAY_MONDAY;
|
||||
break;
|
||||
case UCAL_TUESDAY:
|
||||
*startOfWeek = B_WEEKDAY_TUESDAY;
|
||||
break;
|
||||
case UCAL_WEDNESDAY:
|
||||
*startOfWeek = B_WEEKDAY_WEDNESDAY;
|
||||
break;
|
||||
case UCAL_THURSDAY:
|
||||
*startOfWeek = B_WEEKDAY_THURSDAY;
|
||||
break;
|
||||
case UCAL_FRIDAY:
|
||||
*startOfWeek = B_WEEKDAY_FRIDAY;
|
||||
break;
|
||||
case UCAL_SATURDAY:
|
||||
*startOfWeek = B_WEEKDAY_SATURDAY;
|
||||
break;
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
BLocale::FormatDateTime(char* target, size_t maxSize, time_t time,
|
||||
BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const
|
||||
@ -847,8 +633,8 @@ BLocale::_CreateDateFormatter(const BString& format) const
|
||||
? BLanguage::Private(&fLanguage).ICULocale()
|
||||
: BFormattingConventions::Private(&fConventions).ICULocale();
|
||||
|
||||
DateFormat* dateFormatter
|
||||
= DateFormat::createDateInstance(DateFormat::kShort, *icuLocale);
|
||||
icu::DateFormat* dateFormatter
|
||||
= icu::DateFormat::createDateInstance(DateFormat::kShort, *icuLocale);
|
||||
if (dateFormatter == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -870,8 +656,8 @@ BLocale::_CreateTimeFormatter(const BString& format) const
|
||||
? BLanguage::Private(&fLanguage).ICULocale()
|
||||
: BFormattingConventions::Private(&fConventions).ICULocale();
|
||||
|
||||
DateFormat* timeFormatter
|
||||
= DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale);
|
||||
icu::DateFormat* timeFormatter
|
||||
= icu::DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale);
|
||||
if (timeFormatter == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -174,6 +174,14 @@ BLocaleRoster::GetDefaultLocale() const
|
||||
return &fData->fDefaultLocale;
|
||||
}
|
||||
|
||||
|
||||
const BDateFormat*
|
||||
BLocaleRoster::GetDefaultDateFormat() const
|
||||
{
|
||||
return &fData->fDefaultDateFormat;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BLocaleRoster::GetLanguage(const char* languageCode,
|
||||
BLanguage** _language) const
|
||||
|
@ -126,6 +126,7 @@ LocaleRosterData::LocaleRosterData(const BLanguage& language,
|
||||
:
|
||||
fLock("LocaleRosterData"),
|
||||
fDefaultLocale(&language, &conventions),
|
||||
fDefaultDateFormat(&language, &conventions),
|
||||
fIsFilesystemTranslationPreferred(false),
|
||||
fAreResourcesLoaded(false)
|
||||
{
|
||||
|
@ -654,7 +654,7 @@ BCalendarView::_InitObject()
|
||||
{
|
||||
fDate = BDate::CurrentDate(B_LOCAL_TIME);
|
||||
|
||||
BLocale::Default()->GetStartOfWeek((BWeekday*)&fStartOfWeek);
|
||||
BDateFormat::Default()->GetStartOfWeek((BWeekday*)&fStartOfWeek);
|
||||
|
||||
_SetupDayNames();
|
||||
_SetupDayNumbers();
|
||||
|
@ -45,6 +45,7 @@ All rights reserved.
|
||||
#include <Alert.h>
|
||||
#include <AppFileInfo.h>
|
||||
#include <Catalog.h>
|
||||
#include <DateFormat.h>
|
||||
#include <Debug.h>
|
||||
#include <Locale.h>
|
||||
#include <NodeInfo.h>
|
||||
@ -213,7 +214,7 @@ TruncTimeBase(BString* outString, int64 value, const View* view, float width)
|
||||
}
|
||||
|
||||
if (resultWidth > width
|
||||
&& BLocale::Default()->FormatDate(&date, timeValue,
|
||||
&& BDateFormat::Default()->Format(&date, timeValue,
|
||||
B_SHORT_DATE_FORMAT) == B_OK) {
|
||||
resultWidth = view->StringWidth(date.String(), date.Length());
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <Catalog.h>
|
||||
#include <CheckBox.h>
|
||||
#include <ControlLook.h>
|
||||
#include <DateFormat.h>
|
||||
#include <GridLayout.h>
|
||||
#include <GridLayoutBuilder.h>
|
||||
#include <GroupLayout.h>
|
||||
@ -360,16 +361,16 @@ FormatSettingsView::_UpdateExamples()
|
||||
time_t timeValue = (time_t)time(NULL);
|
||||
BString result;
|
||||
|
||||
BLocale::Default()->FormatDate(&result, timeValue, B_FULL_DATE_FORMAT);
|
||||
BDateFormat::Default()->Format(&result, timeValue, B_FULL_DATE_FORMAT);
|
||||
fFullDateExampleView->SetText(result);
|
||||
|
||||
BLocale::Default()->FormatDate(&result, timeValue, B_LONG_DATE_FORMAT);
|
||||
BDateFormat::Default()->Format(&result, timeValue, B_LONG_DATE_FORMAT);
|
||||
fLongDateExampleView->SetText(result);
|
||||
|
||||
BLocale::Default()->FormatDate(&result, timeValue, B_MEDIUM_DATE_FORMAT);
|
||||
BDateFormat::Default()->Format(&result, timeValue, B_MEDIUM_DATE_FORMAT);
|
||||
fMediumDateExampleView->SetText(result);
|
||||
|
||||
BLocale::Default()->FormatDate(&result, timeValue, B_SHORT_DATE_FORMAT);
|
||||
BDateFormat::Default()->Format(&result, timeValue, B_SHORT_DATE_FORMAT);
|
||||
fShortDateExampleView->SetText(result);
|
||||
|
||||
BLocale::Default()->FormatTime(&result, timeValue, B_FULL_TIME_FORMAT);
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <DateFormat.h>
|
||||
#include <List.h>
|
||||
#include <Locale.h>
|
||||
#include <String.h>
|
||||
@ -622,14 +623,14 @@ TDateEdit::_UpdateFields()
|
||||
free(fFieldPositions);
|
||||
fFieldPositions = NULL;
|
||||
}
|
||||
BLocale::Default()->FormatDate(&fText, fFieldPositions, fFieldPosCount,
|
||||
BDateFormat::Default()->Format(&fText, fFieldPositions, fFieldPosCount,
|
||||
time, B_SHORT_DATE_FORMAT);
|
||||
|
||||
if (fFields != NULL) {
|
||||
free(fFields);
|
||||
fFields = NULL;
|
||||
}
|
||||
BLocale::Default()->GetDateFields(fFields, fFieldCount,
|
||||
BDateFormat::Default()->GetFields(fFields, fFieldCount,
|
||||
B_SHORT_DATE_FORMAT);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <new>
|
||||
|
||||
#include <Catalog.h>
|
||||
#include <DateFormat.h>
|
||||
#include <Locale.h>
|
||||
#include <String.h>
|
||||
#include <TimeZone.h>
|
||||
@ -50,7 +51,7 @@ TimeZoneListView::GetToolTipAt(BPoint point, BToolTip** _tip)
|
||||
&item->TimeZone());
|
||||
|
||||
BString dateInTimeZone;
|
||||
BLocale::Default()->FormatDate(&dateInTimeZone, now, B_SHORT_DATE_FORMAT,
|
||||
BDateFormat::Default()->Format(&dateInTimeZone, now, B_SHORT_DATE_FORMAT,
|
||||
&item->TimeZone());
|
||||
|
||||
BString toolTip = item->Text();
|
||||
|
Loading…
Reference in New Issue
Block a user