blob: bf6656d4b565a9a2f0c69c8f47962b88dbf04954 [file] [log] [blame]
function shouldBe(actual, expected) {
// Tolerate different space characters used by different ICU versions.
// Older ICU uses U+2009 Thin Space in ranges, whereas newer ICU uses
// regular old U+0020. Let's ignore these differences.
if (typeof actual === 'string')
actual = actual.replaceAll(' ', ' ');
if (actual !== expected)
throw new Error('bad value: ' + actual + ' expected value: ' + expected);
}
function shouldBeOneOf(actual, expectedArray) {
// Tolerate different space characters used by different ICU versions.
// Older ICU uses U+2009 Thin Space in ranges, whereas newer ICU uses
// regular old U+0020. Let's ignore these differences.
if (typeof actual === 'string')
actual = actual.replaceAll(' ', ' ');
if (!expectedArray.some((value) => value === actual))
throw new Error('bad value: ' + actual + ' expected values: ' + expectedArray);
}
function shouldThrow(func, errorMessage) {
var errorThrown = false;
var error = null;
try {
func();
} catch (e) {
errorThrown = true;
error = e;
}
if (!errorThrown)
throw new Error('not thrown');
if (String(error) !== errorMessage)
throw new Error(`bad error: ${String(error)}`);
}
let date1 = new Date(Date.UTC(2007, 0, 10, 10, 0, 0));
let date2 = new Date(Date.UTC(2007, 0, 10, 11, 0, 0));
let date3 = new Date(Date.UTC(2007, 0, 20, 10, 0, 0));
let date4 = new Date(Date.UTC(2010, 0, 20, 10, 0, 0));
let date5 = new Date(Date.UTC(2007, 0, 10, 12, 0, 0));
let date6 = new Date(Date.UTC(2007, 0, 10, 14, 0, 0));
let date7 = new Date(Date.UTC(2007, 0, 10, 23, 0, 0));
let date8 = new Date(Date.UTC(2007, 0, 11, 0, 0, 0));
if ($vm.icuVersion() >= 64) {
// Test three relavant extensions.
// "nu" NumberingSystem
let fmt1 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'America/Los_Angeles',
numberingSystem: 'hanidec',
});
shouldBe(fmt1.format(date1), `〇七/一/一〇 二:〇〇`);
shouldBe(fmt1.formatRange(date1, date2), `〇七/一/一〇 二時〇〇分~三時〇〇分`);
shouldBe(fmt1.formatRange(date1, date3), `〇七/一/一〇 二:〇〇~〇七/一/二〇 二:〇〇`);
// "ca" Calendar
let fmt2 = new Intl.DateTimeFormat("ja", {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'America/Los_Angeles',
calendar: 'chinese'
});
shouldBeOneOf(fmt2.format(date1), [ `丙戌-11-22 2:00`, `丙戌年1122 2:00` ]);
shouldBe(fmt2.formatRange(date1, date2), `丙戌年1122 200分~300分`);
shouldBe(fmt2.formatRange(date1, date3), `丙戌年1122 2:00~丙戌年122 2:00`);
let fmt3 = new Intl.DateTimeFormat("ja", {
year: 'numeric',
timeZone: 'America/Los_Angeles',
calendar: 'chinese'
});
shouldBe(fmt3.format(date1), `丙戌年`);
shouldBe(fmt3.formatRange(date1, date2), `丙戌年`);
shouldBe(fmt3.formatRange(date1, date3), `丙戌年`);
shouldBe(fmt3.formatRange(date1, date4), `丙戌年~己丑年`);
// Calendar-sensitive format
let fmt4 = new Intl.DateTimeFormat('ja-u-ca-buddhist', {
year: 'numeric',
timeZone: 'America/Los_Angeles',
});
shouldBe(fmt4.format(date1), `仏暦2550年`);
shouldBe(fmt4.formatRange(date1, date2), `仏暦2550年`);
shouldBe(fmt4.formatRange(date1, date3), `仏暦2550年`);
shouldBe(fmt4.formatRange(date1, date4), `仏暦2550年~2553年`);
// "hc" HourCycle
let fmt5 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h24',
});
shouldBe(fmt5.format(date1), `07/1/10 10:00`);
shouldBe(fmt5.format(date8), `07/1/11 24:00`);
shouldBeOneOf(fmt5.formatRange(date1, date2), [ `07/1/10 10:0011:00`, `07/1/10 1000分~1100分` ]);
shouldBe(fmt5.formatRange(date1, date3), `07/1/10 10:0007/1/20 10:00`);
shouldBeOneOf(fmt5.formatRange(date1, date5), [ `07/1/10 10:0012:00`, `07/1/10 1000分~1200分` ]);
shouldBeOneOf(fmt5.formatRange(date1, date6), [ `07/1/10 10:0014:00`, `07/1/10 1000分~1400分` ]);
shouldBeOneOf(fmt5.formatRange(date1, date7), [ `07/1/10 10:0023:00`, `07/1/10 1000分~2300分` ]);
if ($vm.icuVersion() > 66)
shouldBe(fmt5.formatRange(date1, date8), `07/1/10 10:0007/1/11 24:00`);
let fmt6 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h23',
});
shouldBe(fmt6.format(date1), `07/1/10 10:00`);
shouldBe(fmt6.format(date8), `07/1/11 0:00`);
shouldBe(fmt6.formatRange(date1, date2), `07/1/10 1000分~1100分`);
shouldBe(fmt6.formatRange(date1, date3), `07/1/10 10:0007/1/20 10:00`);
shouldBe(fmt6.formatRange(date1, date5), `07/1/10 1000分~1200分`);
shouldBe(fmt6.formatRange(date1, date6), `07/1/10 1000分~1400分`);
shouldBe(fmt6.formatRange(date1, date7), `07/1/10 1000分~2300分`);
shouldBe(fmt6.formatRange(date1, date8), `07/1/10 10:0007/1/11 0:00`);
let fmt7 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h11',
});
shouldBe(fmt7.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt7.format(date8), `07/1/11 午前0:00`);
shouldBeOneOf(fmt7.formatRange(date1, date2), [ `07/1/10 午前10:00~午前11:00`, `07/1/10 午前1000分~1100分` ]);
shouldBeOneOf(fmt7.formatRange(date1, date3), [ `07/1/10 午前10:0007/1/20 午前10:00`, `07/1/10 午前1000分~午後000分` ]);
shouldBeOneOf(fmt7.formatRange(date1, date5), [ `07/1/10 午前10:00~午後0:00`, `07/1/10 午前1000分~午後000分` ]);
shouldBeOneOf(fmt7.formatRange(date1, date6), [ `07/1/10 午前10:00~午後2:00`, `07/1/10 午前1000分~午後200分` ]);
shouldBeOneOf(fmt7.formatRange(date1, date7), [ `07/1/10 午前10:00~午後11:00`, `07/1/10 午前1000分~午後1100分` ]);
shouldBe(fmt7.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前0:00`);
let fmt8 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h12',
});
shouldBe(fmt8.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt8.format(date8), `07/1/11 午前12:00`);
shouldBe(fmt8.formatRange(date1, date2), `07/1/10 午前1000分~1100分`);
shouldBe(fmt8.formatRange(date1, date3), `07/1/10 午前10:0007/1/20 午前10:00`);
shouldBe(fmt8.formatRange(date1, date5), `07/1/10 午前1000分~午後000分`);
shouldBe(fmt8.formatRange(date1, date6), `07/1/10 午前1000分~午後200分`);
shouldBe(fmt8.formatRange(date1, date7), `07/1/10 午前1000分~午後1100分`);
if ($vm.icuVersion() > 66)
shouldBe(fmt8.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前12:00`);
// "hc" + hour 2-digit
let fmt9 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h24',
});
shouldBe(fmt9.format(date1), `07/1/10 10:00`);
shouldBe(fmt9.format(date8), `07/1/11 24:00`);
shouldBeOneOf(fmt9.formatRange(date1, date2), [ `07/1/10 10:0011:00`, `07/1/10 1000分~1100分` ]);
shouldBe(fmt9.formatRange(date1, date3), `07/1/10 10:0007/1/20 10:00`);
shouldBeOneOf(fmt9.formatRange(date1, date5), [ `07/1/10 10:0012:00`, `07/1/10 1000分~1200分` ]);
shouldBeOneOf(fmt9.formatRange(date1, date6), [ `07/1/10 10:0014:00`, `07/1/10 1000分~1400分` ]);
shouldBeOneOf(fmt9.formatRange(date1, date7), [ `07/1/10 10:0023:00`, `07/1/10 1000分~2300分` ]);
if ($vm.icuVersion() > 66)
shouldBe(fmt9.formatRange(date1, date8), `07/1/10 10:0007/1/11 24:00`);
let fmt10 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h23',
});
shouldBe(fmt10.format(date1), `07/1/10 10:00`);
shouldBe(fmt10.format(date8), `07/1/11 00:00`);
shouldBe(fmt10.formatRange(date1, date2), `07/1/10 1000分~1100分`);
shouldBe(fmt10.formatRange(date1, date3), `07/1/10 10:0007/1/20 10:00`);
shouldBe(fmt10.formatRange(date1, date5), `07/1/10 1000分~1200分`);
shouldBe(fmt10.formatRange(date1, date6), `07/1/10 1000分~1400分`);
shouldBe(fmt10.formatRange(date1, date7), `07/1/10 1000分~2300分`);
shouldBe(fmt10.formatRange(date1, date8), `07/1/10 10:0007/1/11 0:00`);
let fmt11 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h11',
});
shouldBe(fmt11.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt11.format(date8), `07/1/11 午前00:00`);
shouldBeOneOf(fmt11.formatRange(date1, date2), [ `07/1/10 午前10:00~午前11:00`, `07/1/10 午前1000分~1100分` ]);
shouldBe(fmt11.formatRange(date1, date3), `07/1/10 午前10:0007/1/20 午前10:00`);
shouldBeOneOf(fmt11.formatRange(date1, date5), [ `07/1/10 午前10:00~午後0:00`, `07/1/10 午前1000分~午後000分` ]);
shouldBeOneOf(fmt11.formatRange(date1, date6), [ `07/1/10 午前10:00~午後2:00`, `07/1/10 午前1000分~午後200分` ]);
shouldBeOneOf(fmt11.formatRange(date1, date7), [ `07/1/10 午前10:00~午後11:00`, `07/1/10 午前1000分~午後1100分` ]);
shouldBe(fmt11.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前0:00`);
let fmt12 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h12',
});
shouldBe(fmt12.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt12.format(date8), `07/1/11 午前12:00`);
shouldBe(fmt12.formatRange(date1, date2), `07/1/10 午前1000分~1100分`);
shouldBe(fmt12.formatRange(date1, date3), `07/1/10 午前10:0007/1/20 午前10:00`);
shouldBe(fmt12.formatRange(date1, date5), `07/1/10 午前1000分~午後000分`);
shouldBe(fmt12.formatRange(date1, date6), `07/1/10 午前1000分~午後200分`);
shouldBe(fmt12.formatRange(date1, date7), `07/1/10 午前1000分~午後1100分`);
if ($vm.icuVersion() > 66)
shouldBe(fmt12.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前12:00`);
// "hc" + hour12.
let fmt13 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h24',
hour12: true,
});
shouldBe(fmt13.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt13.format(date8), `07/1/11 午前00:00`);
shouldBeOneOf(fmt13.formatRange(date1, date2), [ `07/1/10 午前10:00~午前11:00`, `07/1/10 午前1000分~1100分` ]);
shouldBe(fmt13.formatRange(date1, date3), `07/1/10 午前10:0007/1/20 午前10:00`);
shouldBeOneOf(fmt13.formatRange(date1, date5), [ `07/1/10 午前10:00~午後0:00`, `07/1/10 午前1000分~午後000分` ]);
shouldBeOneOf(fmt13.formatRange(date1, date6), [ `07/1/10 午前10:00~午後2:00`, `07/1/10 午前1000分~午後200分` ]);
shouldBeOneOf(fmt13.formatRange(date1, date7), [ `07/1/10 午前10:00~午後11:00`, `07/1/10 午前1000分~午後1100分` ]);
shouldBe(fmt13.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前0:00`);
let fmt14 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h23',
hour12: true,
});
shouldBe(fmt14.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt14.format(date8), `07/1/11 午前00:00`);
shouldBeOneOf(fmt14.formatRange(date1, date2), [ `07/1/10 午前10:00~午前11:00`, `07/1/10 午前1000分~1100分` ]);
shouldBe(fmt14.formatRange(date1, date3), `07/1/10 午前10:0007/1/20 午前10:00`);
shouldBeOneOf(fmt14.formatRange(date1, date5), [ `07/1/10 午前10:00~午後0:00`, `07/1/10 午前1000分~午後000分` ]);
shouldBeOneOf(fmt14.formatRange(date1, date6), [ `07/1/10 午前10:00~午後2:00`, `07/1/10 午前1000分~午後200分` ]);
shouldBeOneOf(fmt14.formatRange(date1, date7), [ `07/1/10 午前10:00~午後11:00`, `07/1/10 午前1000分~午後1100分` ]);
shouldBe(fmt14.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前0:00`);
let fmt15 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h11',
hour12: true,
});
shouldBe(fmt15.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt15.format(date8), `07/1/11 午前00:00`);
shouldBeOneOf(fmt15.formatRange(date1, date2), [ `07/1/10 午前10:00~午前11:00`, `07/1/10 午前1000分~1100分` ]);
shouldBe(fmt15.formatRange(date1, date3), `07/1/10 午前10:0007/1/20 午前10:00`);
shouldBeOneOf(fmt15.formatRange(date1, date5), [ `07/1/10 午前10:00~午後0:00`, `07/1/10 午前1000分~午後000分` ]);
shouldBeOneOf(fmt15.formatRange(date1, date6), [ `07/1/10 午前10:00~午後2:00`, `07/1/10 午前1000分~午後200分` ]);
shouldBeOneOf(fmt15.formatRange(date1, date7), [ `07/1/10 午前10:00~午後11:00`, `07/1/10 午前1000分~午後1100分` ]);
shouldBe(fmt15.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前0:00`);
let fmt16 = new Intl.DateTimeFormat("ja", {
year: '2-digit',
month: 'numeric',
day: 'numeric',
hour: '2-digit',
minute: 'numeric',
timeZone: 'UTC',
hourCycle: 'h12',
hour12: true,
});
shouldBe(fmt16.format(date1), `07/1/10 午前10:00`);
shouldBe(fmt16.format(date8), `07/1/11 午前00:00`);
shouldBeOneOf(fmt16.formatRange(date1, date2), [ `07/1/10 午前10:00~午前11:00`, `07/1/10 午前1000分~1100分` ]);
shouldBe(fmt16.formatRange(date1, date3), `07/1/10 午前10:0007/1/20 午前10:00`);
shouldBeOneOf(fmt16.formatRange(date1, date5), [ `07/1/10 午前10:00~午後0:00`, `07/1/10 午前1000分~午後000分` ]);
shouldBeOneOf(fmt16.formatRange(date1, date6), [ `07/1/10 午前10:00~午後2:00`, `07/1/10 午前1000分~午後200分` ]);
shouldBeOneOf(fmt16.formatRange(date1, date7), [ `07/1/10 午前10:00~午後11:00`, `07/1/10 午前1000分~午後1100分` ]);
shouldBe(fmt16.formatRange(date1, date8), `07/1/10 午前10:0007/1/11 午前0:00`);
}