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:
@@ -1,29 +1,67 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, Haiku, Inc.
|
* Copyright 2010-2014, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT Licence.
|
* Distributed under the terms of the MIT Licence.
|
||||||
*/
|
*/
|
||||||
#ifndef _B_DATE_FORMAT_H_
|
#ifndef _B_DATE_FORMAT_H_
|
||||||
#define _B_DATE_FORMAT_H_
|
#define _B_DATE_FORMAT_H_
|
||||||
|
|
||||||
|
|
||||||
#include <DateTimeFormat.h>
|
#include <DateTimeFormat.h>
|
||||||
|
#include <FormattingConventions.h>
|
||||||
|
#include <Language.h>
|
||||||
|
#include <Locker.h>
|
||||||
|
|
||||||
|
|
||||||
class BString;
|
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:
|
public:
|
||||||
BDateFormat();
|
BDateFormat(const BLanguage* const,
|
||||||
|
const BFormattingConventions* const);
|
||||||
BDateFormat(const BDateFormat &other);
|
BDateFormat(const BDateFormat &other);
|
||||||
virtual ~BDateFormat();
|
virtual ~BDateFormat();
|
||||||
|
|
||||||
|
static const BDateFormat* Default();
|
||||||
|
|
||||||
// formatting
|
// formatting
|
||||||
|
|
||||||
// no-frills version: Simply appends the
|
ssize_t Format(char* string, size_t maxSize,
|
||||||
// formatted date to the string buffer.
|
time_t time, BDateFormatStyle style) const;
|
||||||
// Can fail only with B_NO_MEMORY or B_BAD_VALUE.
|
status_t Format(BString* string, time_t time,
|
||||||
virtual status_t Format(bigtime_t value, BString* buffer) const;
|
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.
|
* Distributed under the terms of the MIT Licence.
|
||||||
*/
|
*/
|
||||||
#ifndef _B_DATE_TIME_FORMAT_H_
|
#ifndef _B_DATE_TIME_FORMAT_H_
|
||||||
#define _B_DATE_TIME_FORMAT_H_
|
#define _B_DATE_TIME_FORMAT_H_
|
||||||
|
|
||||||
|
|
||||||
#include <Format.h>
|
#include <Format.h>
|
||||||
#include <FormatParameters.h>
|
#include <FormatParameters.h>
|
||||||
|
|
||||||
|
|
||||||
class BString;
|
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 {
|
class BDateTimeFormat : public BFormat {
|
||||||
public:
|
public:
|
||||||
BDateTimeFormat();
|
BDateTimeFormat();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <Collator.h>
|
#include <Collator.h>
|
||||||
|
#include <DateTimeFormat.h>
|
||||||
#include <FormattingConventions.h>
|
#include <FormattingConventions.h>
|
||||||
#include <Language.h>
|
#include <Language.h>
|
||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
@@ -18,21 +19,11 @@ namespace icu {
|
|||||||
|
|
||||||
|
|
||||||
class BCatalog;
|
class BCatalog;
|
||||||
|
class BDateFormat;
|
||||||
class BString;
|
class BString;
|
||||||
class BTimeZone;
|
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 {
|
enum BNumberElement {
|
||||||
B_NUMBER_ELEMENT_INVALID = B_BAD_DATA,
|
B_NUMBER_ELEMENT_INVALID = B_BAD_DATA,
|
||||||
B_NUMBER_ELEMENT_INTEGER = 0,
|
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 {
|
class BLocale {
|
||||||
public:
|
public:
|
||||||
BLocale(const BLanguage* language = NULL,
|
BLocale(const BLanguage* language = NULL,
|
||||||
@@ -78,11 +57,6 @@ public:
|
|||||||
// see definitions in LocaleStrings.h
|
// see definitions in LocaleStrings.h
|
||||||
const char* GetString(uint32 id) const;
|
const char* GetString(uint32 id) const;
|
||||||
|
|
||||||
void FormatString(char* target, size_t maxSize,
|
|
||||||
char* fmt, ...) const;
|
|
||||||
void FormatString(BString* buffer, char* fmt,
|
|
||||||
...) const;
|
|
||||||
|
|
||||||
// DateTime
|
// DateTime
|
||||||
|
|
||||||
// TODO: drop some of these once BDateTimeFormat
|
// TODO: drop some of these once BDateTimeFormat
|
||||||
@@ -95,24 +69,6 @@ public:
|
|||||||
BTimeFormatStyle timeStyle,
|
BTimeFormatStyle timeStyle,
|
||||||
const BTimeZone* timeZone = NULL) const;
|
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
|
// Time
|
||||||
|
|
||||||
// TODO: drop some of these once BTimeFormat
|
// TODO: drop some of these once BTimeFormat
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class BBitmap;
|
|||||||
class BCatalog;
|
class BCatalog;
|
||||||
class BCollator;
|
class BCollator;
|
||||||
class BCountry;
|
class BCountry;
|
||||||
|
class BDateFormat;
|
||||||
class BFormattingConventions;
|
class BFormattingConventions;
|
||||||
class BLanguage;
|
class BLanguage;
|
||||||
class BLocale;
|
class BLocale;
|
||||||
@@ -78,6 +79,7 @@ public:
|
|||||||
// (that needs to link with liblocalestub.a)
|
// (that needs to link with liblocalestub.a)
|
||||||
|
|
||||||
const BLocale* GetDefaultLocale() const;
|
const BLocale* GetDefaultLocale() const;
|
||||||
|
const BDateFormat* GetDefaultDateFormat() const;
|
||||||
|
|
||||||
bool IsFilesystemTranslationPreferred() const;
|
bool IsFilesystemTranslationPreferred() const;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <Collator.h>
|
#include <Collator.h>
|
||||||
|
#include <DateFormat.h>
|
||||||
#include <FormattingConventions.h>
|
#include <FormattingConventions.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <Language.h>
|
#include <Language.h>
|
||||||
@@ -37,6 +38,7 @@ struct LocaleRosterData {
|
|||||||
|
|
||||||
BLocale fDefaultLocale;
|
BLocale fDefaultLocale;
|
||||||
BTimeZone fDefaultTimeZone;
|
BTimeZone fDefaultTimeZone;
|
||||||
|
BDateFormat fDefaultDateFormat;
|
||||||
|
|
||||||
bool fIsFilesystemTranslationPreferred;
|
bool fIsFilesystemTranslationPreferred;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "DateTime.h"
|
#include "DateTime.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <DateFormat.h>
|
||||||
#include <Invoker.h>
|
#include <Invoker.h>
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ All rights reserved.
|
|||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <DateFormat.h>
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <MenuItem.h>
|
#include <MenuItem.h>
|
||||||
@@ -421,7 +422,7 @@ TTimeView::GetCurrentDate()
|
|||||||
{
|
{
|
||||||
char tmp[sizeof(fCurrentDateStr)];
|
char tmp[sizeof(fCurrentDateStr)];
|
||||||
|
|
||||||
fLocale.FormatDate(tmp, sizeof(fCurrentDateStr), fCurrentTime,
|
BDateFormat::Default()->Format(tmp, sizeof(fCurrentDateStr), fCurrentTime,
|
||||||
B_FULL_DATE_FORMAT);
|
B_FULL_DATE_FORMAT);
|
||||||
|
|
||||||
// remove leading 0 from date when month is less than 10 (MM/DD/YY)
|
// remove leading 0 from date when month is less than 10 (MM/DD/YY)
|
||||||
|
|||||||
@@ -8,27 +8,291 @@
|
|||||||
|
|
||||||
#include <DateFormat.h>
|
#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
|
// default constructor
|
||||||
BDateFormat::BDateFormat()
|
BDateFormat::BDateFormat(const BLanguage* const language,
|
||||||
: BDateTimeFormat()
|
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
|
// copy constructor
|
||||||
BDateFormat::BDateFormat(const BDateFormat &other)
|
BDateFormat::BDateFormat(const BDateFormat &other)
|
||||||
: BDateTimeFormat(other)
|
: fConventions(other.fConventions),
|
||||||
|
fLanguage(other.fLanguage)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ const BDateFormat*
|
||||||
|
BDateFormat::Default()
|
||||||
|
{
|
||||||
|
return BLocaleRoster::Default()->GetDefaultDateFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
BDateFormat::~BDateFormat()
|
BDateFormat::~BDateFormat()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format
|
// Format
|
||||||
status_t
|
ssize_t
|
||||||
BDateFormat::Format(bigtime_t value, BString* buffer) const
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+4
-218
@@ -188,220 +188,6 @@ BLocale::SetLanguage(const BLanguage& newLanguage)
|
|||||||
// #pragma mark - Date
|
// #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
|
ssize_t
|
||||||
BLocale::FormatDateTime(char* target, size_t maxSize, time_t time,
|
BLocale::FormatDateTime(char* target, size_t maxSize, time_t time,
|
||||||
BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const
|
BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const
|
||||||
@@ -847,8 +633,8 @@ BLocale::_CreateDateFormatter(const BString& format) const
|
|||||||
? BLanguage::Private(&fLanguage).ICULocale()
|
? BLanguage::Private(&fLanguage).ICULocale()
|
||||||
: BFormattingConventions::Private(&fConventions).ICULocale();
|
: BFormattingConventions::Private(&fConventions).ICULocale();
|
||||||
|
|
||||||
DateFormat* dateFormatter
|
icu::DateFormat* dateFormatter
|
||||||
= DateFormat::createDateInstance(DateFormat::kShort, *icuLocale);
|
= icu::DateFormat::createDateInstance(DateFormat::kShort, *icuLocale);
|
||||||
if (dateFormatter == NULL)
|
if (dateFormatter == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -870,8 +656,8 @@ BLocale::_CreateTimeFormatter(const BString& format) const
|
|||||||
? BLanguage::Private(&fLanguage).ICULocale()
|
? BLanguage::Private(&fLanguage).ICULocale()
|
||||||
: BFormattingConventions::Private(&fConventions).ICULocale();
|
: BFormattingConventions::Private(&fConventions).ICULocale();
|
||||||
|
|
||||||
DateFormat* timeFormatter
|
icu::DateFormat* timeFormatter
|
||||||
= DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale);
|
= icu::DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale);
|
||||||
if (timeFormatter == NULL)
|
if (timeFormatter == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -174,6 +174,14 @@ BLocaleRoster::GetDefaultLocale() const
|
|||||||
return &fData->fDefaultLocale;
|
return &fData->fDefaultLocale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BDateFormat*
|
||||||
|
BLocaleRoster::GetDefaultDateFormat() const
|
||||||
|
{
|
||||||
|
return &fData->fDefaultDateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BLocaleRoster::GetLanguage(const char* languageCode,
|
BLocaleRoster::GetLanguage(const char* languageCode,
|
||||||
BLanguage** _language) const
|
BLanguage** _language) const
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ LocaleRosterData::LocaleRosterData(const BLanguage& language,
|
|||||||
:
|
:
|
||||||
fLock("LocaleRosterData"),
|
fLock("LocaleRosterData"),
|
||||||
fDefaultLocale(&language, &conventions),
|
fDefaultLocale(&language, &conventions),
|
||||||
|
fDefaultDateFormat(&language, &conventions),
|
||||||
fIsFilesystemTranslationPreferred(false),
|
fIsFilesystemTranslationPreferred(false),
|
||||||
fAreResourcesLoaded(false)
|
fAreResourcesLoaded(false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -654,7 +654,7 @@ BCalendarView::_InitObject()
|
|||||||
{
|
{
|
||||||
fDate = BDate::CurrentDate(B_LOCAL_TIME);
|
fDate = BDate::CurrentDate(B_LOCAL_TIME);
|
||||||
|
|
||||||
BLocale::Default()->GetStartOfWeek((BWeekday*)&fStartOfWeek);
|
BDateFormat::Default()->GetStartOfWeek((BWeekday*)&fStartOfWeek);
|
||||||
|
|
||||||
_SetupDayNames();
|
_SetupDayNames();
|
||||||
_SetupDayNumbers();
|
_SetupDayNumbers();
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ All rights reserved.
|
|||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <AppFileInfo.h>
|
#include <AppFileInfo.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <DateFormat.h>
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <NodeInfo.h>
|
#include <NodeInfo.h>
|
||||||
@@ -213,7 +214,7 @@ TruncTimeBase(BString* outString, int64 value, const View* view, float width)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resultWidth > width
|
if (resultWidth > width
|
||||||
&& BLocale::Default()->FormatDate(&date, timeValue,
|
&& BDateFormat::Default()->Format(&date, timeValue,
|
||||||
B_SHORT_DATE_FORMAT) == B_OK) {
|
B_SHORT_DATE_FORMAT) == B_OK) {
|
||||||
resultWidth = view->StringWidth(date.String(), date.Length());
|
resultWidth = view->StringWidth(date.String(), date.Length());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <CheckBox.h>
|
#include <CheckBox.h>
|
||||||
#include <ControlLook.h>
|
#include <ControlLook.h>
|
||||||
|
#include <DateFormat.h>
|
||||||
#include <GridLayout.h>
|
#include <GridLayout.h>
|
||||||
#include <GridLayoutBuilder.h>
|
#include <GridLayoutBuilder.h>
|
||||||
#include <GroupLayout.h>
|
#include <GroupLayout.h>
|
||||||
@@ -360,16 +361,16 @@ FormatSettingsView::_UpdateExamples()
|
|||||||
time_t timeValue = (time_t)time(NULL);
|
time_t timeValue = (time_t)time(NULL);
|
||||||
BString result;
|
BString result;
|
||||||
|
|
||||||
BLocale::Default()->FormatDate(&result, timeValue, B_FULL_DATE_FORMAT);
|
BDateFormat::Default()->Format(&result, timeValue, B_FULL_DATE_FORMAT);
|
||||||
fFullDateExampleView->SetText(result);
|
fFullDateExampleView->SetText(result);
|
||||||
|
|
||||||
BLocale::Default()->FormatDate(&result, timeValue, B_LONG_DATE_FORMAT);
|
BDateFormat::Default()->Format(&result, timeValue, B_LONG_DATE_FORMAT);
|
||||||
fLongDateExampleView->SetText(result);
|
fLongDateExampleView->SetText(result);
|
||||||
|
|
||||||
BLocale::Default()->FormatDate(&result, timeValue, B_MEDIUM_DATE_FORMAT);
|
BDateFormat::Default()->Format(&result, timeValue, B_MEDIUM_DATE_FORMAT);
|
||||||
fMediumDateExampleView->SetText(result);
|
fMediumDateExampleView->SetText(result);
|
||||||
|
|
||||||
BLocale::Default()->FormatDate(&result, timeValue, B_SHORT_DATE_FORMAT);
|
BDateFormat::Default()->Format(&result, timeValue, B_SHORT_DATE_FORMAT);
|
||||||
fShortDateExampleView->SetText(result);
|
fShortDateExampleView->SetText(result);
|
||||||
|
|
||||||
BLocale::Default()->FormatTime(&result, timeValue, B_FULL_TIME_FORMAT);
|
BLocale::Default()->FormatTime(&result, timeValue, B_FULL_TIME_FORMAT);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <DateFormat.h>
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
@@ -622,14 +623,14 @@ TDateEdit::_UpdateFields()
|
|||||||
free(fFieldPositions);
|
free(fFieldPositions);
|
||||||
fFieldPositions = NULL;
|
fFieldPositions = NULL;
|
||||||
}
|
}
|
||||||
BLocale::Default()->FormatDate(&fText, fFieldPositions, fFieldPosCount,
|
BDateFormat::Default()->Format(&fText, fFieldPositions, fFieldPosCount,
|
||||||
time, B_SHORT_DATE_FORMAT);
|
time, B_SHORT_DATE_FORMAT);
|
||||||
|
|
||||||
if (fFields != NULL) {
|
if (fFields != NULL) {
|
||||||
free(fFields);
|
free(fFields);
|
||||||
fFields = NULL;
|
fFields = NULL;
|
||||||
}
|
}
|
||||||
BLocale::Default()->GetDateFields(fFields, fFieldCount,
|
BDateFormat::Default()->GetFields(fFields, fFieldCount,
|
||||||
B_SHORT_DATE_FORMAT);
|
B_SHORT_DATE_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <DateFormat.h>
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <TimeZone.h>
|
#include <TimeZone.h>
|
||||||
@@ -50,7 +51,7 @@ TimeZoneListView::GetToolTipAt(BPoint point, BToolTip** _tip)
|
|||||||
&item->TimeZone());
|
&item->TimeZone());
|
||||||
|
|
||||||
BString dateInTimeZone;
|
BString dateInTimeZone;
|
||||||
BLocale::Default()->FormatDate(&dateInTimeZone, now, B_SHORT_DATE_FORMAT,
|
BDateFormat::Default()->Format(&dateInTimeZone, now, B_SHORT_DATE_FORMAT,
|
||||||
&item->TimeZone());
|
&item->TimeZone());
|
||||||
|
|
||||||
BString toolTip = item->Text();
|
BString toolTip = item->Text();
|
||||||
|
|||||||
Reference in New Issue
Block a user