xref: /haiku/src/kits/locale/TimeUnitFormat.cpp (revision 81ec973846ea4816c53ed8901822e43c8b06878d)
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 	: Inherited()
39 {
40 	Locale icuLocale(fLanguage.Code());
41 	UErrorCode icuStatus = U_ZERO_ERROR;
42 	fFormatter = new TimeUnitFormat(icuLocale, icuStatus);
43 	if (fFormatter == NULL) {
44 		fInitStatus = B_NO_MEMORY;
45 		return;
46 	}
47 
48 	if (!U_SUCCESS(icuStatus))
49 		fInitStatus = B_ERROR;
50 }
51 
52 
53 BTimeUnitFormat::BTimeUnitFormat(const BLanguage& language,
54 	const BFormattingConventions& conventions)
55 	: Inherited(language, conventions)
56 {
57 	Locale icuLocale(fLanguage.Code());
58 	UErrorCode icuStatus = U_ZERO_ERROR;
59 	fFormatter = new TimeUnitFormat(icuLocale, icuStatus);
60 	if (fFormatter == NULL) {
61 		fInitStatus = B_NO_MEMORY;
62 		return;
63 	}
64 
65 	if (!U_SUCCESS(icuStatus))
66 		fInitStatus = B_ERROR;
67 }
68 
69 
70 BTimeUnitFormat::BTimeUnitFormat(const BTimeUnitFormat& other)
71 	:
72 	Inherited(other),
73 	fFormatter(other.fFormatter != NULL
74 		? new TimeUnitFormat(*other.fFormatter) : NULL)
75 {
76 	if (fFormatter == NULL && other.fFormatter != NULL)
77 		fInitStatus = B_NO_MEMORY;
78 }
79 
80 
81 BTimeUnitFormat::~BTimeUnitFormat()
82 {
83 	delete fFormatter;
84 }
85 
86 
87 status_t
88 BTimeUnitFormat::Format(BString& buffer, const int32 value,
89 	const time_unit_element unit, time_unit_style style) const
90 {
91 	if (unit < 0 || unit > B_TIME_UNIT_LAST
92 		|| (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL))
93 		return B_BAD_VALUE;
94 
95 	if (fFormatter == NULL)
96 		return B_NO_INIT;
97 
98 	UErrorCode icuStatus = U_ZERO_ERROR;
99 	TimeUnitAmount* timeUnitAmount
100 		= new TimeUnitAmount((double)value, skUnitMap[unit], icuStatus);
101 	if (timeUnitAmount == NULL)
102 		return B_NO_MEMORY;
103 	if (!U_SUCCESS(icuStatus))
104 		return B_ERROR;
105 
106 	Formattable formattable;
107 	formattable.adoptObject(timeUnitAmount);
108 	FieldPosition pos(FieldPosition::DONT_CARE);
109 	UnicodeString unicodeResult;
110 	fFormatter->format(formattable, unicodeResult, pos, icuStatus);
111 	if (!U_SUCCESS(icuStatus))
112 		return B_ERROR;
113 
114 	BStringByteSink byteSink(&buffer);
115 	unicodeResult.toUTF8(byteSink);
116 
117 	return B_OK;
118 }
119