xref: /haiku/src/kits/locale/TimeUnitFormat.cpp (revision 4466b89c65970de4c7236ac87faa2bee4589f413)
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 <TimeUnitFormat.h>
12 
13 #include <new>
14 
15 #include <unicode/format.h>
16 #include <unicode/locid.h>
17 #include <unicode/tmutfmt.h>
18 #include <unicode/utypes.h>
19 #include <ICUWrapper.h>
20 
21 #include <Language.h>
22 #include <Locale.h>
23 #include <LocaleRoster.h>
24 
25 // maps our unit element to the corresponding ICU unit
26 static const TimeUnit::UTimeUnitFields skUnitMap[] = {
27 	TimeUnit::UTIMEUNIT_YEAR,
28 	TimeUnit::UTIMEUNIT_MONTH,
29 	TimeUnit::UTIMEUNIT_WEEK,
30 	TimeUnit::UTIMEUNIT_DAY,
31 	TimeUnit::UTIMEUNIT_HOUR,
32 	TimeUnit::UTIMEUNIT_MINUTE,
33 	TimeUnit::UTIMEUNIT_SECOND,
34 };
35 
36 
37 BTimeUnitFormat::BTimeUnitFormat()
38 	:
39 	Inherited(),
40 	fFormatter(NULL)
41 {
42 	fInitStatus = SetLocale(fLocale);
43 }
44 
45 
46 BTimeUnitFormat::BTimeUnitFormat(const BTimeUnitFormat& other)
47 	:
48 	Inherited(other),
49 	fFormatter(other.fFormatter != NULL
50 		? new TimeUnitFormat(*other.fFormatter) : NULL)
51 {
52 	if (fFormatter == NULL && other.fFormatter != NULL)
53 		fInitStatus = B_NO_MEMORY;
54 }
55 
56 
57 BTimeUnitFormat::~BTimeUnitFormat()
58 {
59 	delete fFormatter;
60 }
61 
62 
63 BTimeUnitFormat&
64 BTimeUnitFormat::operator=(const BTimeUnitFormat& other)
65 {
66 	if (this == &other)
67 		return *this;
68 
69 	Inherited::operator=(other);
70 
71 	delete fFormatter;
72 	fFormatter = other.fFormatter != NULL
73 		? new TimeUnitFormat(*other.fFormatter) : NULL;
74 
75 	if (fFormatter == NULL && other.fFormatter != NULL)
76 		fInitStatus = B_NO_MEMORY;
77 
78 	return *this;
79 }
80 
81 
82 status_t
83 BTimeUnitFormat::SetLocale(const BLocale* locale)
84 {
85 	status_t result = Inherited::SetLocale(locale);
86 	if (result != B_OK)
87 		return result;
88 
89 	BLanguage language;
90 	if (fLocale != NULL)
91 		fLocale->GetLanguage(&language);
92 	else
93 		BLocale::Default()->GetLanguage(&language);
94 
95 	Locale icuLocale(language.Code());
96 	UErrorCode icuStatus = U_ZERO_ERROR;
97 	if (fFormatter == NULL) {
98 		fFormatter = new TimeUnitFormat(icuLocale, icuStatus);
99 		if (fFormatter == NULL)
100 			return B_NO_MEMORY;
101 	} else
102 		fFormatter->setLocale(icuLocale, icuStatus);
103 	if (!U_SUCCESS(icuStatus))
104 		return B_ERROR;
105 
106 	return B_OK;
107 }
108 
109 
110 status_t
111 BTimeUnitFormat::Format(int32 value, time_unit_element unit,
112 	BString* buffer, time_unit_style style) const
113 {
114 	if (buffer == NULL || unit < 0 || unit > B_TIME_UNIT_LAST
115 		|| (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL))
116 		return B_BAD_VALUE;
117 
118 	if (fFormatter == NULL)
119 		return B_NO_INIT;
120 
121 	UErrorCode icuStatus = U_ZERO_ERROR;
122 	TimeUnitAmount* timeUnitAmount
123 		= new TimeUnitAmount((double)value, skUnitMap[unit], icuStatus);
124 	if (timeUnitAmount == NULL)
125 		return B_NO_MEMORY;
126 	if (!U_SUCCESS(icuStatus))
127 		return B_ERROR;
128 
129 	Formattable formattable;
130 	formattable.adoptObject(timeUnitAmount);
131 	FieldPosition pos(FieldPosition::DONT_CARE);
132 	UnicodeString unicodeResult;
133 	fFormatter->format(formattable, unicodeResult, pos, icuStatus);
134 	if (!U_SUCCESS(icuStatus))
135 		return B_ERROR;
136 
137 	BStringByteSink byteSink(buffer);
138 	unicodeResult.toUTF8(byteSink);
139 
140 	return B_OK;
141 }
142