Cómo calcular los días entre fechas en PHP: 5 errores fatales

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

«¿Cuántos días han pasado?» — la pregunta que desconcierta a los principiantes

\n\n

Cada desarrollador PHP, tarde o temprano, se enfrenta a la tarea: necesita saber cuántos días han pasado entre dos fechas. Parecería, ¿qué podría ser más simple? Tomamos dos cadenas, restamos una de la otra — y listo. Pero es precisamente aquí, de la nada, donde se cometen los errores más engañosos.

\n\n

Hemos mirado en Stack Overflow y encontramos una pregunta real «Finding the number of days between two dates», que acumuló miles de visitas. Resulta que incluso programadores experimentados caen en trampas relacionadas con las zonas horarias, las marcas unix y el comportamiento inesperado de strtotime().

\n\n

En este artículo, analizaremos los cinco errores más comunes al calcular el número de días entre fechas en PHP y mostraremos cómo evitarlos. Preparen su editor — habrá mucho código y consejos prácticos.

\n\n

Error n.º 1: Restar marcas unix «a lo bruto»

\n\n

El error más popular es intentar obtener la diferencia entre fechas restando timestamps directamente:

\n\n
<?php\n$date1 = strtotime('2024-01-01');\n$date2 = strtotime('2024-01-10');\n$days = ($date2 - $date1) / (60 * 60 * 24);\necho $days; // 9\n?>
\n\n

En apariencia, funciona. Pero prueben a cambiar la hora al horario de verano. Al pasar al «horario de verano», el día se acorta una hora, y al regresar, se alarga. Resultado: 9.04166 o 8.95833 días en lugar de exactamente 9.

\n\n

Cómo corregirlo

\n

Usen objetos DateTime y el método diff(). Ellos tienen en cuenta todos los saltos de tiempo:

\n\n
<?php\n$date1 = new DateTime('2024-01-01');\n$date2 = new DateTime('2024-01-10');\n$interval = $date1->diff($date2);\necho $interval->days; // 9 — siempre correcto\n?>
\n\n

Trabajar con la diferencia de fechas PHP mediante DateTime::diff es el estándar de la industria. Recuerden este patrón.

\n\n

Error n.º 2: Ignorar la zona horaria

\n\n

Imaginen: su servidor está en Europa/Moscú, y un usuario de Nueva York ingresa la fecha «2024-03-10». Ustedes crean un DateTime sin especificar la zona horaria. PHP usa la zona horaria del sistema del servidor. Resultado: la diferencia en días puede «desviarse» en uno.

\n\n

Esto es especialmente crítico en los límites de los meses y los cambios al horario de verano. El error se manifiesta raramente, pero cuando aparece en producción, es muy difícil de detectar.

\n\n

Solución: especifiquen explícitamente la zona horaria

\n
<?php\n$tz = new DateTimeZone('UTC');\n$date1 = new DateTime('2024-03-10', $tz);\n$date2 = new DateTime('2024-03-20', $tz);\n$interval = $date1->diff($date2);\necho $interval->days; // 10 — honesto\n?>
\n\n

Usen siempre UTC para los cálculos internos. Si necesitan mostrar la fecha al usuario, conviértanla a su zona horaria local solo en la etapa de salida.

\n\n

Error n.º 3: Confundir days con format('%a')

\n\n

El objeto DateInterval tiene una propiedad days y un método format('%a'). Parece que son lo mismo. Pero hay un matiz:

\n\n
    \n
  • $interval->days — el número total de días (considera todos los meses y años). El valor siempre es correcto.
  • \n
  • $interval->format('%a') — lo mismo, pero como cadena.
  • \n
  • $interval->d — solo los días sin tener en cuenta los meses. Si la diferencia es de 35 días, entonces d devolverá 4 (el resto después de restar un mes).
  • \n
\n\n

Los principiantes a menudo confunden d y days. Como resultado, obtienen 4 días en lugar de 35. De ahí, bugs en informes, facturación y planificadores de tareas.

\n\n

Siempre verifiquen qué propiedad están usando

\n
<?php\n$date1 = new DateTime('2024-01-01');\n$date2 = new DateTime('2024-02-05');\n$interval = $date1->diff($date2);\n\necho $interval->days; // 35\necho $interval->d;    // 4 — ¡NO ES LO MISMO!\n?>
\n\n

Si necesitan exactamente el número de días entre dos fechas — tomen

Blogs

Book Recommendations