2 * Copyright 2017, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Akshay Agarwal <agarwal.akshay.akshay8@gmail.com>
10 #include <unicode/uversion.h>
11 #include <RelativeDateTimeFormat.h>
16 #include <unicode/gregocal.h>
17 #include <unicode/reldatefmt.h>
18 #include <unicode/utypes.h>
20 #include <ICUWrapper.h>
24 #include <LocaleRoster.h>
25 #include <TimeUnitFormat.h>
28 static const URelativeDateTimeUnit kTimeUnitToRelativeDateTime
[] = {
39 static const UCalendarDateFields kTimeUnitToICUDateField
[] = {
50 BRelativeDateTimeFormat::BRelativeDateTimeFormat()
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
;
62 fCalendar
= new GregorianCalendar(icuStatus
);
63 if (fCalendar
== NULL
) {
64 fInitStatus
= B_NO_MEMORY
;
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
;
86 fCalendar
= new GregorianCalendar(icuStatus
);
87 if (fCalendar
== NULL
) {
88 fInitStatus
= B_NO_MEMORY
;
92 if (!U_SUCCESS(icuStatus
))
93 fInitStatus
= B_ERROR
;
97 BRelativeDateTimeFormat::BRelativeDateTimeFormat(const BRelativeDateTimeFormat
& 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()
118 BRelativeDateTimeFormat::Format(BString
& string
,
119 const time_t timeValue
) const
121 if (fFormatter
== NULL
)
124 time_t currentTime
= time(NULL
);
126 UErrorCode icuStatus
= U_ZERO_ERROR
;
127 fCalendar
->setTime((UDate
)currentTime
* 1000, icuStatus
);
128 if (!U_SUCCESS(icuStatus
))
131 UDate UTimeValue
= (UDate
)timeValue
* 1000;
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
))
144 if (abs(delta
) >= offset
) {
145 unit
= kTimeUnitToRelativeDateTime
[timeUnit
];
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
))
159 BStringByteSink
byteSink(&string
);
160 unicodeResult
.toUTF8(byteSink
);