RemoteDrawingEngine: Reduce RP_READ_BITMAP result timeout.
[haiku.git] / src / kits / locale / RelativeDateTimeFormat.cpp
blob6b43885e77999a298f42a60e18c14885c1719c20
1 /*
2 * Copyright 2017, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Akshay Agarwal <agarwal.akshay.akshay8@gmail.com>
7 */
10 #include <unicode/uversion.h>
11 #include <RelativeDateTimeFormat.h>
13 #include <stdlib.h>
14 #include <time.h>
16 #include <unicode/gregocal.h>
17 #include <unicode/reldatefmt.h>
18 #include <unicode/utypes.h>
20 #include <ICUWrapper.h>
22 #include <Language.h>
23 #include <Locale.h>
24 #include <LocaleRoster.h>
25 #include <TimeUnitFormat.h>
28 static const URelativeDateTimeUnit kTimeUnitToRelativeDateTime[] = {
29 UDAT_REL_UNIT_YEAR,
30 UDAT_REL_UNIT_MONTH,
31 UDAT_REL_UNIT_WEEK,
32 UDAT_REL_UNIT_DAY,
33 UDAT_REL_UNIT_HOUR,
34 UDAT_REL_UNIT_MINUTE,
35 UDAT_REL_UNIT_SECOND,
39 static const UCalendarDateFields kTimeUnitToICUDateField[] = {
40 UCAL_YEAR,
41 UCAL_MONTH,
42 UCAL_WEEK_OF_MONTH,
43 UCAL_DAY_OF_WEEK,
44 UCAL_HOUR_OF_DAY,
45 UCAL_MINUTE,
46 UCAL_SECOND,
50 BRelativeDateTimeFormat::BRelativeDateTimeFormat()
51 : Inherited()
53 Locale icuLocale(fLanguage.Code());
54 UErrorCode icuStatus = U_ZERO_ERROR;
56 fFormatter = new RelativeDateTimeFormatter(icuLocale, icuStatus);
57 if (fFormatter == NULL) {
58 fInitStatus = B_NO_MEMORY;
59 return;
62 fCalendar = new GregorianCalendar(icuStatus);
63 if (fCalendar == NULL) {
64 fInitStatus = B_NO_MEMORY;
65 return;
68 if (!U_SUCCESS(icuStatus))
69 fInitStatus = B_ERROR;
73 BRelativeDateTimeFormat::BRelativeDateTimeFormat(const BLanguage& language,
74 const BFormattingConventions& conventions)
75 : Inherited(language, conventions)
77 Locale icuLocale(fLanguage.Code());
78 UErrorCode icuStatus = U_ZERO_ERROR;
80 fFormatter = new RelativeDateTimeFormatter(icuLocale, icuStatus);
81 if (fFormatter == NULL) {
82 fInitStatus = B_NO_MEMORY;
83 return;
86 fCalendar = new GregorianCalendar(icuStatus);
87 if (fCalendar == NULL) {
88 fInitStatus = B_NO_MEMORY;
89 return;
92 if (!U_SUCCESS(icuStatus))
93 fInitStatus = B_ERROR;
97 BRelativeDateTimeFormat::BRelativeDateTimeFormat(const BRelativeDateTimeFormat& other)
98 : Inherited(other),
99 fFormatter(other.fFormatter != NULL
100 ? new RelativeDateTimeFormatter(*other.fFormatter) : NULL),
101 fCalendar(other.fCalendar != NULL
102 ? new GregorianCalendar(*other.fCalendar) : NULL)
104 if ((fFormatter == NULL && other.fFormatter != NULL)
105 || (fCalendar == NULL && other.fCalendar != NULL))
106 fInitStatus = B_NO_MEMORY;
110 BRelativeDateTimeFormat::~BRelativeDateTimeFormat()
112 delete fFormatter;
113 delete fCalendar;
117 status_t
118 BRelativeDateTimeFormat::Format(BString& string,
119 const time_t timeValue) const
121 if (fFormatter == NULL)
122 return B_NO_INIT;
124 time_t currentTime = time(NULL);
126 UErrorCode icuStatus = U_ZERO_ERROR;
127 fCalendar->setTime((UDate)currentTime * 1000, icuStatus);
128 if (!U_SUCCESS(icuStatus))
129 return B_ERROR;
131 UDate UTimeValue = (UDate)timeValue * 1000;
133 int delta = 0;
134 int offset = 1;
135 URelativeDateTimeUnit unit = UDAT_REL_UNIT_SECOND;
137 for (int timeUnit = 0; timeUnit <= B_TIME_UNIT_LAST; ++timeUnit) {
138 delta = fCalendar->fieldDifference(UTimeValue,
139 kTimeUnitToICUDateField[timeUnit], icuStatus);
141 if (!U_SUCCESS(icuStatus))
142 return B_ERROR;
144 if (abs(delta) >= offset) {
145 unit = kTimeUnitToRelativeDateTime[timeUnit];
146 break;
150 UnicodeString unicodeResult;
152 // Note: icu::RelativeDateTimeFormatter::formatNumeric() is a part of ICU Draft API
153 // and may be changed in the future versions and was introduced in ICU 57.
154 fFormatter->formatNumeric(delta, unit, unicodeResult, icuStatus);
156 if (!U_SUCCESS(icuStatus))
157 return B_ERROR;
159 BStringByteSink byteSink(&string);
160 unicodeResult.toUTF8(byteSink);
162 return B_OK;