DateInterval representa una duración (un período de tiempo como «3 meses y 5 días»), mientras que DatePeriod permite iterar sobre un rango de fechas con un intervalo fijo. Combinados con DateTimeImmutable, cubren prácticamente cualquier necesidad de cálculo de fechas en PHP.
DateInterval: crear duraciones
La especificación de un DateInterval sigue el formato ISO 8601: P (de period) seguido de los componentes de fecha y luego T seguido de los componentes de tiempo:
<?php
$tresAnios = new DateInterval('P3Y'); // 3 años
$unMes = new DateInterval('P1M'); // 1 mes
$diezDias = new DateInterval('P10D'); // 10 días
$dosHoras = new DateInterval('PT2H'); // 2 horas (T antes de componentes de tiempo)
$completo = new DateInterval('P1Y2M3DT4H5M6S'); // 1a 2m 3d 4h 5min 6s
// Acceder a los componentes
echo $completo->y; // 1 (años)
echo $completo->m; // 2 (meses)
echo $completo->d; // 3 (días)
echo $completo->h; // 4 (horas)
echo $completo->i; // 5 (minutos)
echo $completo->s; // 6 (segundos)
?>
diff(): calcular la diferencia entre dos fechas
El método diff() de DateTimeImmutable devuelve un DateInterval con la diferencia entre dos fechas:
<?php
$inicio = new DateTimeImmutable('2026-01-01');
$fin = new DateTimeImmutable('2026-07-22');
$diff = $inicio->diff($fin);
echo $diff->y . ' años, '; // 0 años
echo $diff->m . ' meses, '; // 6 meses
echo $diff->d . ' días'; // 21 días
echo "n";
echo $diff->days . ' días totales'; // 202 días totales (propiedad especial)
?>
La propiedad $diff->days devuelve el total de días entre las dos fechas, independientemente de años y meses. Es la forma más fiable de calcular una diferencia en días.
Calcular la edad de un usuario
<?php
function calcularEdad(string $nacimiento): int
{
$fechaNac = new DateTimeImmutable($nacimiento);
$hoy = new DateTimeImmutable('today');
return $fechaNac->diff($hoy)->y; // propiedad y = años completos
}
echo calcularEdad('1990-07-22') . ' años'; // 35 años (en 2026)
echo calcularEdad('1990-07-25') . ' años'; // 35 años (cumple en 3 días, aún no)
?>
Tiempo relativo en interfaces de usuario
<?php
function tiempoRelativo(DateTimeImmutable $fecha): string
{
$ahora = new DateTimeImmutable();
$diff = $fecha->diff($ahora);
if ($diff->days === 0) {
if ($diff->h === 0) {
return $diff->i . ' minutos';
}
return $diff->h . ' horas';
}
if ($diff->days < 7) {
return $diff->days . ' días';
}
if ($diff->days < 30) {
return (int) ($diff->days / 7) . ' semanas';
}
if ($diff->m < 12) {
return $diff->m . ' meses';
}
return $diff->y . ' años';
}
$publicado = new DateTimeImmutable('-3 hours');
echo 'Hace ' . tiempoRelativo($publicado); // Hace 3 horas
?>
DatePeriod: rangos de fechas para calendarios
DatePeriod genera una secuencia de fechas iterables entre un inicio y un fin (o un número de recurrencias) separadas por un intervalo:
<?php
// Todos los días de julio de 2026
$inicio = new DateTimeImmutable('2026-07-01');
$fin = new DateTimeImmutable('2026-08-01');
$intervalo = new DateInterval('P1D'); // 1 día
$periodo = new DatePeriod($inicio, $intervalo, $fin);
foreach ($periodo as $dia) {
echo $dia->format('d/m/Y') . "n";
}
// 01/07/2026, 02/07/2026, ... 31/07/2026
?>
Generación de slots de agenda
<?php
// Slots de 30 minutos entre las 9:00 y las 14:00
$apertura = new DateTimeImmutable('2026-07-22 09:00:00');
$cierre = new DateTimeImmutable('2026-07-22 14:00:00');
$slot = new DateInterval('PT30M'); // 30 minutos
$agenda = new DatePeriod($apertura, $slot, $cierre);
foreach ($agenda as $hora) {
echo $hora->format('H:i') . "n";
}
// 09:00, 09:30, 10:00, 10:30, 11:00, 11:30, 12:00, 12:30, 13:00, 13:30
?>
Errores frecuentes
- Confundir
$diff->mcon el total de meses:$diff->mson los meses restantes tras calcular los años. Para el total de meses, usa$diff->y * 12 + $diff->m. - DatePeriod no incluye la fecha de fin: si quieres incluirla, usa
DatePeriod::INCLUDE_END_DATE(disponible desde PHP 8.2) o añade un día extra al límite. - Zona horaria en diff(): si las dos fechas tienen zonas horarias distintas,
diff()convierte internamente a UTC antes de calcular, lo que puede dar resultados inesperados en fechas con cambio de horario.
La documentación de DateInterval y la de DatePeriod detallan todos los constructores y opciones disponibles.
