几行文字里的生活
22 DEC 1984 · BORN
1984年12月22日是我的出生日期。人生天数从这一天开始计算。
30 JUL 2022 · DUBAI
2022年7月30日标志着我在迪拜生活的开始。这段生活有自己的计数器。
NOW
按迪拜时间(UTC+4)显示的今天日期,随日历更新。
LIFE · DAY
出生后经过的完整日历天数。出生当天是起点,即第零天。
DUBAI · DAY
搬到迪拜以来经过的天数。
OF LIFE · DUBAI
在迪拜生活的天数除以全部已度过的天数,让这次搬迁在整个人生的尺度上清晰可见。
这些数字背后的代码
这个函数计算已度过的天数、在迪拜的天数及其占人生的比例。上方计数器也使用同一个函数。你可以复制这个可运行示例到自己的页面,并替换其中的两个日期。日历日期按迪拜时区确定。
<output id="life-counter" aria-label="计数器代码"></output>
<script>
const lifeCounters = function lifeCounters(now, residency, birth, locale, units) {
const parts = Object.fromEntries(new Intl.DateTimeFormat("en-CA", {
timeZone: "Asia/Dubai",
year: "numeric",
month: "2-digit",
day: "2-digit"
}).formatToParts(now).map((p) => [p.type, p.value]));
const day = Date.UTC(+parts.year, +parts.month - 1, +parts.day);
const count = (date) => {
if (!/^\d{4}-\d{2}-\d{2}$/.test(date || "")) throw new Error("Invalid counter date");
return Math.floor((day - Date.parse(date + "T00:00:00Z")) / 864e5);
};
const dubai = count(residency), life = count(birth);
if (!Number.isFinite(dubai) || !Number.isFinite(life) || dubai < 0 || life <= 0) throw new Error("Invalid counter range");
const unit = (n) => units[new Intl.PluralRules(locale).select(n)] || units.other;
const d = Object.fromEntries(new Intl.DateTimeFormat(locale, {
timeZone: "Asia/Dubai",
year: "numeric",
month: "long",
day: "numeric"
}).formatToParts(now).map((p) => [p.type, p.value]));
return {
"data-current-date": ["ru", "en"].includes(locale.split("-")[0]) ? `${d.day} ${d.month} ${d.year}` : new Intl.DateTimeFormat(locale, {
timeZone: "Asia/Dubai",
dateStyle: "long"
}).format(now),
"data-dubai-day-counter": dubai.toLocaleString(locale),
"data-life-day-counter": life.toLocaleString(locale),
"data-dubai-day-unit": unit(dubai),
"data-life-day-unit": unit(life),
"data-dubai-life-share": (dubai / life * 100).toLocaleString(locale, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}) + "%"
};
};
function updateCounter() {
const counters = lifeCounters(
new Date(), '2022-07-30', '1984-12-22', 'en-US', {other: 'days'}
);
document.getElementById('life-counter').textContent = [
'LIFE · DAY ' + counters['data-life-day-counter'],
'DUBAI · DAY ' + counters['data-dubai-day-counter'],
counters['data-dubai-life-share'] + ' OF LIFE · DUBAI'
].join(' / ');
}
updateCounter();
setInterval(updateCounter, 30000);
</script>
@nevsky_alexander
在 Instagram,看明信片之外的迪拜:家人、城市、新发现,还有项目之间的日常。在 Threads,聊聊设计与 AI 的随想;在 YouTube,分享一条限时动态装不下的视频。选你习惯的平台关注,常来聊聊