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