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