«¿Cuántos días han pasado?» — la pregunta que desconcierta a los principiantes
\n\nCada 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\nHemos 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().
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\nError n.º 1: Restar marcas unix «a lo bruto»
\n\nEl 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\nEn 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\nCómo corregirlo
\nUsen objetos DateTime y el método diff(). Ellos tienen en cuenta todos los saltos de tiempo:
<?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\nTrabajar con la diferencia de fechas PHP mediante DateTime::diff es el estándar de la industria. Recuerden este patrón.
Error n.º 2: Ignorar la zona horaria
\n\nImaginen: 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.
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\nSolució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\nUsen 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\nError n.º 3: Confundir days con format('%a')
\n\nEl objeto DateInterval tiene una propiedad days y un método format('%a'). Parece que son lo mismo. Pero hay un matiz:
- \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, entoncesddevolverá 4 (el resto después de restar un mes). \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.
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\nSi necesitan exactamente el número de días entre dos fechas — tomen