date_modify()
Guía completa sobre la función date_modify de PHP: cómo modificar fechas con cadenas de formato relativo y evitar errores comunes.
Esta guía cubre el método DateTime::modify() de PHP (la contraparte orientada a objetos de la función procedimental date_modify()). Explica cómo modify() analiza cadenas de fecha relativas, qué devuelve, el problema del desbordamiento de mes que confunde a la mayoría de los desarrolladores y cómo evitar mutar una fecha por accidente.
¿Qué es DateTime::modify()?
modify() es un método integrado de la clase DateTime que altera la fecha/hora que contiene usando una cadena de formato relativo como +10 days, -3 months o next monday. Úsalo cuando necesites aritmética de fechas — adelantar un plazo, retroceder un timestamp o saltar al siguiente día laborable — sin calcular manualmente los segundos.
Dos características hacen que modify() sea distintivo y vale la pena tenerlas en mente antes de leer los ejemplos:
- Muta el objeto en su lugar — modifica el mismo
DateTimesobre el que se llama en lugar de devolver una copia nueva. - Acepta la misma gramática de formato relativo que PHP usa al construir fechas a partir de cadenas, por lo que todo lo que
new DateTime('+1 week')entiende,modify()también lo entiende.
Sintaxis
public DateTime::modify(string $modifier): DateTime|false$modifier— una cadena de formato relativo (p. ej.,+1 day,-2 weeks,first day of next month,14:00).- Devuelve el mismo objeto
DateTimeen caso de éxito (para que las llamadas puedan encadenarse), ofalseen caso de fallo (por ejemplo, una cadena que no se puede analizar).
Dado que devuelve el propio objeto, estas dos líneas son equivalentes — el $date original se modifica en ambos casos:
$date->modify('+1 day'); // mutates $date, return value ignored
$date = $date->modify('+1 day'); // mutates $date AND reassigns the same objectConsejo: Cuando $modifier proviene de la entrada del usuario, comprueba siempre si es false antes de usar el resultado, ya que una cadena mal formada devuelve false en lugar de lanzar una excepción.
Ejemplos
Ejemplo 1: Añadir días a una fecha
Para añadir 10 días a una fecha fija con manejo básico de errores:
Añadir días a una fecha en PHP
Salida:
2023-03-11Ejemplo 2: Restar meses a una fecha
Para restar 3 meses a una fecha fija:
Restar meses a una fecha en PHP
Salida:
2022-12-01Ejemplo 3: Establecer la hora a un valor específico
Para establecer la hora a las 2 PM en una fecha fija:
Establecer la hora a un valor específico en PHP
Salida:
2023-03-01 14:00:00Ten en cuenta que modify('14:00') establece la parte de la hora a las 2 PM pero no modifica la fecha — los formatos relativos que solo mencionan una hora actúan sobre la hora, no sobre el día.
Ejemplo 4: Combinar varias unidades en una sola llamada
Puedes agrupar múltiples unidades relativas en una sola cadena de modificación, separadas por espacios. Se aplican de izquierda a derecha:
<?php
$date = new DateTime('2023-03-01');
$date->modify('+1 week +2 days');
echo $date->format('Y-m-d');Salida:
2023-03-10El problema del desbordamiento de mes
Añadir o restar meses no se ajusta al final de un mes más corto — desborda al siguiente. Observa qué ocurre cuando añades un mes al 31 de enero:
<?php
$date = new DateTime('2023-01-31');
$date->modify('+1 month');
echo $date->format('Y-m-d');Salida:
2023-03-03Como febrero de 2023 solo tiene 28 días, "31 de enero + 1 mes" cae en el inexistente "31 de febrero", que PHP convierte en el 3 de marzo. Si necesitas el último día del mes siguiente, usa un formato relativo absoluto:
<?php
$date = new DateTime('2023-01-31');
$date->modify('last day of next month');
echo $date->format('Y-m-d');Salida:
2023-02-28Evitar mutaciones accidentales con DateTimeImmutable
Dado que modify() cambia el objeto en su lugar, compartir un solo DateTime en todo el código puede provocar errores difíciles de encontrar — modificarlo en un lugar afecta a todas las referencias al mismo. Si quieres que cada operación devuelva un valor nuevo y deje el original intacto, usa DateTimeImmutable, cuyo método modify() devuelve un nuevo objeto:
<?php
$original = new DateTimeImmutable('2023-03-01');
$nextWeek = $original->modify('+7 days');
echo $original->format('Y-m-d') . "\n"; // unchanged
echo $nextWeek->format('Y-m-d');Salida:
2023-03-01
2023-03-08Formatos relativos útiles
modify() acepta una rica gramática de expresiones relativas. Algunas de las más comunes:
| Modificador | Significado |
|---|---|
+5 days, -2 weeks | Añadir o restar un número de unidades |
+1 year +6 months | Combinar unidades en una sola cadena |
next monday, last friday | Saltar a un día de la semana con nombre |
first day of this month | Moverse al día 1 del mes |
last day of next month | Moverse al último día del mes siguiente |
tomorrow, yesterday | Desplazarse un día (y restablecer la hora a medianoche) |
14:30, midnight | Establecer solo la parte de la hora |
Funciones relacionadas
date_add()— añadir unDateIntervala una fecha.date_sub()— restar unDateIntervalde una fecha.date_diff()— obtener la diferencia entre dos fechas.date_format()— formatear un objetoDateTimecomo cadena.
Resumen
DateTime::modify() aplica una cadena de formato relativo a una fecha, mutando el objeto en su lugar y devolviéndolo (o false en caso de fallo). Es ideal para la aritmética de fechas y para saltar a días con nombre, pero recuerda dos cosas: las operaciones con meses desbordan los meses más cortos, y la mutación es compartida — usa DateTimeImmutable cuando necesites preservar el original.