1 /********************************************************************
2 * Copyright (c) 2016, International Business Machines Corporation
3 * and others. All Rights Reserved.
4 ********************************************************************/
5 /* C API TEST FOR DATE INTERVAL FORMAT */
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
11 #include "unicode/ureldatefmt.h"
12 #include "unicode/unum.h"
13 #include "unicode/udisplaycontext.h"
14 #include "unicode/ustring.h"
18 static void TestRelDateFmt(void);
19 static void TestCombineDateTime(void);
21 void addRelativeDateFormatTest(TestNode
** root
);
23 #define TESTCASE(x) addTest(root, &x, "tsformat/crelativedateformattest/" #x)
25 void addRelativeDateFormatTest(TestNode
** root
)
27 TESTCASE(TestRelDateFmt
);
28 TESTCASE(TestCombineDateTime
);
31 static const double offsets
[] = { -5.0, -2.2, -2.0, -1.0, -0.7, 0.0, 0.7, 1.0, 2.0, 5.0 };
32 enum { kNumOffsets
= UPRV_LENGTHOF(offsets
) };
34 static const char* en_decDef_long_midSent_week
[kNumOffsets
*2] = {
36 "5 weeks ago", "5 weeks ago", /* -5 */
37 "2.2 weeks ago", "2.2 weeks ago", /* -2.2 */
38 "2 weeks ago", "2 weeks ago", /* -2 */
39 "last week", "1 week ago", /* -1 */
40 "0.7 weeks ago", "0.7 weeks ago", /* -0.7 */
41 "this week", "in 0 weeks", /* 0 */
42 "in 0.7 weeks", "in 0.7 weeks", /* 0.7 */
43 "next week", "in 1 week", /* 1 */
44 "in 2 weeks", "in 2 weeks", /* 2 */
45 "in 5 weeks", "in 5 weeks" /* 5 */
48 static const char* en_dec0_long_midSent_week
[kNumOffsets
*2] = {
50 "5 weeks ago", "5 weeks ago", /* -5 */
51 "2 weeks ago", "2 weeks ago", /* -2.2 */
52 "2 weeks ago", "2 weeks ago", /* -2 */
53 "last week", "1 week ago", /* -1 */
54 "0 weeks ago", "0 weeks ago", /* -0.7 */
55 "this week", "in 0 weeks", /* 0 */
56 "in 0 weeks", "in 0 weeks", /* 0.7 */
57 "next week", "in 1 week", /* 1 */
58 "in 2 weeks", "in 2 weeks", /* 2 */
59 "in 5 weeks", "in 5 weeks" /* 5 */
62 static const char* en_decDef_short_midSent_week
[kNumOffsets
*2] = {
64 "5 wk. ago", "5 wk. ago", /* -5 */
65 "2.2 wk. ago", "2.2 wk. ago", /* -2.2 */
66 "2 wk. ago", "2 wk. ago", /* -2 */
67 "last wk.", "1 wk. ago", /* -1 */
68 "0.7 wk. ago", "0.7 wk. ago", /* -0.7 */
69 "this wk.", "in 0 wk.", /* 0 */
70 "in 0.7 wk.", "in 0.7 wk.", /* 0.7 */
71 "next wk.", "in 1 wk.", /* 1 */
72 "in 2 wk.", "in 2 wk.", /* 2 */
73 "in 5 wk.", "in 5 wk." /* 5 */
76 static const char* en_decDef_long_midSent_min
[kNumOffsets
*2] = {
78 "5 minutes ago", "5 minutes ago", /* -5 */
79 "2.2 minutes ago", "2.2 minutes ago", /* -2.2 */
80 "2 minutes ago", "2 minutes ago", /* -2 */
81 "1 minute ago", "1 minute ago", /* -1 */
82 "0.7 minutes ago", "0.7 minutes ago", /* -0.7 */
83 "in 0 minutes", "in 0 minutes", /* 0 */
84 "in 0.7 minutes", "in 0.7 minutes", /* 0.7 */
85 "in 1 minute", "in 1 minute", /* 1 */
86 "in 2 minutes", "in 2 minutes", /* 2 */
87 "in 5 minutes", "in 5 minutes" /* 5 */
90 static const char* en_dec0_long_midSent_tues
[kNumOffsets
*2] = {
92 ""/*no data */, ""/*no data */, /* -5 */
93 ""/*no data */, ""/*no data */, /* -2.2 */
94 ""/*no data */, ""/*no data */, /* -2 */
95 "last Tuesday", ""/*no data */, /* -1 */
96 ""/*no data */, ""/*no data */, /* -0.7 */
97 "this Tuesday", ""/*no data */, /* 0 */
98 ""/*no data */, ""/*no data */, /* 0.7 */
99 "next Tuesday", ""/*no data */, /* 1 */
100 ""/*no data */, ""/*no data */, /* 2 */
101 ""/*no data */, ""/*no data */, /* 5 */
104 static const char* fr_decDef_long_midSent_day
[kNumOffsets
*2] = {
106 "il y a 5 jours", "il y a 5 jours", /* -5 */
107 "il y a 2,2 jours", "il y a 2,2 jours", /* -2.2 */
108 "avant-hier", "il y a 2 jours", /* -2 */
109 "hier", "il y a 1 jour", /* -1 */
110 "il y a 0,7 jour", "il y a 0,7 jour", /* -0.7 */
111 "aujourd\\u2019hui", "dans 0 jour", /* 0 */
112 "dans 0,7 jour", "dans 0,7 jour", /* 0.7 */
113 "demain", "dans 1 jour", /* 1 */
114 "apr\\u00E8s-demain", "dans 2 jours", /* 2 */
115 "dans 5 jours", "dans 5 jours" /* 5 */
121 int32_t decPlaces
; /* fixed decimal places; -1 to use default num formatter */
122 UDateRelativeDateTimeFormatterStyle width
;
123 UDisplayContext capContext
;
124 URelativeDateTimeUnit unit
;
125 const char ** expectedResults
; /* for the various offsets */
126 } RelDateTimeFormatTestItem
;
128 static const RelDateTimeFormatTestItem fmtTestItems
[] = {
129 { "en", -1, UDAT_STYLE_LONG
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDAT_REL_UNIT_WEEK
, en_decDef_long_midSent_week
},
130 { "en", 0, UDAT_STYLE_LONG
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDAT_REL_UNIT_WEEK
, en_dec0_long_midSent_week
},
131 { "en", -1, UDAT_STYLE_SHORT
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDAT_REL_UNIT_WEEK
, en_decDef_short_midSent_week
},
132 { "en", -1, UDAT_STYLE_LONG
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDAT_REL_UNIT_MINUTE
, en_decDef_long_midSent_min
},
133 { "en", -1, UDAT_STYLE_LONG
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDAT_REL_UNIT_TUESDAY
, en_dec0_long_midSent_tues
},
134 { "fr", -1, UDAT_STYLE_LONG
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDAT_REL_UNIT_DAY
, fr_decDef_long_midSent_day
},
135 { NULL
, 0, (UDateRelativeDateTimeFormatterStyle
)0, (UDisplayContext
)0, (URelativeDateTimeUnit
)0, NULL
} /* terminator */
138 enum { kUBufMax
= 64, kBBufMax
= 256 };
140 static void TestRelDateFmt()
142 const RelDateTimeFormatTestItem
*itemPtr
;
143 log_verbose("\nTesting ureldatefmt_open(), ureldatefmt_format(), ureldatefmt_formatNumeric() with various parameters\n");
144 for (itemPtr
= fmtTestItems
; itemPtr
->locale
!= NULL
; itemPtr
++) {
145 URelativeDateTimeFormatter
*reldatefmt
= NULL
;
146 UNumberFormat
* nfToAdopt
= NULL
;
147 UErrorCode status
= U_ZERO_ERROR
;
150 if (itemPtr
->decPlaces
>= 0) {
151 nfToAdopt
= unum_open(UNUM_DECIMAL
, NULL
, 0, itemPtr
->locale
, NULL
, &status
);
152 if ( U_FAILURE(status
) ) {
153 log_data_err("FAIL: unum_open(UNUM_DECIMAL, ...) for locale %s: %s\n", itemPtr
->locale
, myErrorName(status
));
156 unum_setAttribute(nfToAdopt
, UNUM_MIN_FRACTION_DIGITS
, itemPtr
->decPlaces
);
157 unum_setAttribute(nfToAdopt
, UNUM_MAX_FRACTION_DIGITS
, itemPtr
->decPlaces
);
158 unum_setAttribute(nfToAdopt
, UNUM_ROUNDING_MODE
, UNUM_ROUND_DOWN
);
160 reldatefmt
= ureldatefmt_open(itemPtr
->locale
, nfToAdopt
, itemPtr
->width
, itemPtr
->capContext
, &status
);
161 if ( U_FAILURE(status
) ) {
162 log_data_err("FAIL: ureldatefmt_open() for locale %s, decPlaces %d, width %d, capContext %d: %s\n",
163 itemPtr
->locale
, itemPtr
->decPlaces
, (int)itemPtr
->width
, (int)itemPtr
->capContext
,
164 myErrorName(status
) );
168 for (iOffset
= 0; iOffset
< kNumOffsets
; iOffset
++) {
169 UChar ubufget
[kUBufMax
];
172 if (itemPtr
->unit
>= UDAT_REL_UNIT_SUNDAY
&& offsets
[iOffset
] != -1.0 && offsets
[iOffset
] != 0.0 && offsets
[iOffset
] != 1.0) {
173 continue; /* we do not currently have data for this */
176 status
= U_ZERO_ERROR
;
177 ulenget
= ureldatefmt_format(reldatefmt
, offsets
[iOffset
], itemPtr
->unit
, ubufget
, kUBufMax
, &status
);
178 if ( U_FAILURE(status
) ) {
179 log_err("FAIL: ureldatefmt_format() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
180 itemPtr
->locale
, itemPtr
->decPlaces
, (int)itemPtr
->width
, (int)itemPtr
->capContext
,
181 offsets
[iOffset
], (int)itemPtr
->unit
, myErrorName(status
) );
183 UChar ubufexp
[kUBufMax
];
184 int32_t ulenexp
= u_unescape(itemPtr
->expectedResults
[iOffset
*2], ubufexp
, kUBufMax
);
185 if (ulenget
!= ulenexp
|| u_strncmp(ubufget
, ubufexp
, ulenexp
) != 0) {
186 char bbufget
[kBBufMax
];
187 u_austrncpy(bbufget
, ubufget
, kUBufMax
);
188 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",
189 itemPtr
->locale
, itemPtr
->decPlaces
, (int)itemPtr
->width
, (int)itemPtr
->capContext
,
190 offsets
[iOffset
], (int)itemPtr
->unit
, itemPtr
->expectedResults
[iOffset
*2], bbufget
);
194 if (itemPtr
->unit
>= UDAT_REL_UNIT_SUNDAY
) {
195 continue; /* we do not currently have numeric-style data for this */
198 status
= U_ZERO_ERROR
;
199 ulenget
= ureldatefmt_formatNumeric(reldatefmt
, offsets
[iOffset
], itemPtr
->unit
, ubufget
, kUBufMax
, &status
);
200 if ( U_FAILURE(status
) ) {
201 log_err("FAIL: ureldatefmt_formatNumeric() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
202 itemPtr
->locale
, itemPtr
->decPlaces
, (int)itemPtr
->width
, (int)itemPtr
->capContext
,
203 offsets
[iOffset
], (int)itemPtr
->unit
, myErrorName(status
) );
205 UChar ubufexp
[kUBufMax
];
206 int32_t ulenexp
= u_unescape(itemPtr
->expectedResults
[iOffset
*2 + 1], ubufexp
, kUBufMax
);
207 if (ulenget
!= ulenexp
|| u_strncmp(ubufget
, ubufexp
, ulenexp
) != 0) {
208 char bbufget
[kBBufMax
];
209 u_austrncpy(bbufget
, ubufget
, kUBufMax
);
210 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",
211 itemPtr
->locale
, itemPtr
->decPlaces
, (int)itemPtr
->width
, (int)itemPtr
->capContext
,
212 offsets
[iOffset
], (int)itemPtr
->unit
, itemPtr
->expectedResults
[iOffset
*2 + 1], bbufget
);
217 ureldatefmt_close(reldatefmt
);
223 UDateRelativeDateTimeFormatterStyle width
;
224 UDisplayContext capContext
;
225 const char * relativeDateString
;
226 const char * timeString
;
227 const char * expectedResult
;
228 } CombineDateTimeTestItem
;
230 static const CombineDateTimeTestItem combTestItems
[] = {
231 { "en", UDAT_STYLE_LONG
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, "yesterday", "3:45 PM", "yesterday, 3:45 PM" },
232 { NULL
, (UDateRelativeDateTimeFormatterStyle
)0, (UDisplayContext
)0, NULL
, NULL
, NULL
} /* terminator */
235 static void TestCombineDateTime()
237 const CombineDateTimeTestItem
*itemPtr
;
238 log_verbose("\nTesting ureldatefmt_combineDateAndTime() with various parameters\n");
239 for (itemPtr
= combTestItems
; itemPtr
->locale
!= NULL
; itemPtr
++) {
240 URelativeDateTimeFormatter
*reldatefmt
= NULL
;
241 UErrorCode status
= U_ZERO_ERROR
;
242 UChar ubufreldate
[kUBufMax
];
243 UChar ubuftime
[kUBufMax
];
244 UChar ubufget
[kUBufMax
];
245 int32_t ulenreldate
, ulentime
, ulenget
;
247 reldatefmt
= ureldatefmt_open(itemPtr
->locale
, NULL
, itemPtr
->width
, itemPtr
->capContext
, &status
);
248 if ( U_FAILURE(status
) ) {
249 log_data_err("FAIL: ureldatefmt_open() for locale %s, width %d, capContext %d: %s\n",
250 itemPtr
->locale
, (int)itemPtr
->width
, (int)itemPtr
->capContext
, myErrorName(status
) );
254 ulenreldate
= u_unescape(itemPtr
->relativeDateString
, ubufreldate
, kUBufMax
);
255 ulentime
= u_unescape(itemPtr
->timeString
, ubuftime
, kUBufMax
);
256 ulenget
= ureldatefmt_combineDateAndTime(reldatefmt
, ubufreldate
, ulenreldate
, ubuftime
, ulentime
, ubufget
, kUBufMax
, &status
);
257 if ( U_FAILURE(status
) ) {
258 log_err("FAIL: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d: %s\n",
259 itemPtr
->locale
, (int)itemPtr
->width
, (int)itemPtr
->capContext
, myErrorName(status
) );
261 UChar ubufexp
[kUBufMax
];
262 int32_t ulenexp
= u_unescape(itemPtr
->expectedResult
, ubufexp
, kUBufMax
);
263 if (ulenget
!= ulenexp
|| u_strncmp(ubufget
, ubufexp
, ulenexp
) != 0) {
264 char bbufget
[kBBufMax
];
265 u_austrncpy(bbufget
, ubufget
, kUBufMax
);
266 log_err("ERROR: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d;\n expected %s\n get %s\n",
267 itemPtr
->locale
, (int)itemPtr
->width
, (int)itemPtr
->capContext
, itemPtr
->expectedResult
, bbufget
);
271 status
= U_ZERO_ERROR
;
272 ulenget
= ureldatefmt_combineDateAndTime(reldatefmt
, ubufreldate
, ulenreldate
, ubuftime
, ulentime
, NULL
, 0, &status
);
273 if ( status
!= U_BUFFER_OVERFLOW_ERROR
) {
274 log_err("FAIL: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d: expected U_BUFFER_OVERFLOW_ERROR, got %s\n",
275 itemPtr
->locale
, (int)itemPtr
->width
, (int)itemPtr
->capContext
, myErrorName(status
) );
277 UChar ubufexp
[kUBufMax
];
278 int32_t ulenexp
= u_unescape(itemPtr
->expectedResult
, ubufexp
, kUBufMax
);
279 if (ulenget
!= ulenexp
) {
280 log_err("ERROR: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d;\n expected len %d, get len %d\n",
281 itemPtr
->locale
, (int)itemPtr
->width
, (int)itemPtr
->capContext
, ulenexp
, ulenget
);
285 ureldatefmt_close(reldatefmt
);
289 #endif /* #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION */