1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4 * Copyright (c) 2016, International Business Machines Corporation
5 * and others. All Rights Reserved.
6 ********************************************************************/
7 /* C API TEST FOR DATE INTERVAL FORMAT */
8
9 #include "unicode/utypes.h"
10
11 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
12
13 #include "unicode/ureldatefmt.h"
14 #include "unicode/unum.h"
15 #include "unicode/udisplaycontext.h"
16 #include "unicode/ustring.h"
17 #include "cintltst.h"
18 #include "cmemory.h"
19 #include "cformtst.h"
20
21 static void TestRelDateFmt(void);
22 static void TestNumericField(void);
23 static void TestCombineDateTime(void);
24 static void TestFields(void);
25
26 void addRelativeDateFormatTest(TestNode** root);
27
28 #define TESTCASE(x) addTest(root, &x, "tsformat/crelativedateformattest/" #x)
29
addRelativeDateFormatTest(TestNode ** root)30 void addRelativeDateFormatTest(TestNode** root)
31 {
32 TESTCASE(TestRelDateFmt);
33 TESTCASE(TestNumericField);
34 TESTCASE(TestCombineDateTime);
35 TESTCASE(TestFields);
36 }
37
38 static const double offsets[] = { -5.0, -2.2, -2.0, -1.0, -0.7, -0.0, 0.0, 0.7, 1.0, 2.0, 5.0 };
39 enum { kNumOffsets = UPRV_LENGTHOF(offsets) };
40
41 typedef struct {
42 int32_t field;
43 int32_t beginPos;
44 int32_t endPos;
45 } FieldsDat;
46
47 static const char* en_decDef_long_midSent_sec[kNumOffsets*2] = {
48 /* text numeric */
49 "5 seconds ago", "5 seconds ago", /* -5 */
50 "2.2 seconds ago", "2.2 seconds ago", /* -2.2 */
51 "2 seconds ago", "2 seconds ago", /* -2 */
52 "1 second ago", "1 second ago", /* -1 */
53 "0.7 seconds ago", "0.7 seconds ago", /* -0.7 */
54 "now", "0 seconds ago", /* -0 */
55 "now", "in 0 seconds", /* 0 */
56 "in 0.7 seconds", "in 0.7 seconds", /* 0.7 */
57 "in 1 second", "in 1 second", /* 1 */
58 "in 2 seconds", "in 2 seconds", /* 2 */
59 "in 5 seconds", "in 5 seconds" /* 5 */
60 };
61
62 static const FieldsDat en_attrDef_long_midSent_sec[kNumOffsets*2] = {
63 /* text numeric text numeric */
64 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "5 seconds ago", "5 seconds ago", -5 */
65 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "2.2 seconds ago", "2.2 seconds ago", -2.2 */
66 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "2 seconds ago", "2 seconds ago", -2 */
67 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "1 second ago", "1 second ago", -1 */
68 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "0.7 seconds ago", "0.7 seconds ago", -0.7 */
69 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "now", "0 seconds ago", -0 */
70 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "now", "in 0 seconds", 0 */
71 {UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6}, /* "in 0.7 seconds", "in 0.7 seconds", 0.7 */
72 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 1 second", "in 1 second", 1 */
73 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 2 seconds", "in 2 seconds", 2 */
74 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 5 seconds", "in 5 seconds" 5 */
75 };
76
77 static const char* en_decDef_long_midSent_week[kNumOffsets*2] = {
78 /* text numeric */
79 "5 weeks ago", "5 weeks ago", /* -5 */
80 "2.2 weeks ago", "2.2 weeks ago", /* -2.2 */
81 "2 weeks ago", "2 weeks ago", /* -2 */
82 "last week", "1 week ago", /* -1 */
83 "0.7 weeks ago", "0.7 weeks ago", /* -0.7 */
84 "this week", "0 weeks ago", /* -0 */
85 "this week", "in 0 weeks", /* 0 */
86 "in 0.7 weeks", "in 0.7 weeks", /* 0.7 */
87 "next week", "in 1 week", /* 1 */
88 "in 2 weeks", "in 2 weeks", /* 2 */
89 "in 5 weeks", "in 5 weeks" /* 5 */
90 };
91
92 static const FieldsDat en_attrDef_long_midSent_week[kNumOffsets*2] = {
93 /* text numeric text numeric */
94 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "5 weeks ago", "5 weeks ago", -5 */
95 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "2.2 weeks ago", "2.2 weeks ago", -2.2 */
96 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "2 weeks ago", "2 weeks ago", -2 */
97 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "last week", "1 week ago", -1 */
98 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "0.7 weeks ago", "0.7 weeks ago", -0.7 */
99 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "this week", "0 weeks ago", -0 */
100 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "this week", "in 0 weeks", 0 */
101 {UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6}, /* "in 0.7 weeks", "in 0.7 weeks", 0.7 */
102 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "next week", "in 1 week", 1 */
103 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 2 weeks", "in 2 weeks", 2 */
104 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 5 weeks", "in 5 weeks" 5 */
105 };
106
107 static const char* en_dec0_long_midSent_week[kNumOffsets*2] = {
108 /* text numeric */
109 "5 weeks ago", "5 weeks ago", /* -5 */
110 "2 weeks ago", "2 weeks ago", /* -2.2 */
111 "2 weeks ago", "2 weeks ago", /* -2 */
112 "last week", "1 week ago", /* -1 */
113 "0 weeks ago", "0 weeks ago", /* -0.7 */
114 "this week", "0 weeks ago", /* -0 */
115 "this week", "in 0 weeks", /* 0 */
116 "in 0 weeks", "in 0 weeks", /* 0.7 */
117 "next week", "in 1 week", /* 1 */
118 "in 2 weeks", "in 2 weeks", /* 2 */
119 "in 5 weeks", "in 5 weeks" /* 5 */
120 };
121
122 static const FieldsDat en_attr0_long_midSent_week[kNumOffsets*2] = {
123 /* text numeric text numeric */
124 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "5 weeks ago", "5 weeks ago", -5 */
125 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "2 weeks ago", "2 weeks ago", -2.2 */
126 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "2 weeks ago", "2 weeks ago", -2 */
127 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "last week", "1 week ago", -1 */
128 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "0 weeks ago", "0 weeks ago", -0.7 */
129 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "this week", "0 weeks ago", -0 */
130 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "this week", "in 0 weeks", 0 */
131 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 0 weeks", "in 0 weeks", 0.7 */
132 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "next week", "in 1 week", 1 */
133 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 2 weeks", "in 2 weeks", 2 */
134 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 5 weeks", "in 5 weeks" 5 */
135 };
136
137 static const char* en_decDef_short_midSent_week[kNumOffsets*2] = {
138 /* text numeric */
139 "5 wk. ago", "5 wk. ago", /* -5 */
140 "2.2 wk. ago", "2.2 wk. ago", /* -2.2 */
141 "2 wk. ago", "2 wk. ago", /* -2 */
142 "last wk.", "1 wk. ago", /* -1 */
143 "0.7 wk. ago", "0.7 wk. ago", /* -0.7 */
144 "this wk.", "0 wk. ago", /* -0 */
145 "this wk.", "in 0 wk.", /* 0 */
146 "in 0.7 wk.", "in 0.7 wk.", /* 0.7 */
147 "next wk.", "in 1 wk.", /* 1 */
148 "in 2 wk.", "in 2 wk.", /* 2 */
149 "in 5 wk.", "in 5 wk." /* 5 */
150 };
151
152 static const FieldsDat en_attrDef_short_midSent_week[kNumOffsets*2] = {
153 /* text numeric text numeric */
154 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "5 wk. ago", "5 wk. ago", -5 */
155 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "2.2 wk. ago", "2.2 wk. ago", -2.2 */
156 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "2 wk. ago", "2 wk. ago", -2 */
157 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "last wk.", "1 wk. ago", -1 */
158 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "0.7 wk. ago", "0.7 wk. ago", -0.7 */
159 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "this wk.", "0 wk. ago", -0 */
160 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "this wk.", "in 0 wk.", 0 */
161 {UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6}, /* "in 0.7 wk.", "in 0.7 wk.", 0.7 */
162 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "next wk.", "in 1 wk.", 1 */
163 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 2 wk.", "in 2 wk.", 2 */
164 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 5 wk.", "in 5 wk." 5 */
165 };
166
167 static const char* en_decDef_long_midSent_min[kNumOffsets*2] = {
168 /* text numeric */
169 "5 minutes ago", "5 minutes ago", /* -5 */
170 "2.2 minutes ago", "2.2 minutes ago", /* -2.2 */
171 "2 minutes ago", "2 minutes ago", /* -2 */
172 "1 minute ago", "1 minute ago", /* -1 */
173 "0.7 minutes ago", "0.7 minutes ago", /* -0.7 */
174 "this minute", "0 minutes ago", /* -0 */
175 "this minute", "in 0 minutes", /* 0 */
176 "in 0.7 minutes", "in 0.7 minutes", /* 0.7 */
177 "in 1 minute", "in 1 minute", /* 1 */
178 "in 2 minutes", "in 2 minutes", /* 2 */
179 "in 5 minutes", "in 5 minutes" /* 5 */
180 };
181
182 static const FieldsDat en_attrDef_long_midSent_min[kNumOffsets*2] = {
183 /* text numeric text numeric */
184 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "5 minutes ago", "5 minutes ago", -5 */
185 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "2.2 minutes ago", "2.2 minutes ago", -2.2 */
186 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "2 minutes ago", "2 minutes ago", -2 */
187 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "1 minute ago", "1 minute ago", -1 */
188 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3}, /* "0.7 minutes ago", "0.7 minutes ago", -0.7 */
189 {-1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "this minute", "0 minutes ago", -0 */
190 {-1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "this minute", "in 0 minutes", 0 */
191 {UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6}, /* "in 0.7 minutes", "in 0.7 minutes", 0.7 */
192 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 1 minute", "in 1 minute", 1 */
193 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 2 minutes", "in 2 minutes", 2 */
194 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 5 minutes", "in 5 minutes" 5 */
195 };
196
197 static const char* en_dec0_long_midSent_tues[kNumOffsets*2] = {
198 /* text numeric */
199 "5 Tuesdays ago", "5 Tuesdays ago", /* -5 */
200 ""/*no data */, ""/*no data */, /* -2.2 */
201 "2 Tuesdays ago", "2 Tuesdays ago", /* -2 */
202 "last Tuesday", "1 Tuesday ago", /* -1 */
203 ""/*no data */, ""/*no data */, /* -0.7 */
204 "this Tuesday", "0 Tuesdays ago", /* -0 */
205 "this Tuesday", "in 0 Tuesdays", /* 0 */
206 ""/*no data */, ""/*no data */, /* 0.7 */
207 "next Tuesday", "in 1 Tuesday", /* 1 */
208 "in 2 Tuesdays", "in 2 Tuesdays", /* 2 */
209 "in 5 Tuesdays", "in 5 Tuesdays", /* 5 */
210 };
211
212 static const FieldsDat en_attr0_long_midSent_tues[kNumOffsets*2] = {
213 /* text numeric text numeric */
214 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "5 Tuesdays ago", "5 Tuesdays ago", -5 */
215 { -1, -1, -1}, { -1, -1, -1}, /* "" , "" , -2.2 */
216 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "2 Tuesdays ago", "2 Tuesdays ago", -2 */
217 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "last Tuesday", "1 Tuesday ago", -1 */
218 { -1, -1, -1}, { -1, -1, -1}, /* "" , "" , -0.7 */
219 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1}, /* "this Tuesday", "0 Tuesdays ago", -0 */
220 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "this Tuesday", "in 0 Tuesdays", 0 */
221 { -1, -1, -1}, { -1, -1, -1}, /* "" , "" , 0.7 */
222 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "next Tuesday", "in 1 Tuesday", 1 */
223 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 2 Tuesdays", "in 2 Tuesdays", 2 */
224 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 3, 4}, /* "in 5 Tuesdays", "in 5 Tuesdays", 5 */
225 };
226
227 static const char* fr_decDef_long_midSent_day[kNumOffsets*2] = {
228 /* text numeric */
229 "il y a 5 jours", "il y a 5 jours", /* -5 */
230 "il y a 2,2 jours", "il y a 2,2 jours", /* -2.2 */
231 "avant-hier", "il y a 2 jours", /* -2 */
232 "hier", "il y a 1 jour", /* -1 */
233 "il y a 0,7 jour", "il y a 0,7 jour", /* -0.7 */
234 "aujourd\\u2019hui", "il y a 0 jour", /* -0 */
235 "aujourd\\u2019hui", "dans 0 jour", /* 0 */
236 "dans 0,7 jour", "dans 0,7 jour", /* 0.7 */
237 "demain", "dans 1 jour", /* 1 */
238 "apr\\u00E8s-demain", "dans 2 jours", /* 2 */
239 "dans 5 jours", "dans 5 jours" /* 5 */
240 };
241
242 static const FieldsDat fr_attrDef_long_midSent_day[kNumOffsets*2] = {
243 /* text numeric text numeric */
244 {UDAT_REL_NUMERIC_FIELD, 7, 8}, {UDAT_REL_NUMERIC_FIELD, 7, 8}, /* "il y a 5 jours", "il y a 5 jours", -5 */
245 {UDAT_REL_NUMERIC_FIELD, 7, 10}, {UDAT_REL_NUMERIC_FIELD, 7, 10}, /* "il y a 2,2 jours", "il y a 2,2 jours", -2.2 */
246 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 7, 8}, /* "avant-hier", "il y a 2 jours", -2 */
247 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 7, 8}, /* "hier", "il y a 1 jour", -1 */
248 {UDAT_REL_NUMERIC_FIELD, 7, 10}, {UDAT_REL_NUMERIC_FIELD, 7, 10}, /* "il y a 0,7 jour", "il y a 0,7 jour", -0.7 */
249 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 7, 8}, /* "aujourd\\u2019hui", "il y a 0 jour", -0 */
250 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 5, 6}, /* "aujourd\\u2019hui", "dans 0 jour", 0 */
251 {UDAT_REL_NUMERIC_FIELD, 5, 8}, {UDAT_REL_NUMERIC_FIELD, 5, 8}, /* "dans 0,7 jour", "dans 0,7 jour", 0.7 */
252 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 5, 6}, /* "demain", "dans 1 jour", 1 */
253 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 5, 6}, /* "apr\\u00E8s-demain", "dans 2 jours", 2 */
254 {UDAT_REL_NUMERIC_FIELD, 5, 6}, {UDAT_REL_NUMERIC_FIELD, 5, 6}, /* "dans 5 jours", "dans 5 jours" 5 */
255 };
256
257 static const char* ak_decDef_long_stdAlon_sec[kNumOffsets*2] = { // falls back to root
258 /* text numeric */
259 "-5 s", "-5 s", /* -5 */
260 "-2.2 s", "-2.2 s", /* -2.2 */
261 "-2 s", "-2 s", /* -2 */
262 "-1 s", "-1 s", /* -1 */
263 "-0.7 s", "-0.7 s", /* -0.7 */
264 "now", "-0 s", /* -0 */
265 "now", "+0 s", /* 0 */
266 "+0.7 s", "+0.7 s", /* 0.7 */
267 "+1 s", "+1 s", /* 1 */
268 "+2 s", "+2 s", /* 2 */
269 "+5 s", "+5 s", /* 5 */
270 };
271
272 static const FieldsDat ak_attrDef_long_stdAlon_sec[kNumOffsets*2] = {
273 {UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
274 {UDAT_REL_NUMERIC_FIELD, 1, 4}, {UDAT_REL_NUMERIC_FIELD, 1, 4},
275 {UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
276 {UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
277 {UDAT_REL_NUMERIC_FIELD, 1, 4}, {UDAT_REL_NUMERIC_FIELD, 1, 4},
278 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
279 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
280 {UDAT_REL_NUMERIC_FIELD, 1, 4}, {UDAT_REL_NUMERIC_FIELD, 1, 4},
281 {UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
282 {UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
283 {UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
284 };
285
286 static const char* enIN_decDef_short_midSent_weds[kNumOffsets*2] = {
287 /* text numeric */
288 "5 Wed. ago", "5 Wed. ago", /* -5 */
289 "2.2 Wed. ago", "2.2 Wed. ago", /* -2.2 */
290 "2 Wed. ago", "2 Wed. ago", /* -2 */
291 "last Wed", "1 Wed. ago", /* -1 */
292 "0.7 Wed. ago", "0.7 Wed. ago", /* -0.7 */
293 "this Wed", "0 Wed. ago", /* -0 */
294 "this Wed", "in 0 Wed.", /* 0 */
295 "in 0.7 Wed.", "in 0.7 Wed.", /* 0.7 */
296 "next Wed", "in 1 Wed", /* 1 */ // in 1 Wed. missing in logical group
297 "in 2 Wed.", "in 2 Wed.", /* 2 */
298 "in 5 Wed.", "in 5 Wed." /* 5 */
299 };
300
301 static const FieldsDat enIN_attrDef_short_midSent_weds[kNumOffsets*2] = {
302 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
303 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
304 {UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
305 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
306 {UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
307 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
308 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
309 {UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6},
310 { -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
311 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
312 {UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
313 };
314
315 typedef struct {
316 const char* locale;
317 int32_t decPlaces; /* fixed decimal places; -1 to use default num formatter */
318 UDateRelativeDateTimeFormatterStyle width;
319 UDisplayContext capContext;
320 URelativeDateTimeUnit unit;
321 const char ** expectedResults; /* for the various offsets */
322 const FieldsDat* expectedAttributes;
323 } RelDateTimeFormatTestItem;
324
325 static const RelDateTimeFormatTestItem fmtTestItems[] = {
326 { "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_SECOND,
327 en_decDef_long_midSent_sec, en_attrDef_long_midSent_sec },
328 { "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK,
329 en_decDef_long_midSent_week, en_attrDef_long_midSent_week},
330 { "en", 0, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK,
331 en_dec0_long_midSent_week, en_attr0_long_midSent_week},
332 { "en", -1, UDAT_STYLE_SHORT, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK,
333 en_decDef_short_midSent_week, en_attrDef_short_midSent_week},
334 { "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_MINUTE,
335 en_decDef_long_midSent_min, en_attrDef_long_midSent_min},
336 { "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_TUESDAY,
337 en_dec0_long_midSent_tues, en_attr0_long_midSent_tues},
338 { "fr", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_DAY,
339 fr_decDef_long_midSent_day, fr_attrDef_long_midSent_day},
340 { "ak", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, UDAT_REL_UNIT_SECOND,
341 ak_decDef_long_stdAlon_sec, ak_attrDef_long_stdAlon_sec},
342 { "en_IN", -1, UDAT_STYLE_SHORT, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEDNESDAY,
343 enIN_decDef_short_midSent_weds, enIN_attrDef_short_midSent_weds},
344 { NULL, 0, (UDateRelativeDateTimeFormatterStyle)0, (UDisplayContext)0, (URelativeDateTimeUnit)0, NULL, NULL } /* terminator */
345 };
346
347 enum { kUBufMax = 64, kBBufMax = 256 };
348
TestRelDateFmt()349 static void TestRelDateFmt()
350 {
351 const RelDateTimeFormatTestItem *itemPtr;
352 log_verbose("\nTesting ureldatefmt_open(), ureldatefmt_format(), ureldatefmt_formatNumeric() with various parameters\n");
353 for (itemPtr = fmtTestItems; itemPtr->locale != NULL; itemPtr++) {
354 URelativeDateTimeFormatter *reldatefmt = NULL;
355 UNumberFormat* nfToAdopt = NULL;
356 UErrorCode status = U_ZERO_ERROR;
357 int32_t iOffset;
358
359 if (itemPtr->decPlaces >= 0) {
360 nfToAdopt = unum_open(UNUM_DECIMAL, NULL, 0, itemPtr->locale, NULL, &status);
361 if ( U_FAILURE(status) ) {
362 log_data_err("FAIL: unum_open(UNUM_DECIMAL, ...) for locale %s: %s\n", itemPtr->locale, myErrorName(status));
363 continue;
364 }
365 unum_setAttribute(nfToAdopt, UNUM_MIN_FRACTION_DIGITS, itemPtr->decPlaces);
366 unum_setAttribute(nfToAdopt, UNUM_MAX_FRACTION_DIGITS, itemPtr->decPlaces);
367 unum_setAttribute(nfToAdopt, UNUM_ROUNDING_MODE, UNUM_ROUND_DOWN);
368 }
369 reldatefmt = ureldatefmt_open(itemPtr->locale, nfToAdopt, itemPtr->width, itemPtr->capContext, &status);
370 if ( U_FAILURE(status) ) {
371 log_data_err("FAIL: ureldatefmt_open() for locale %s, decPlaces %d, width %d, capContext %d: %s\n",
372 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
373 myErrorName(status) );
374 continue;
375 }
376
377 for (iOffset = 0; iOffset < kNumOffsets; iOffset++) {
378 UChar ubufget[kUBufMax];
379 int32_t ulenget;
380
381 if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY && offsets[iOffset] != -1.0 && offsets[iOffset] != 0.0 && offsets[iOffset] != 1.0) {
382 continue; /* we do not currently have data for this */
383 }
384
385 status = U_ZERO_ERROR;
386 ulenget = ureldatefmt_format(reldatefmt, offsets[iOffset], itemPtr->unit, ubufget, kUBufMax, &status);
387 if ( U_FAILURE(status) ) {
388 log_err("FAIL: ureldatefmt_format() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
389 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
390 offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
391 } else {
392 UChar ubufexp[kUBufMax];
393 int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2], ubufexp, kUBufMax);
394 if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) {
395 char bbufget[kBBufMax];
396 u_austrncpy(bbufget, ubufget, kUBufMax);
397 log_err("ERROR: ureldatefmt_format() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d;\n expected %s\n get %s\n",
398 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
399 offsets[iOffset], (int)itemPtr->unit, itemPtr->expectedResults[iOffset*2], bbufget );
400 }
401 }
402
403 if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY) {
404 continue; /* we do not currently have numeric-style data for this */
405 }
406
407 status = U_ZERO_ERROR;
408 ulenget = ureldatefmt_formatNumeric(reldatefmt, offsets[iOffset], itemPtr->unit, ubufget, kUBufMax, &status);
409 if ( U_FAILURE(status) ) {
410 log_err("FAIL: ureldatefmt_formatNumeric() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
411 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
412 offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
413 } else {
414 UChar ubufexp[kUBufMax];
415 int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2 + 1], ubufexp, kUBufMax);
416 if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) {
417 char bbufget[kBBufMax];
418 u_austrncpy(bbufget, ubufget, kUBufMax);
419 log_err("ERROR: ureldatefmt_formatNumeric() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d;\n expected %s\n get %s\n",
420 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
421 offsets[iOffset], (int)itemPtr->unit, itemPtr->expectedResults[iOffset*2 + 1], bbufget );
422 }
423 }
424 }
425
426 ureldatefmt_close(reldatefmt);
427 }
428 }
429
TestNumericField()430 static void TestNumericField()
431 {
432 const RelDateTimeFormatTestItem *itemPtr;
433 log_verbose("\nTesting ureldatefmt_open(), ureldatefmt_formatForFields(), ureldatefmt_formatNumericForFields() with various parameters\n");
434 for (itemPtr = fmtTestItems; itemPtr->locale != NULL; itemPtr++) {
435 URelativeDateTimeFormatter *reldatefmt = NULL;
436 UNumberFormat* nfToAdopt = NULL;
437 UErrorCode status = U_ZERO_ERROR;
438 int32_t iOffset;
439
440 if (itemPtr->decPlaces >= 0) {
441 nfToAdopt = unum_open(UNUM_DECIMAL, NULL, 0, itemPtr->locale, NULL, &status);
442 if ( U_FAILURE(status) ) {
443 log_data_err("FAIL: unum_open(UNUM_DECIMAL, ...) for locale %s: %s\n", itemPtr->locale, myErrorName(status));
444 continue;
445 }
446 unum_setAttribute(nfToAdopt, UNUM_MIN_FRACTION_DIGITS, itemPtr->decPlaces);
447 unum_setAttribute(nfToAdopt, UNUM_MAX_FRACTION_DIGITS, itemPtr->decPlaces);
448 unum_setAttribute(nfToAdopt, UNUM_ROUNDING_MODE, UNUM_ROUND_DOWN);
449 }
450 reldatefmt = ureldatefmt_open(itemPtr->locale, nfToAdopt, itemPtr->width, itemPtr->capContext, &status);
451 if ( U_FAILURE(status) ) {
452 log_data_err("FAIL: ureldatefmt_open() for locale %s, decPlaces %d, width %d, capContext %d: %s\n",
453 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
454 myErrorName(status) );
455 continue;
456 }
457
458 for (iOffset = 0; iOffset < kNumOffsets; iOffset++) {
459 if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY && offsets[iOffset] != -1.0 && offsets[iOffset] != 0.0 && offsets[iOffset] != 1.0) {
460 continue; /* we do not currently have data for this */
461 }
462
463 /* Depend on the next one to verify the data */
464 status = U_ZERO_ERROR;
465 UFormattedRelativeDateTime* fv = ureldatefmt_openResult(&status);
466 if ( U_FAILURE(status) ) {
467 log_err("ureldatefmt_openResult fails, status %s\n", u_errorName(status));
468 continue;
469 }
470 ureldatefmt_formatToResult(reldatefmt, offsets[iOffset], itemPtr->unit, fv, &status);
471 if ( U_FAILURE(status) ) {
472 log_err("FAIL: ureldatefmt_formatForFields() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
473 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
474 offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
475 } else {
476 UChar ubufexp[kUBufMax];
477 int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2], ubufexp, kUBufMax);
478 int32_t ulenget;
479 const UChar* ubufget = ufmtval_getString(ureldatefmt_resultAsValue(fv, &status), &ulenget, &status);
480 assertUEquals("String content", ubufexp, ubufget);
481 assertIntEquals("String length", ulenexp, ulenget);
482
483 FieldsDat expectedAttr = itemPtr->expectedAttributes[iOffset*2];
484 UConstrainedFieldPosition* cfpos = ucfpos_open(&status);
485 UBool foundNumeric = FALSE;
486 while (TRUE) {
487 foundNumeric = ufmtval_nextPosition(ureldatefmt_resultAsValue(fv, &status), cfpos, &status);
488 if (!foundNumeric) {
489 break;
490 }
491 if (ucfpos_getCategory(cfpos, &status) == UFIELD_CATEGORY_RELATIVE_DATETIME
492 && ucfpos_getField(cfpos, &status) == UDAT_REL_NUMERIC_FIELD) {
493 break;
494 }
495 }
496 assertSuccess("Looking for numeric", &status);
497 int32_t beginPos, endPos;
498 ucfpos_getIndexes(cfpos, &beginPos, &endPos, &status);
499 if (expectedAttr.field == -1) {
500 if (foundNumeric) {
501 log_err("ureldatefmt_formatForFields as \"%s\"; expect no field, but got %d\n",
502 itemPtr->expectedResults[iOffset*2],
503 ucfpos_getField(cfpos, &status));
504 }
505 } else {
506 if (!foundNumeric ||
507 beginPos != expectedAttr.beginPos ||
508 endPos != expectedAttr.endPos) {
509 log_err("ureldatefmt_formatForFields as \"%s\"; expect field %d range %d-%d, get range %d-%d\n",
510 itemPtr->expectedResults[iOffset*2],
511 expectedAttr.field, expectedAttr.beginPos, expectedAttr.endPos,
512 beginPos, endPos);
513 }
514 }
515 ucfpos_close(cfpos);
516 }
517
518 if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY) {
519 ureldatefmt_closeResult(fv);
520 continue; /* we do not currently have numeric-style data for this */
521 }
522
523 /* Depend on the next one to verify the data */
524 status = U_ZERO_ERROR;
525 ureldatefmt_formatNumericToResult(reldatefmt, offsets[iOffset], itemPtr->unit, fv, &status);
526 if ( U_FAILURE(status) ) {
527 log_err("FAIL: ureldatefmt_formatNumericForFields() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
528 itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
529 offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
530 } else {
531 UChar ubufexp[kUBufMax];
532 int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2 + 1], ubufexp, kUBufMax);
533 int32_t ulenget;
534 const UChar* ubufget = ufmtval_getString(ureldatefmt_resultAsValue(fv, &status), &ulenget, &status);
535 assertUEquals("String content", ubufexp, ubufget);
536 assertIntEquals("String length", ulenexp, ulenget);
537
538 FieldsDat expectedAttr = itemPtr->expectedAttributes[iOffset*2 + 1];
539 UConstrainedFieldPosition* cfpos = ucfpos_open(&status);
540 UBool foundNumeric = FALSE;
541 while (TRUE) {
542 foundNumeric = ufmtval_nextPosition(ureldatefmt_resultAsValue(fv, &status), cfpos, &status);
543 if (!foundNumeric) {
544 break;
545 }
546 if (ucfpos_getCategory(cfpos, &status) == UFIELD_CATEGORY_RELATIVE_DATETIME
547 && ucfpos_getField(cfpos, &status) == UDAT_REL_NUMERIC_FIELD) {
548 break;
549 }
550 }
551 assertSuccess("Looking for numeric", &status);
552 int32_t beginPos, endPos;
553 ucfpos_getIndexes(cfpos, &beginPos, &endPos, &status);
554 if (expectedAttr.field == -1) {
555 if (foundNumeric) {
556 log_err("ureldatefmt_formatForFields as \"%s\"; expect no field, but got %d rang %d-%d\n",
557 itemPtr->expectedResults[iOffset*2],
558 ucfpos_getField(cfpos, &status), beginPos, endPos);
559 }
560 } else {
561 if (!foundNumeric ||
562 (beginPos != expectedAttr.beginPos || endPos != expectedAttr.endPos)) {
563 log_err("ureldatefmt_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
564 itemPtr->expectedResults[iOffset*2 + 1],
565 expectedAttr.field, expectedAttr.beginPos, expectedAttr.endPos,
566 ucfpos_getField(cfpos, &status), beginPos, endPos);
567 }
568 }
569 ucfpos_close(cfpos);
570 }
571 ureldatefmt_closeResult(fv);
572 }
573
574 ureldatefmt_close(reldatefmt);
575 }
576 }
577
578 typedef struct {
579 const char* locale;
580 UDateRelativeDateTimeFormatterStyle width;
581 UDisplayContext capContext;
582 const char * relativeDateString;
583 const char * timeString;
584 const char * expectedResult;
585 } CombineDateTimeTestItem;
586
587 static const CombineDateTimeTestItem combTestItems[] = {
588 { "en", UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, "yesterday", "3:45 PM", "yesterday, 3:45 PM" },
589 { NULL, (UDateRelativeDateTimeFormatterStyle)0, (UDisplayContext)0, NULL, NULL, NULL } /* terminator */
590 };
591
TestCombineDateTime()592 static void TestCombineDateTime()
593 {
594 const CombineDateTimeTestItem *itemPtr;
595 log_verbose("\nTesting ureldatefmt_combineDateAndTime() with various parameters\n");
596 for (itemPtr = combTestItems; itemPtr->locale != NULL; itemPtr++) {
597 URelativeDateTimeFormatter *reldatefmt = NULL;
598 UErrorCode status = U_ZERO_ERROR;
599 UChar ubufreldate[kUBufMax];
600 UChar ubuftime[kUBufMax];
601 UChar ubufget[kUBufMax];
602 int32_t ulenreldate, ulentime, ulenget;
603
604 reldatefmt = ureldatefmt_open(itemPtr->locale, NULL, itemPtr->width, itemPtr->capContext, &status);
605 if ( U_FAILURE(status) ) {
606 log_data_err("FAIL: ureldatefmt_open() for locale %s, width %d, capContext %d: %s\n",
607 itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) );
608 continue;
609 }
610
611 ulenreldate = u_unescape(itemPtr->relativeDateString, ubufreldate, kUBufMax);
612 ulentime = u_unescape(itemPtr->timeString, ubuftime, kUBufMax);
613 ulenget = ureldatefmt_combineDateAndTime(reldatefmt, ubufreldate, ulenreldate, ubuftime, ulentime, ubufget, kUBufMax, &status);
614 if ( U_FAILURE(status) ) {
615 log_err("FAIL: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d: %s\n",
616 itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) );
617 } else {
618 UChar ubufexp[kUBufMax];
619 int32_t ulenexp = u_unescape(itemPtr->expectedResult, ubufexp, kUBufMax);
620 if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) {
621 char bbufget[kBBufMax];
622 u_austrncpy(bbufget, ubufget, kUBufMax);
623 log_err("ERROR: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d;\n expected %s\n get %s\n",
624 itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, itemPtr->expectedResult, bbufget );
625 }
626 }
627 // preflight test
628 status = U_ZERO_ERROR;
629 ulenget = ureldatefmt_combineDateAndTime(reldatefmt, ubufreldate, ulenreldate, ubuftime, ulentime, NULL, 0, &status);
630 if ( status != U_BUFFER_OVERFLOW_ERROR) {
631 log_err("FAIL: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d: expected U_BUFFER_OVERFLOW_ERROR, got %s\n",
632 itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) );
633 } else {
634 UChar ubufexp[kUBufMax];
635 int32_t ulenexp = u_unescape(itemPtr->expectedResult, ubufexp, kUBufMax);
636 if (ulenget != ulenexp) {
637 log_err("ERROR: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d;\n expected len %d, get len %d\n",
638 itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, ulenexp, ulenget );
639 }
640 }
641
642 ureldatefmt_close(reldatefmt);
643 }
644 }
645
TestFields()646 static void TestFields() {
647 UErrorCode ec = U_ZERO_ERROR;
648 URelativeDateTimeFormatter* fmt = ureldatefmt_open(
649 "en-us",
650 NULL,
651 UDAT_STYLE_SHORT,
652 UDISPCTX_CAPITALIZATION_NONE,
653 &ec);
654 assertSuccess("Creating RelDTFmt", &ec);
655 UFormattedRelativeDateTime* frdt = ureldatefmt_openResult(&ec);
656 assertSuccess("Creating FmtVal", &ec);
657
658 ureldatefmt_formatNumericToResult(fmt, -50, UDAT_REL_UNIT_SATURDAY, frdt, &ec);
659 assertSuccess("formatNumeric", &ec);
660 {
661 const UFormattedValue* fv = ureldatefmt_resultAsValue(frdt, &ec);
662 assertSuccess("Should convert without error", &ec);
663 static const UFieldPositionWithCategory expectedFieldPositions[] = {
664 // category, field, begin index, end index
665 {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 0, 2},
666 {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 0, 2},
667 {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 3, 11}};
668 checkMixedFormattedValue(
669 "FormattedRelativeDateTime as FormattedValue (numeric)",
670 fv,
671 u"50 Sat. ago",
672 expectedFieldPositions,
673 UPRV_LENGTHOF(expectedFieldPositions));
674 }
675
676 ureldatefmt_formatToResult(fmt, -1, UDAT_REL_UNIT_WEEK, frdt, &ec);
677 assertSuccess("format", &ec);
678 {
679 const UFormattedValue* fv = ureldatefmt_resultAsValue(frdt, &ec);
680 assertSuccess("Should convert without error", &ec);
681 static const UFieldPositionWithCategory expectedFieldPositions[] = {
682 // category, field, begin index, end index
683 {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 8}};
684 checkMixedFormattedValue(
685 "FormattedRelativeDateTime as FormattedValue (relative)",
686 fv,
687 u"last wk.",
688 expectedFieldPositions,
689 UPRV_LENGTHOF(expectedFieldPositions));
690 }
691
692 ureldatefmt_closeResult(frdt);
693 ureldatefmt_close(fmt);
694 }
695
696 #endif /* #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION */
697