Жизнь в нескольких строках
22 DEC 1984 · BORN
22 декабря 1984 года — дата моего рождения. От неё считается число прожитых дней.
30 JUL 2022 · DUBAI
30 июля 2022 года — начало моей жизни в Дубае. У этой части жизни свой счётчик.
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 — видео, которым тесно в сторис. Подписывайтесь там, где вам удобнее: будем на связи