Skip to content

Commit ed68b40

Browse files
authored
ICU4C: fixing some date/time format problems (#223)
* Fix skeleton parsing in CPP date/time format. Update sampling, too * Fixing some CPP date time failures * Updating tools to understand failures
1 parent 6a94dcf commit ed68b40

File tree

9 files changed

+178
-24
lines changed

9 files changed

+178
-24
lines changed

executors/cpp/datetime_fmt.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,23 +132,26 @@ const string test_datetime_fmt(json_object *json_in) {
132132
timezone_str = json_object_get_string(option_item);
133133
UnicodeString u_tz(timezone_str.c_str());
134134
tz = TimeZone::createTimeZone(u_tz);
135-
cout << "# Created timezone " << tz << " for " << timezone_str << endl;
135+
// cout << "# Created timezone " << tz << " for " << timezone_str << endl;
136136
}
137137
}
138138

139139
json_object *date_skeleton_obj =
140-
json_object_object_get(json_in, "datetime_skeleton");
140+
json_object_object_get(json_in, "skeleton");
141141
if (date_skeleton_obj) {
142142
// Data specifies a date time skeleton. Make a formatter based on this.
143143
string skeleton_string = json_object_get_string(date_skeleton_obj);
144144

145+
cout << "# Skeleton = " << skeleton_string << endl;
145146
UnicodeString u_skeleton(skeleton_string.c_str());
146147
if (cal) {
148+
cout << " Cal defined " << endl;
147149
df = DateFormat::createInstanceForSkeleton(cal,
148150
u_skeleton,
149151
displayLocale,
150152
status);
151153
} else {
154+
cout << " NO CAL DEFINED " << endl;
152155
df = DateFormat::createInstanceForSkeleton(u_skeleton,
153156
displayLocale,
154157
status);
@@ -163,6 +166,12 @@ const string test_datetime_fmt(json_object *json_in) {
163166
}
164167
} else {
165168
// Create default formatter
169+
cout << "# createDateTimeInstance: dstyle " <<
170+
date_style << ", tstyle " <<
171+
time_style << " locale " <<
172+
locale_string <<
173+
endl;
174+
166175
df = DateFormat::createDateTimeInstance(
167176
date_style,
168177
time_style,
@@ -180,10 +189,7 @@ const string test_datetime_fmt(json_object *json_in) {
180189
}
181190

182191
if (tz) {
183-
cout <<
184-
"# Setting TZ " <<
185-
tz <<
186-
endl;
192+
// cout << "# Setting TZ " << tz << endl;
187193
df->setTimeZone(*tz);
188194
}
189195

executors/test_strings.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,18 @@
313313
{"test_type": "rdt_fmt", "label": "100", "unit":"day" "day", "count": 1, "locale": "en-US", "options": {}}
314314
{"test_type": "rdt_fmt", "label": "100", "unit":"day", "count": 1, "locale": "es", "options": {}}
315315

316+
317+
318+
// Testing skeleton options
319+
{"test_type": "datetime_fmt", "label":"10","input_string":"2001-09-09T01:46:40.000Z","locale":"en-US","options":{"calendar":"gregory","numberingSystem":"latn"}}
320+
{"test_type": "datetime_fmt", "label":"10","input_string":"2001-09-09T01:46:40.000Z","locale":"en-US","options":{"calendar":"gregory","numberingSystem":"latn"}}
321+
322+
{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"hh","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
323+
{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"h","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
324+
{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"H","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
325+
{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"hhh","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
326+
{"test_type": "datetime_fmt", "label":"1265","input_string":"2024-03-17T07:00:00.000Z","skeleton":"hhhm","locale":"en-US","options":{"hour":"2-digit","minute":"numeric","calendar":"chinese","timeZone":"Australia/Brisbane","numberingSystem":"latn"}}
327+
328+
{"test_type": "datetime_fmt", "label":"3812","input_string":"1969-07-16T07:00:00.000Z","skeleton":"HHm","locale":"en-GB","options":{"hour":"2-digit","minute":"numeric","calendar":"buddhist","timeZone":"Australia/Brisbane","numberingSystem":"latn"}}
329+
330+
{"test_type": "datetime_fmt", "label":"3812","input_string":"1969-07-16T07:00:00.000Z","locale":"en-GB","options":{"dateStyle": "short", "timeStyle": "short", "hour":"2-digit","minute":"numeric","calendar":"buddhist","timeZone":"Australia/Brisbane","numberingSystem":"latn"}}

testgen/generators/datetime_fmt.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def process_test_data(self):
3232

3333
# Set up Node version and call the generator
3434
nvm_version = icu_nvm_versions[self.icu_version]
35-
generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/datetime_gen.js' % (nvm_version, nvm_version)
35+
generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/datetime_gen.js %s %s' % (
36+
nvm_version, nvm_version, '-run_limit', self.run_limit)
3637

3738
logging.info('Running this command: %s', generate_command)
3839
result = result = subprocess.run(generate_command, shell=True)

testgen/generators/datetime_gen.js

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,10 @@ const dates = [
100100
new Date('Mar 17, 2024'),
101101
new Date('AD 1'),
102102
new Date('AD 0, 13:00'),
103+
//new Date('1066, December 16, 7:17'), // Expect Sunday
103104
new Date('1066, December 16, 7:17'),
104-
new Date('1454, May 29, 16:47'),
105+
// new Date('1454, May 29, 16:47'), // Expect Monday
106+
new Date('1754, May 29, 16:47'),
105107
new Date('BCE 753, April 21'),
106108
new Date('1969, July 16'),
107109
new Date(0),
@@ -188,7 +190,7 @@ function optionsToSkeleton(options) {
188190
return skeleton_array.join('');
189191
}
190192

191-
function generateAll() {
193+
function generateAll(run_limit) {
192194

193195
let test_obj = {
194196
'Test scenario': 'datetime_fmt',
@@ -256,7 +258,7 @@ function generateAll() {
256258
try {
257259
formatter = new Intl.DateTimeFormat(locale, all_options);
258260
} catch (error) {
259-
console.log(error, ' with locale ',
261+
console.error(error, ' with locale ',
260262
locale, ' and options: ', all_options);
261263
continue;
262264
}
@@ -268,7 +270,7 @@ function generateAll() {
268270
const parts = formatter.formatToParts(d);
269271
result = parts.map((x) => x.value).join("");
270272
} catch (error) {
271-
console.log('FORMATTER CREATION FAILS! ', error);
273+
console.error('FORMATTER CREATION FAILS! ', error);
272274
}
273275
// format this date
274276
// get the milliseconds
@@ -297,7 +299,7 @@ function generateAll() {
297299
}
298300

299301
if (debug) {
300-
console.log("TEST CASE :", test_case);
302+
console.debug("TEST CASE :", test_case);
301303
}
302304
test_cases.push(test_case);
303305

@@ -309,7 +311,7 @@ function generateAll() {
309311
console.log(' expected = ', result);
310312
}
311313
} catch (error) {
312-
console.log('!!! error ', error, ' in label ', label_num,
314+
console.error('!!! error ', error, ' in label ', label_num,
313315
' for date = ', d);
314316
}
315317
label_num ++;
@@ -318,25 +320,52 @@ function generateAll() {
318320
}
319321
}
320322

321-
322-
console.log('Number of date/time tests generated for ',
323+
console.log('Total date/time tests generated for ',
323324
process.versions.icu, ': ', label_num);
324325

325-
test_obj['tests'] = test_cases;
326+
test_obj['tests'] = sample_tests(test_cases, run_limit);
326327
try {
327328
fs.writeFileSync('datetime_fmt_test.json', JSON.stringify(test_obj, null, 2));
328329
// file written successfully
329330
} catch (err) {
330331
console.error(err);
331332
}
332333

333-
verify_obj['verifications'] = verify_cases;
334+
console.log('Number of date/time sampled tests ',
335+
process.versions.icu, ': ', test_obj['tests'] .length);
336+
337+
verify_obj['verifications'] = sample_tests(verify_cases, run_limit);
334338
try {
335339
fs.writeFileSync('datetime_fmt_verify.json', JSON.stringify(verify_obj, null, 2));
336340
// file written successfully
337341
} catch (err) {
338342
console.error(err);
339343
}
340344
}
345+
346+
function sample_tests(all_tests, run_limit) {
347+
// Gets a sampling of the data based on total and the expected number.
348+
349+
if (run_limit < 0 || all_tests.length <= run_limit) {
350+
return all_tests;
351+
}
352+
353+
let size_all = all_tests.length;
354+
let increment = Math.floor(size_all / run_limit);
355+
let samples = [];
356+
for (let index = 0; index < size_all; index += increment) {
357+
samples.push(all_tests[index]);
358+
}
359+
return samples;
360+
}
361+
341362
/* Call the generator */
342-
generateAll();
363+
let run_limit = -1;
364+
if (process.argv.length >= 5) {
365+
if (process.argv[3] == '-run_limit') {
366+
run_limit = Number(process.argv[4]);
367+
}
368+
}
369+
370+
// Call the generator
371+
generateAll(run_limit);

testgen/generators/relativedatetime_fmt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def process_test_data(self):
3535
generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/rdt_fmt_gen.js' % (nvm_version, nvm_version)
3636

3737
logging.info('Running this command: %s', generate_command)
38-
result = result = subprocess.run(generate_command, shell=True)
38+
result = subprocess.run(generate_command, shell=True)
3939

4040
# Move results to the right directory
4141
mv_command = 'mv rdt_fmt*.json %s' % self.icu_version

verifier/detail_template.html

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@
3333
cursor: pointer;
3434
font-size:20px;
3535
}
36-
36+
37+
#diff_area {
38+
font-size: 24px;
39+
font-color: blue;
40+
}
3741
h1, h2, h3, p {
3842
font-family: Arial, Helvetica, sans-serif;
3943
}
@@ -350,7 +354,7 @@
350354
} else {
351355
output = item[key];
352356
}
353-
html.push('<td onclick="captureInputDataOnClick(this);">' + output +'</td>');
357+
html.push('<td onclick="captureInputDataOnClick(this);" onmouseover="hoverDiffText(this);">' + output +'</td>');
354358
}
355359
}
356360
html.push("</tr>");
@@ -609,7 +613,31 @@
609613
navigator.clipboard.writeText(output);
610614
}
611615

616+
// On hover, show the differen between expected and actual result.
617+
function hoverDiffText(element) {
618+
// First, get the row of this item.
619+
const row = element.parentNode;
620+
const text1 = row.children[1].innerHTML;
621+
const text2 = row.children[2].innerHTML;
622+
if (text1 == text2) {
623+
return;
624+
}
625+
const dmp = new diff_match_patch();
626+
const diff_text = dmp.diff_main(text1, text2);
627+
dmp.diff_cleanupSemantic(diff_text);
628+
// And show the difference nicely.
629+
const ds = dmp.diff_prettyHtml(diff_text);
630+
const diff_area = document.getElementById("diff_area");
631+
diff_area.innerHTML = ds;
632+
}
612633
</script>
634+
635+
<!-- diff-match-patch code from
636+
https://github.com/google/diff-match-patch/wiki/Language:-JavaScript
637+
Intended to use for differences between expected and actual result.
638+
-->
639+
<script src="../../../diff_match_patch.js"></script>
640+
613641
</head>
614642
<body>
615643
<h1>Verification report: $test_type on $library_name</h1>
@@ -628,6 +656,10 @@ <h2>$platform_info</h2>
628656
<h2>Test details</h2>
629657
<p>$test_environment</p>
630658
</div>
659+
<div bp="4">
660+
<h2>Acknowledgements</h2>
661+
<p><a href='https://github.com/google/diff-match-patch/wiki/Language:-JavaScript'>diff-match-patch</a></p>
662+
</div>
631663
</div>
632664
<br>
633665
<div id='test_result_details' class='test_results'>
@@ -660,6 +692,7 @@ <h2>Test details</h2>
660692

661693
<details>
662694
<summary>Failing tests <span id='fail_count'>($failing_tests)</span></summary>
695+
<div id="diff_area"><p></p></div>
663696
<div id="fail-pagination-container"></div>
664697
<div id="fail-data-container"></div>
665698
<div id='testFailuresCharacterized'>

0 commit comments

Comments
 (0)