xref: /haiku/src/kits/locale/DateTimeFormat.cpp (revision e3857211d305a595c2d0b58768f25623d5967675)
138ac8defSOliver Tappe /*
2*e3857211SAdrien Destugues  * Copyright 2010-2014, Haiku, Inc. All Rights Reserved.
338ac8defSOliver Tappe  * Distributed under the terms of the MIT License.
438ac8defSOliver Tappe  *
538ac8defSOliver Tappe  * Authors:
638ac8defSOliver Tappe  *		Oliver Tappe <zooey@hirschkaefer.de>
738ac8defSOliver Tappe  */
838ac8defSOliver Tappe 
938ac8defSOliver Tappe #include <DateTimeFormat.h>
1038ac8defSOliver Tappe 
11*e3857211SAdrien Destugues #include <AutoDeleter.h>
12*e3857211SAdrien Destugues #include <Autolock.h>
13*e3857211SAdrien Destugues #include <FormattingConventionsPrivate.h>
14*e3857211SAdrien Destugues #include <LanguagePrivate.h>
15*e3857211SAdrien Destugues #include <TimeZone.h>
1638ac8defSOliver Tappe 
17*e3857211SAdrien Destugues #include <ICUWrapper.h>
18*e3857211SAdrien Destugues 
19*e3857211SAdrien Destugues #include <unicode/datefmt.h>
20*e3857211SAdrien Destugues #include <unicode/smpdtfmt.h>
21*e3857211SAdrien Destugues 
22*e3857211SAdrien Destugues 
2338ac8defSOliver Tappe BDateTimeFormat::BDateTimeFormat()
2438ac8defSOliver Tappe 	: BFormat()
2538ac8defSOliver Tappe {
2638ac8defSOliver Tappe }
2738ac8defSOliver Tappe 
28f3dd81abSOliver Tappe 
2938ac8defSOliver Tappe BDateTimeFormat::BDateTimeFormat(const BDateTimeFormat &other)
3038ac8defSOliver Tappe 	: BFormat(other)
3138ac8defSOliver Tappe {
3238ac8defSOliver Tappe }
3338ac8defSOliver Tappe 
34f3dd81abSOliver Tappe 
3538ac8defSOliver Tappe BDateTimeFormat::~BDateTimeFormat()
3638ac8defSOliver Tappe {
3738ac8defSOliver Tappe }
3838ac8defSOliver Tappe 
39f3dd81abSOliver Tappe 
40*e3857211SAdrien Destugues // #pragma mark - Formatting
41*e3857211SAdrien Destugues 
42*e3857211SAdrien Destugues 
43*e3857211SAdrien Destugues ssize_t
44*e3857211SAdrien Destugues BDateTimeFormat::Format(char* target, size_t maxSize, time_t time,
45*e3857211SAdrien Destugues 	BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const
4638ac8defSOliver Tappe {
47*e3857211SAdrien Destugues 	BAutolock lock(fLock);
48*e3857211SAdrien Destugues 	if (!lock.IsLocked())
4938ac8defSOliver Tappe 		return B_ERROR;
50*e3857211SAdrien Destugues 
51*e3857211SAdrien Destugues 	BString format;
52*e3857211SAdrien Destugues 	fConventions.GetDateFormat(dateStyle, format);
53*e3857211SAdrien Destugues 	ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
54*e3857211SAdrien Destugues 	if (dateFormatter.Get() == NULL)
55*e3857211SAdrien Destugues 		return B_NO_MEMORY;
56*e3857211SAdrien Destugues 
57*e3857211SAdrien Destugues 	fConventions.GetTimeFormat(timeStyle, format);
58*e3857211SAdrien Destugues 	ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
59*e3857211SAdrien Destugues 	if (timeFormatter.Get() == NULL)
60*e3857211SAdrien Destugues 		return B_NO_MEMORY;
61*e3857211SAdrien Destugues 
62*e3857211SAdrien Destugues 	UnicodeString icuString;
63*e3857211SAdrien Destugues 	dateFormatter->format((UDate)time * 1000, icuString);
64*e3857211SAdrien Destugues 
65*e3857211SAdrien Destugues 	icuString.append(UnicodeString::fromUTF8(", "));
66*e3857211SAdrien Destugues 
67*e3857211SAdrien Destugues 	timeFormatter->format((UDate)time * 1000, icuString);
68*e3857211SAdrien Destugues 
69*e3857211SAdrien Destugues 	CheckedArrayByteSink stringConverter(target, maxSize);
70*e3857211SAdrien Destugues 	icuString.toUTF8(stringConverter);
71*e3857211SAdrien Destugues 
72*e3857211SAdrien Destugues 	if (stringConverter.Overflowed())
73*e3857211SAdrien Destugues 		return B_BAD_VALUE;
74*e3857211SAdrien Destugues 
75*e3857211SAdrien Destugues 	return stringConverter.NumberOfBytesWritten();
76*e3857211SAdrien Destugues }
77*e3857211SAdrien Destugues 
78*e3857211SAdrien Destugues 
79*e3857211SAdrien Destugues status_t
80*e3857211SAdrien Destugues BDateTimeFormat::Format(BString& target, const time_t time,
81*e3857211SAdrien Destugues 	BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle,
82*e3857211SAdrien Destugues 	const BTimeZone* timeZone) const
83*e3857211SAdrien Destugues {
84*e3857211SAdrien Destugues 	BAutolock lock(fLock);
85*e3857211SAdrien Destugues 	if (!lock.IsLocked())
86*e3857211SAdrien Destugues 		return B_ERROR;
87*e3857211SAdrien Destugues 
88*e3857211SAdrien Destugues 	BString format;
89*e3857211SAdrien Destugues 	fConventions.GetDateFormat(dateStyle, format);
90*e3857211SAdrien Destugues 	ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format));
91*e3857211SAdrien Destugues 	if (dateFormatter.Get() == NULL)
92*e3857211SAdrien Destugues 		return B_NO_MEMORY;
93*e3857211SAdrien Destugues 
94*e3857211SAdrien Destugues 	fConventions.GetTimeFormat(timeStyle, format);
95*e3857211SAdrien Destugues 	ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format));
96*e3857211SAdrien Destugues 	if (timeFormatter.Get() == NULL)
97*e3857211SAdrien Destugues 		return B_NO_MEMORY;
98*e3857211SAdrien Destugues 
99*e3857211SAdrien Destugues 	if (timeZone != NULL) {
100*e3857211SAdrien Destugues 		ObjectDeleter<TimeZone> icuTimeZone(
101*e3857211SAdrien Destugues 			TimeZone::createTimeZone(timeZone->ID().String()));
102*e3857211SAdrien Destugues 		if (icuTimeZone.Get() == NULL)
103*e3857211SAdrien Destugues 			return B_NO_MEMORY;
104*e3857211SAdrien Destugues 		timeFormatter->setTimeZone(*icuTimeZone.Get());
105*e3857211SAdrien Destugues 	}
106*e3857211SAdrien Destugues 
107*e3857211SAdrien Destugues 	UnicodeString icuString;
108*e3857211SAdrien Destugues 	dateFormatter->format((UDate)time * 1000, icuString);
109*e3857211SAdrien Destugues 	icuString.append(UnicodeString::fromUTF8(", "));
110*e3857211SAdrien Destugues 	timeFormatter->format((UDate)time * 1000, icuString);
111*e3857211SAdrien Destugues 
112*e3857211SAdrien Destugues 	target.Truncate(0);
113*e3857211SAdrien Destugues 	BStringByteSink stringConverter(&target);
114*e3857211SAdrien Destugues 	icuString.toUTF8(stringConverter);
115*e3857211SAdrien Destugues 
116*e3857211SAdrien Destugues 	return B_OK;
117*e3857211SAdrien Destugues }
118*e3857211SAdrien Destugues 
119*e3857211SAdrien Destugues 
120*e3857211SAdrien Destugues DateFormat*
121*e3857211SAdrien Destugues BDateTimeFormat::_CreateDateFormatter(const BString& format) const
122*e3857211SAdrien Destugues {
123*e3857211SAdrien Destugues 	Locale* icuLocale
124*e3857211SAdrien Destugues 		= fConventions.UseStringsFromPreferredLanguage()
125*e3857211SAdrien Destugues 			? BLanguage::Private(&fLanguage).ICULocale()
126*e3857211SAdrien Destugues 			: BFormattingConventions::Private(&fConventions).ICULocale();
127*e3857211SAdrien Destugues 
128*e3857211SAdrien Destugues 	icu::DateFormat* dateFormatter
129*e3857211SAdrien Destugues 		= icu::DateFormat::createDateInstance(DateFormat::kShort, *icuLocale);
130*e3857211SAdrien Destugues 	if (dateFormatter == NULL)
131*e3857211SAdrien Destugues 		return NULL;
132*e3857211SAdrien Destugues 
133*e3857211SAdrien Destugues 	SimpleDateFormat* dateFormatterImpl
134*e3857211SAdrien Destugues 		= static_cast<SimpleDateFormat*>(dateFormatter);
135*e3857211SAdrien Destugues 
136*e3857211SAdrien Destugues 	UnicodeString pattern(format.String());
137*e3857211SAdrien Destugues 	dateFormatterImpl->applyPattern(pattern);
138*e3857211SAdrien Destugues 
139*e3857211SAdrien Destugues 	return dateFormatter;
140*e3857211SAdrien Destugues }
141*e3857211SAdrien Destugues 
142*e3857211SAdrien Destugues 
143*e3857211SAdrien Destugues DateFormat*
144*e3857211SAdrien Destugues BDateTimeFormat::_CreateTimeFormatter(const BString& format) const
145*e3857211SAdrien Destugues {
146*e3857211SAdrien Destugues 	Locale* icuLocale
147*e3857211SAdrien Destugues 		= fConventions.UseStringsFromPreferredLanguage()
148*e3857211SAdrien Destugues 			? BLanguage::Private(&fLanguage).ICULocale()
149*e3857211SAdrien Destugues 			: BFormattingConventions::Private(&fConventions).ICULocale();
150*e3857211SAdrien Destugues 
151*e3857211SAdrien Destugues 	icu::DateFormat* timeFormatter
152*e3857211SAdrien Destugues 		= icu::DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale);
153*e3857211SAdrien Destugues 	if (timeFormatter == NULL)
154*e3857211SAdrien Destugues 		return NULL;
155*e3857211SAdrien Destugues 
156*e3857211SAdrien Destugues 	SimpleDateFormat* timeFormatterImpl
157*e3857211SAdrien Destugues 		= static_cast<SimpleDateFormat*>(timeFormatter);
158*e3857211SAdrien Destugues 
159*e3857211SAdrien Destugues 	UnicodeString pattern(format.String());
160*e3857211SAdrien Destugues 	timeFormatterImpl->applyPattern(pattern);
161*e3857211SAdrien Destugues 
162*e3857211SAdrien Destugues 	return timeFormatter;
16338ac8defSOliver Tappe }
164