year-month.js (3608B)
1 // |reftest| skip-if(!this.hasOwnProperty("Temporal")||!this.hasOwnProperty("Intl")) 2 3 // Test formatting for Temporal.YearMonth. 4 5 const locales = [ 6 "en", 7 "de", 8 "fr", 9 "es", 10 "ar", 11 "th", 12 "zh", 13 "ja", 14 ]; 15 16 const options = [ 17 { 18 year: "numeric", 19 month: "numeric", 20 }, 21 { 22 month: "long", 23 }, 24 25 { 26 era: "long", 27 year: "numeric", 28 }, 29 { 30 era: "short", 31 year: "2-digit", 32 month: "narrow", 33 }, 34 ]; 35 36 const dateStyles = [ 37 "full", "long", "medium", "short" 38 ]; 39 40 // The current implementation computes the skeleton from the resolved pattern, 41 // which doesn't always produce the correct results. It'd be better to compute 42 // the skeleton from ICU's "DateTimeSkeletons" resource table. This requires 43 // writing manual resource lookup code, though. And "DateTimeSkeletons" doesn't 44 // (yet) contain the correct skeletons in all cases. For more info see these 45 // ICU and CLDR bugs: 46 // - https://unicode-org.atlassian.net/browse/ICU-22867 47 // - https://unicode-org.atlassian.net/browse/CLDR-14993 48 // - https://unicode-org.atlassian.net/browse/CLDR-18136 49 50 const dateStyleToOptions = { 51 full: { 52 year: "numeric", 53 month: "long", 54 }, 55 long: { 56 year: "numeric", 57 month: "long", 58 }, 59 medium: { 60 year: "numeric", 61 month: "short", 62 }, 63 short: { 64 year: "2-digit", 65 month: "numeric", 66 }, 67 overrides: { 68 de: { 69 medium: { 70 year: "numeric", 71 month: "2-digit", 72 }, 73 short: { 74 year: "2-digit", 75 month: "2-digit", 76 }, 77 }, 78 fr: { 79 short: { 80 year: "numeric", 81 month: "2-digit", 82 }, 83 }, 84 ar: { 85 medium: { 86 year: "numeric", 87 month: "2-digit", 88 }, 89 short: { 90 year: "numeric", 91 month: "numeric", 92 }, 93 }, 94 th: { 95 full: { 96 era: "short", 97 year: "numeric", 98 month: "long", 99 }, 100 }, 101 zh: { 102 full: { 103 year: "numeric", 104 month: "numeric", 105 }, 106 long: { 107 year: "numeric", 108 month: "numeric", 109 }, 110 medium: { 111 year: "numeric", 112 month: "numeric", 113 }, 114 short: { 115 year: "numeric", 116 month: "numeric", 117 }, 118 }, 119 ja: { 120 full: { 121 year: "numeric", 122 month: "numeric", 123 }, 124 long: { 125 year: "numeric", 126 month: "numeric", 127 }, 128 medium: { 129 year: "numeric", 130 month: "2-digit", 131 }, 132 short: { 133 year: "numeric", 134 month: "2-digit", 135 }, 136 }, 137 }, 138 }; 139 140 const timeZone = "UTC"; 141 142 let date = new Date(0); 143 let instant = date.toTemporalInstant(); 144 let zonedDateTime = instant.toZonedDateTimeISO(timeZone); 145 let plainDate = zonedDateTime.toPlainDate(); 146 147 for (let locale of locales) { 148 // Get the default calendar for |locale|. 149 let calendar = new Intl.DateTimeFormat(locale).resolvedOptions().calendar; 150 151 // Calendar must match for YearMonth. 152 // 153 // https://github.com/js-temporal/proposal-temporal-v2/issues/29 154 let plainYearMonth = plainDate.withCalendar(calendar).toPlainYearMonth(); 155 156 for (let opts of options) { 157 assertEq( 158 plainYearMonth.toLocaleString(locale, {timeZone, ...opts}), 159 date.toLocaleDateString(locale, {timeZone, ...opts}) 160 ); 161 } 162 163 for (let dateStyle of dateStyles) { 164 let opts = dateStyleToOptions.overrides[locale]?.[dateStyle] ?? dateStyleToOptions[dateStyle]; 165 assertEq( 166 plainYearMonth.toLocaleString(locale, {timeZone, dateStyle}), 167 date.toLocaleDateString(locale, {timeZone, ...opts}) 168 ); 169 } 170 } 171 172 if (typeof reportCompare === "function") 173 reportCompare(true, true);