xref: /haiku/src/kits/locale/TimeUnitFormat.cpp (revision 97dfeb96704e5dbc5bec32ad7b21379d0125e031)
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 // maps our unit element to the corresponding ICU unit
27 static const TimeUnit::UTimeUnitFields skUnitMap[] = {
28 	TimeUnit::UTIMEUNIT_YEAR,
29 	TimeUnit::UTIMEUNIT_MONTH,
30 	TimeUnit::UTIMEUNIT_WEEK,
31 	TimeUnit::UTIMEUNIT_DAY,
32 	TimeUnit::UTIMEUNIT_HOUR,
33 	TimeUnit::UTIMEUNIT_MINUTE,
34 	TimeUnit::UTIMEUNIT_SECOND,
35 };
36 
37 
38 BTimeUnitFormat::BTimeUnitFormat()
39 	: Inherited()
40 {
41 	Locale icuLocale(fLanguage.Code());
42 	UErrorCode icuStatus = U_ZERO_ERROR;
43 	fFormatter = new TimeUnitFormat(icuLocale, icuStatus);
44 	if (fFormatter == NULL) {
45 		fInitStatus = B_NO_MEMORY;
46 		return;
47 	}
48 
49 	if (!U_SUCCESS(icuStatus))
50 		fInitStatus = B_ERROR;
51 }
52 
53 
54 BTimeUnitFormat::BTimeUnitFormat(const BLanguage& language,
55 	const BFormattingConventions& conventions)
56 	: Inherited(language, conventions)
57 {
58 	Locale icuLocale(fLanguage.Code());
59 	UErrorCode icuStatus = U_ZERO_ERROR;
60 	fFormatter = new TimeUnitFormat(icuLocale, 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 BTimeUnitFormat& other)
72 	:
73 	Inherited(other),
74 	fFormatter(other.fFormatter != NULL
75 		? new TimeUnitFormat(*other.fFormatter) : NULL)
76 {
77 	if (fFormatter == NULL && other.fFormatter != NULL)
78 		fInitStatus = B_NO_MEMORY;
79 }
80 
81 
82 BTimeUnitFormat::~BTimeUnitFormat()
83 {
84 	delete fFormatter;
85 }
86 
87 
88 status_t
89 BTimeUnitFormat::Format(BString& buffer, const int32 value,
90 	const time_unit_element unit, time_unit_style style) const
91 {
92 	if (unit < 0 || unit > B_TIME_UNIT_LAST
93 		|| (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL))
94 		return B_BAD_VALUE;
95 
96 	if (fFormatter == NULL)
97 		return B_NO_INIT;
98 
99 	UErrorCode icuStatus = U_ZERO_ERROR;
100 	TimeUnitAmount* timeUnitAmount
101 		= new TimeUnitAmount((double)value, skUnitMap[unit], icuStatus);
102 	if (timeUnitAmount == NULL)
103 		return B_NO_MEMORY;
104 	if (!U_SUCCESS(icuStatus))
105 		return B_ERROR;
106 
107 	Formattable formattable;
108 	formattable.adoptObject(timeUnitAmount);
109 	FieldPosition pos(FieldPosition::DONT_CARE);
110 	UnicodeString unicodeResult;
111 	fFormatter->format(formattable, unicodeResult, pos, icuStatus);
112 	if (!U_SUCCESS(icuStatus))
113 		return B_ERROR;
114 
115 	BStringByteSink byteSink(&buffer);
116 	unicodeResult.toUTF8(byteSink);
117 
118 	return B_OK;
119 }
120