Formateo de tiempos relativos

Mostrar '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 la gramática para 'hace 2 días' frente a 'dentro de 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 una salida gramaticalmente correcta.

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 'hace 2 días', '2 days ago' 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" allows "yesterday" or "tomorrow"
      style="long"
    />
  );
}

2. Pasar opciones de formateo

El componente FormattedRelativeTime acepta varias props 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 ("dentro de 2 días").
  • unit: La unidad de tiempo, como 'day', 'hour', 'minute' o 'second'.
  • numeric="auto": Esto permite que la biblioteca utilice palabras como "ayer" o "mañana" en lugar de "hace 1 día" o "dentro de 1 día".

3. Usar el componente en una página

Ahora puedes utilizar 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() {
  // You would calculate these values dynamically
  const daysSinceUpdate = -2;
  const hoursUntilEvent = 3;

  return (
    <div>
      <h1>Updates</h1>
      <p>
        File updated: <RelativeTime value={daysSinceUpdate} unit="day" />
      </p>
      <p>
        Event starts: <RelativeTime value={hoursUntilEvent} unit="hour" />
      </p>
    </div>
  );
}

Un usuario que visite /en verá "Archivo actualizado: hace 2 días" y "El evento comienza: dentro de 3 horas". Un usuario que visite /es verá "Archivo actualizado: hace 2 días" y "El evento comienza: dentro de 3 horas".