Una vida en unas líneas
22 DEC 1984 · BORN
El 22 de diciembre de 1984 es mi fecha de nacimiento. Desde ahí se cuentan los días vividos.
30 JUL 2022 · DUBAI
El 30 de julio de 2022 comenzó mi vida en Dubái. Esta etapa tiene su propio contador.
NOW
La fecha de hoy según la hora de Dubái, UTC+4. Cambia con el calendario.
LIFE · DAY
El número de días naturales completos desde el nacimiento. El día de nacimiento es el punto de partida, el día cero.
DUBAI · DAY
El número de días transcurridos desde la mudanza a Dubái.
OF LIFE · DUBAI
Los días en Dubái divididos entre todos los días vividos. Así la mudanza se hace visible a escala de toda una vida.
El código detrás de estas cifras
Esta función cuenta los días vividos, los días en Dubái y su proporción de la vida. También alimenta el contador de arriba. Copia este ejemplo funcional en tu página y sustituye las dos fechas por las tuyas. Los días de calendario siguen la hora de Dubái.
<output id="life-counter" aria-label="Código del contador"></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
En Instagram, Dubái más allá de la postal: familia, ciudad, descubrimientos y la vida entre proyectos. En Threads, ideas en voz alta sobre diseño e IA. En YouTube, vídeos que necesitan más espacio que una historia. Sígueme donde te sientas más a gusto y seguimos en contacto