Formateo de tiempos relativos

Mostrando 'hace 2 días' en lugar de una marca de tiempo

Problema

Una aplicación muestra una marca de tiempo como 'Publicado hace 2 días'. Aunque esto es claro en inglés, la lógica y gramática para 'hace 2 días' versus 'en 2 días' (pasado vs. futuro) difieren significativamente entre idiomas. Una simple concatenación de cadenas (por ejemplo, '2' + ' ' + 'días atrás') no produce un resultado gramaticalmente correcto.

Solución

Utiliza un componente dedicado como FormattedRelativeTime de react-intl. Este componente toma un valor numérico (por ejemplo, -2) y una unidad (por ejemplo, 'day'), y automáticamente lo formatea en una cadena gramaticalmente correcta y adaptada al idioma, como '2 days ago', 'hace 2 días', o 'gestern' (ayer).

Pasos

1. Crear un componente cliente para tiempo relativo

El componente FormattedRelativeTime debe utilizarse dentro de un componente cliente.

Crea un nuevo archivo app/components/RelativeTime.tsx.

// app/components/RelativeTime.tsx
'use client';

import { FormattedRelativeTime } from 'react-intl';

type Props = {
  value: number;
  unit: Intl.RelativeTimeFormatUnit;
};

export default function RelativeTime({ value, unit }: Props) {
  return (
    <FormattedRelativeTime
      value={value}
      unit={unit}
      numeric="auto" // "auto" permite "yesterday" o "tomorrow"
      style="long"
    />
  );
}

2. Pasar opciones de formato

El componente FormattedRelativeTime acepta varias propiedades clave:

  • value: El número de unidades. Un valor negativo (por ejemplo, -2) indica el pasado ("hace 2 días"), y un valor positivo (2) indica el futuro ("en 2 días").
  • unit: La unidad de tiempo, como 'day', 'hour', 'minute', o 'second'.
  • numeric="auto": Esto permite que la biblioteca use palabras como "ayer" o "mañana" en lugar de "hace 1 día" o "en 1 día".

3. Usar el componente en una página

Ahora puedes usar este componente en cualquier página. Eres responsable de calcular la diferencia de tiempo antes de pasar las props.

// app/[lang]/page.tsx
import RelativeTime from '@/app/components/RelativeTime';

export default function Home() {
  // Calcularías estos valores dinámicamente
  const daysSinceUpdate = -2;
  const hoursUntilEvent = 3;

  return (
    <div>
      <h1>Actualizaciones</h1>
      <p>
        Archivo actualizado: <RelativeTime value={daysSinceUpdate} unit="day" />
      </p>
      <p>
        El evento comienza: <RelativeTime value={hoursUntilEvent} unit="hour" />
      </p>
    </div>
  );
}

Un usuario que visite /en verá "File updated: 2 days ago" y "Event starts: in 3 hours". Un usuario que visite /es verá "Archivo actualizado: hace 2 días" y "El evento comienza: dentro de 3 horas".