|
245 | 245 | // ── Countdown logic ─────────────────────────────────────────────────── |
246 | 246 | var countDownDate = new Date("Sep 1, 2026 00:00:00").getTime(); |
247 | 247 |
|
248 | | - var formatter = new Intl.RelativeTimeFormat(locale, { style: "narrow" }); |
249 | | - |
250 | | - var pfx = new Array(4); |
251 | | - var sfx = new Array(4); |
252 | | - |
253 | | - function getOffset(unit) { |
254 | | - switch (unit) { |
255 | | - case "day": return 0; |
256 | | - case "hour": return 1; |
257 | | - case "minute": return 2; |
258 | | - case "second": return 3; |
259 | | - } |
260 | | - } |
261 | | - |
262 | | - function extractCommon(p, c, reverse) { |
263 | | - var s = 0; |
264 | | - var w = 0; |
265 | | - var i = reverse ? p.length - 1 : 0; |
266 | | - var j = reverse ? c.length - 1 : 0; |
267 | | - var pEnd = reverse ? 0 : p.length; |
268 | | - var cEnd = reverse ? 0 : c.length; |
269 | | - var chr; |
270 | | - while ( |
271 | | - (reverse ? i >= pEnd : i < pEnd) && |
272 | | - (reverse ? j >= cEnd : j < cEnd) && |
273 | | - (chr = p[reverse ? i-- : i++]) === c[reverse ? j-- : j++] |
274 | | - ) { |
275 | | - w = chr === " " ? w + 1 : 0; |
276 | | - s++; |
277 | | - } |
278 | | - return s - w; |
279 | | - } |
280 | | - |
281 | | - function cacheFormattingInfo(value, unit) { |
282 | | - var p = formatter.formatToParts(value, unit); |
283 | | - if (!p.length) return; |
284 | | - var c = formatter.formatToParts(-value, unit); |
285 | | - |
286 | | - var offset = getOffset(unit); |
287 | | - if (p[0].type === "literal" && (!c.length || c[0].type !== "literal" || !c[0].value.endsWith(p[0].value))) { |
288 | | - pfx[offset] = p[0].value.length; |
289 | | - } |
290 | | - if (p[p.length - 1].type === "literal") { |
291 | | - if (!c.length || c[c.length - 1].type !== "literal") { |
292 | | - sfx[offset] = p[p.length - 1].value.length; |
293 | | - } else if (!c[c.length - 1].value.startsWith(p[p.length - 1].value)) { |
294 | | - sfx[offset] = |
295 | | - p[p.length - 1].value.length - |
296 | | - extractCommon(p[p.length - 1].value, c[c.length - 1].value, false); |
297 | | - } |
298 | | - } |
299 | | - } |
300 | | - |
301 | | - cacheFormattingInfo(1, "day"); |
302 | | - cacheFormattingInfo(2, "hour"); |
303 | | - cacheFormattingInfo(3, "minute"); |
304 | | - cacheFormattingInfo(4, "second"); |
| 248 | + var unitFormatters = { |
| 249 | + day: new Intl.NumberFormat(locale, { style: "unit", unit: "day", unitDisplay: "narrow" }), |
| 250 | + hour: new Intl.NumberFormat(locale, { style: "unit", unit: "hour", unitDisplay: "narrow" }), |
| 251 | + minute: new Intl.NumberFormat(locale, { style: "unit", unit: "minute", unitDisplay: "narrow" }), |
| 252 | + second: new Intl.NumberFormat(locale, { style: "unit", unit: "second", unitDisplay: "narrow" }) |
| 253 | + }; |
305 | 254 |
|
306 | | - function getLocalizedUnit(value, unit, trimConjunction, trimSuffix) { |
307 | | - var offset = getOffset(unit); |
308 | | - var string = formatter.format(value, unit); |
309 | | - var p = pfx[offset]; |
310 | | - var s = sfx[offset]; |
311 | | - return string.slice( |
312 | | - trimConjunction && p || (p == 1 && string[0] === "+") ? pfx[offset] : 0, |
313 | | - trimSuffix && s ? -sfx[offset] : string.length |
314 | | - ); |
| 255 | + function formatUnit(value, unit) { |
| 256 | + return unitFormatters[unit].format(value); |
315 | 257 | } |
316 | 258 |
|
317 | 259 | var remaining = new Array(7); |
|
330 | 272 | var seconds = Math.floor((distance % (1000 * 60)) / 1000); |
331 | 273 |
|
332 | 274 | var parts = 0; |
333 | | - remaining[0] = days > 0 ? getLocalizedUnit(days, "day", parts++, true) : null; |
| 275 | + remaining[0] = days > 0 ? formatUnit(days, "day") : null; |
| 276 | + if (remaining[0]) parts++; |
334 | 277 | remaining[1] = parts ? separator : null; |
335 | 278 | remaining[2] = |
336 | 279 | parts || hours > 0 |
337 | | - ? getLocalizedUnit(hours, "hour", parts++, true) |
| 280 | + ? formatUnit(hours, "hour") |
338 | 281 | : null; |
| 282 | + if (remaining[2]) parts++; |
339 | 283 | remaining[3] = parts ? separator : null; |
340 | 284 | remaining[4] = |
341 | 285 | parts || minutes > 0 |
342 | | - ? getLocalizedUnit(minutes, "minute", parts++, true) |
| 286 | + ? formatUnit(minutes, "minute") |
343 | 287 | : null; |
| 288 | + if (remaining[4]) parts++; |
344 | 289 | remaining[5] = parts ? separator : null; |
345 | | - remaining[6] = getLocalizedUnit(seconds, "second", parts++, false); |
| 290 | + remaining[6] = formatUnit(seconds, "second"); |
346 | 291 |
|
347 | 292 | countdownSpan.textContent = remaining.join(""); |
348 | 293 |
|
|
0 commit comments