xref: /haiku/src/kits/locale/TimeUnitFormat.cpp (revision 830f67ef991407f287dbc1238aa5f5906d90c991)
1 /*
2  * Copyright 2010, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  * 		Adrien Destugues <pulkomandy@gmail.com>
7  *		Oliver Tappe <zooey@hirschkaefer.de>
8  */
9 
10 
11 #include <unicode/uversion.h>
12 #include <TimeUnitFormat.h>
13 
14 #include <new>
15 
16 #include <unicode/format.h>
17 #include <unicode/locid.h>
18 #include <unicode/tmutfmt.h>
19 #include <unicode/utypes.h>
20 #include <ICUWrapper.h>
21 
22 #include <Language.h>
23 #include <Locale.h>
24 #include <LocaleRoster.h>
25 
26 
27 U_NAMESPACE_USE
28 
29 
30 // maps our unit element to the corresponding ICU unit
31 static const TimeUnit::UTimeUnitFields skUnitMap[] = {
32 	TimeUnit::UTIMEUNIT_YEAR,
33 	TimeUnit::UTIMEUNIT_MONTH,
34 	TimeUnit::UTIMEUNIT_WEEK,
35 	TimeUnit::UTIMEUNIT_DAY,
36 	TimeUnit::UTIMEUNIT_HOUR,
37 	TimeUnit::UTIMEUNIT_MINUTE,
38 	TimeUnit::UTIMEUNIT_SECOND,
39 };
40 
41 //maps our unit style to the corresponding ICU unit
42 static const UTimeUnitFormatStyle kTimeUnitStyleToICU[] = {
43 	UTMUTFMT_ABBREVIATED_STYLE,
44 	UTMUTFMT_FULL_STYLE,
45 };
46 
47 
48 BTimeUnitFormat::BTimeUnitFormat(const time_unit_style style)
49 	: Inherited()
50 {
51 	Locale icuLocale(fLanguage.Code());
52 	UErrorCode icuStatus = U_ZERO_ERROR;
53 	if (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL) {
54 		fFormatter = NULL;
55 		fInitStatus = B_BAD_VALUE;
56 		return;
57 	}
58 
59 	fFormatter = new TimeUnitFormat(icuLocale, kTimeUnitStyleToICU[style],
60 		icuStatus);
61 	if (fFormatter == NULL) {
62 		fInitStatus = B_NO_MEMORY;
63 		return;
64 	}
65 
66 	if (!U_SUCCESS(icuStatus))
67 		fInitStatus = B_ERROR;
68 }
69 
70 
71 BTimeUnitFormat::BTimeUnitFormat(const BLanguage& language,
72 	const BFormattingConventions& conventions,
73 	const time_unit_style style)
74 	: Inherited(language, conventions)
75 {
76 	Locale icuLocale(fLanguage.Code());
77 	UErrorCode icuStatus = U_ZERO_ERROR;
78 	if (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL) {
79 		fFormatter = NULL;
80 		fInitStatus = B_BAD_VALUE;
81 		return;
82 	}
83 
84 	fFormatter = new TimeUnitFormat(icuLocale, kTimeUnitStyleToICU[style],
85 		icuStatus);
86 	if (fFormatter == NULL) {
87 		fInitStatus = B_NO_MEMORY;
88 		return;
89 	}
90 
91 	if (!U_SUCCESS(icuStatus))
92 		fInitStatus = B_ERROR;
93 }
94 
95 
96 BTimeUnitFormat::BTimeUnitFormat(const BTimeUnitFormat& other)
97 	:
98 	Inherited(other),
99 	fFormatter(other.fFormatter != NULL
100 		? new TimeUnitFormat(*other.fFormatter) : NULL)
101 {
102 	if (fFormatter == NULL && other.fFormatter != NULL)
103 		fInitStatus = B_NO_MEMORY;
104 }
105 
106 
107 BTimeUnitFormat::~BTimeUnitFormat()
108 {
109 	delete fFormatter;
110 }
111 
112 
113 status_t
114 BTimeUnitFormat::Format(BString& buffer, const int32 value,
115 	const time_unit_element unit) const
116 {
117 	if (unit < 0 || unit > B_TIME_UNIT_LAST)
118 		return B_BAD_VALUE;
119 
120 	if (fFormatter == NULL)
121 		return B_NO_INIT;
122 
123 	UErrorCode icuStatus = U_ZERO_ERROR;
124 	TimeUnitAmount* timeUnitAmount
125 		= new TimeUnitAmount((double)value, skUnitMap[unit], icuStatus);
126 	if (timeUnitAmount == NULL)
127 		return B_NO_MEMORY;
128 	if (!U_SUCCESS(icuStatus)) {
129 		delete timeUnitAmount;
130 		return B_ERROR;
131 	}
132 
133 	Formattable formattable;
134 	formattable.adoptObject(timeUnitAmount);
135 	FieldPosition pos(FieldPosition::DONT_CARE);
136 	UnicodeString unicodeResult;
137 	fFormatter->format(formattable, unicodeResult, pos, icuStatus);
138 	if (!U_SUCCESS(icuStatus))
139 		return B_ERROR;
140 
141 	BStringByteSink byteSink(&buffer);
142 	unicodeResult.toUTF8(byteSink);
143 
144 	return B_OK;
145 }
146