BPicture: Fix archive constructor.
[haiku.git] / src / kits / locale / DurationFormat.cpp
blob9536480b383336383a05271327e448790e80cf57
1 /*
2 * Copyright 2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Oliver Tappe <zooey@hirschkaefer.de>
7 */
10 #include <unicode/uversion.h>
11 #include <DurationFormat.h>
13 #include <new>
15 #include <unicode/gregocal.h>
16 #include <unicode/utypes.h>
18 #include <Locale.h>
19 #include <LocaleRoster.h>
20 #include <TimeZone.h>
22 #include <TimeZonePrivate.h>
25 // maps our unit element to the corresponding ICU unit
26 static const UCalendarDateFields skUnitMap[] = {
27 UCAL_YEAR,
28 UCAL_MONTH,
29 UCAL_WEEK_OF_MONTH,
30 UCAL_DAY_OF_WEEK,
31 UCAL_HOUR_OF_DAY,
32 UCAL_MINUTE,
33 UCAL_SECOND,
37 BDurationFormat::BDurationFormat(const BLanguage& language,
38 const BFormattingConventions& conventions, const BString& separator)
40 Inherited(language, conventions),
41 fSeparator(separator),
42 fTimeUnitFormat(language, conventions)
44 UErrorCode icuStatus = U_ZERO_ERROR;
45 fCalendar = new GregorianCalendar(icuStatus);
46 if (fCalendar == NULL) {
47 fInitStatus = B_NO_MEMORY;
48 return;
53 BDurationFormat::BDurationFormat(const BString& separator)
55 Inherited(),
56 fSeparator(separator),
57 fTimeUnitFormat()
59 UErrorCode icuStatus = U_ZERO_ERROR;
60 fCalendar = new GregorianCalendar(icuStatus);
61 if (fCalendar == NULL) {
62 fInitStatus = B_NO_MEMORY;
63 return;
68 BDurationFormat::BDurationFormat(const BDurationFormat& other)
70 Inherited(other),
71 fSeparator(other.fSeparator),
72 fTimeUnitFormat(other.fTimeUnitFormat),
73 fCalendar(other.fCalendar != NULL
74 ? new GregorianCalendar(*other.fCalendar) : NULL)
76 if (fCalendar == NULL && other.fCalendar != NULL)
77 fInitStatus = B_NO_MEMORY;
81 BDurationFormat::~BDurationFormat()
83 delete fCalendar;
87 void
88 BDurationFormat::SetSeparator(const BString& separator)
90 fSeparator = separator;
94 status_t
95 BDurationFormat::SetTimeZone(const BTimeZone* timeZone)
97 if (fCalendar == NULL)
98 return B_NO_INIT;
100 BTimeZone::Private zonePrivate;
101 if (timeZone == NULL) {
102 BTimeZone defaultTimeZone;
103 status_t result
104 = BLocaleRoster::Default()->GetDefaultTimeZone(&defaultTimeZone);
105 if (result != B_OK)
106 return result;
107 zonePrivate.SetTo(&defaultTimeZone);
108 } else
109 zonePrivate.SetTo(timeZone);
111 TimeZone* icuTimeZone = zonePrivate.ICUTimeZone();
112 if (icuTimeZone != NULL)
113 fCalendar->setTimeZone(*icuTimeZone);
115 return B_OK;
119 status_t
120 BDurationFormat::Format(BString& buffer, const bigtime_t startValue,
121 const bigtime_t stopValue, time_unit_style style) const
123 UErrorCode icuStatus = U_ZERO_ERROR;
124 fCalendar->setTime((UDate)startValue / 1000, icuStatus);
125 if (!U_SUCCESS(icuStatus))
126 return B_ERROR;
128 UDate stop = (UDate)stopValue / 1000;
129 bool needSeparator = false;
130 for (int unit = 0; unit <= B_TIME_UNIT_LAST; ++unit) {
131 int delta
132 = fCalendar->fieldDifference(stop, skUnitMap[unit], icuStatus);
133 if (!U_SUCCESS(icuStatus))
134 return B_ERROR;
136 if (delta != 0) {
137 if (needSeparator)
138 buffer.Append(fSeparator);
139 else
140 needSeparator = true;
141 status_t status = fTimeUnitFormat.Format(buffer, delta,
142 (time_unit_element)unit, style);
143 if (status != B_OK)
144 return status;
148 return B_OK;