Manejo de Fechas en PHP
Manejar fechas en PHP puede parecer complicado por las zonas horarias y los cambios de horario. En esta lección aprenderemos a trabajar con timestamps, formatear fechas, validarlas y parsearlas con las funciones procedurales de PHP.
Importancia de la Zona Horaria
Las fechas dependen de las zonas horarias (por ejemplo, UTC vs. hora local) y del horario de verano. Por defecto, las funciones de PHP usan UTC (o GMT), pero el servidor puede estar configurado con una zona horaria local.Para evitar confusiones:
- Convierte siempre las fechas a UTC antes de almacenarlas.
- Representa fechas internamente con timestamps (segundos desde el epoch: 1 de enero de 1970, UTC).
El timestamp y la función time()
time() devuelve los segundos desde el epoch (1 de enero de 1970 a las 00:00 UTC). Como referencia fija e inmutable para un momento dado, independientemente de zonas horarias o cambios de horario, es la base ideal para marcar eventos o fechas sin ambigüedades.
Obtener la fecha y hora actual
<?php
date_default_timezone_set("UTC");
$ahora = time();
echo "Timestamp actual: $ahora\n";
echo "Fecha actual (UTC): " . date("Y-m-d H:i:s", $ahora) . "\n";
//Timestamp actual: 1749288064
//Fecha actual (UTC): 2025-06-07 09:21:04
?>
Nota: PHP se ejecuta en el servidor, por tanto "hora local" se refiere a la del servidor. Especifica la zona horaria por defecto con date_default_timezone_set(). Puedes consultar la lista de zonas disponibles en el manual oficial.
Formateando fechas con date()
date() convierte un timestamp a un formato legible. El primer parámetro (string) es la cadena de formato; el segundo parámetro (int) es un timestamp a formatear. Sin timestamp, usa time():
<?php
echo date("Y-m-d"); // Ejemplo: 2025-05-05
echo date("d/m/Y H:i:s"); // Ejemplo: 05/05/2025 18:10:50
echo date("D, j M Y g:i a"); // Ejemplo: Mon, 5 May 2025 6:10 pm
?>
Usa gmdate() para UTC puro. UTC ("tiempo universal coordinado") es el principal estándar, equivalente a "tiempo medio de Greenwich" (GMT).
Modificadores (selección)
/*
d Día del mes (01-31) 05
j Día del mes sin cero (1-31) 5
D Día de la semana, 3 letras Mon
l Día de la semana, completo Monday
m Mes (01-12) 05
n Mes sin cero (1-12) 5
F Mes, completo May
Y Año (4 dígitos) 2025
y Año (2 dígitos) 25
H Hora (00-23) 18
i Minutos (00-59) 10
s Segundos (00-59) 50
r Formato RFC 2822 Mon, 05 May 2025 18:10:50 +0000
c Formato ISO 8601 2025-05-05T18:10:50+00:00
*/
Ejemplo combinado:
<?php
echo date("l, jS \of F Y, H:i:s"); // Ejemplo: Monday, 5th of May 2025, 18:10:50
?>
Calculando timestamps con mktime()
mktime() calcula el timestamp de una fecha específica. Su sintaxis es:
mktime(hora, minuto, segundo, mes, día, año, dst)
Los parámetros se pueden omitir de derecha a izquierda. Si se omiten, se usan los valores actuales. El parámetro dst (horario de verano) puede ser 1 (sí), 0 (no) o -1 (determinar automáticamente, recomendado).
<?php
$miTimestamp = mktime(0, 0, 0, 1, 1, 2005);
echo $miTimestamp . "\n";
echo date("l", $miTimestamp);
// Resultado:
// 1104537600
// Saturday
?>
Usa (int) para asegurar que los parámetros sean numéricos:
<?php
$mes = "1"; // De un formulario
$miTimestamp = mktime(0, 0, 0, (int)$mes, 1, 2005);
/*
1104537600
*/
?>
Validando fechas con
checkdate()
checkdate() verifica si una fecha es válida (considera años bisiestos):
<?php
if (checkdate(2, 29, 2024)) {
echo "Fecha válida\n"; // 2024 es bisiesto
} else {
echo "Fecha inválida\n";
}
// devuelve fecha válida
?>
Parseando fechas con strtotime()
strtotime() convierte una descripción de fecha en texto a un timestamp:
<?php
$timestampManana = strtotime("tomorrow");
echo "Mañana será: " . date("Y-m-d", $timestampManana) . "\n"; // Ejemplo: 2025-05-06
$timestampProximoLunes = strtotime("next Monday");
echo "El próximo lunes será: " . date("Y-m-d", $timestampProximoLunes) . "\n"; // Ejemplo: 2025-05-12
?>
puedes consultar expresiones de tiempo y fecha soportados (en inglés, claro)
Localización con strftime()
date() no admite localización (por ejemplo, meses en español). Usa strftime() con setlocale():
<?php
setlocale(LC_TIME, "es_ES.UTF8");
echo strftime("Hoy es %A, %e de %B de %Y"); // Ejemplo: Hoy es lunes, 5 de mayo de 2025
?>
Nota: strftime() ha sido declarado obsoleto y requiere soporte de localización en el sistema operativo del servidor. La disponibilidad de locales puede variar. En la siguiente lección veremos alternativas modernas.
/*
%A: Día de la semana, completo (lunes)
%e: Día del mes (1-31)
%B: Mes, completo (mayo)
%Y: Año (2025)
*/
Manejo moderno con DateTime
La clase DateTime es la forma recomendada cuando se necesita manipular fechas con comodidad: sumar intervalos, comparar, cambiar de zona horaria, etc. Su API es más clara que encadenar llamadas a mktime() y date().
<?php
$fecha = new DateTime("2025-05-05");
echo $fecha->format("Y-m-d"); // 2025-05-05
$fecha->modify("+1 day");
echo $fecha->format("Y-m-d"); // 2025-05-06
?>
Con zona horaria:
<?php
$madrid = new DateTime("now", new DateTimeZone("Europe/Madrid"));
echo $madrid->format("Y-m-d H:i:s T"); // 2025-05-05 18:10:50 CEST
?>
Nota: modify() modifica el objeto en el lugar y lo devuelve. Si necesitas conservar el original, clona antes: $copia = clone $fecha;
Recapitulación
- Almacena fechas internamente como timestamps (segundos desde el epoch, 1 de enero de 1970 UTC) para evitar problemas de zona horaria.
time()devuelve el timestamp actual.date($formato, $timestamp)lo convierte a texto legible.gmdate()hace lo mismo siempre en UTC.- Usa siempre
date_default_timezone_set("UTC")(o la zona que corresponda) al inicio del script para evitar comportamientos inesperados. mktime(hora, minuto, segundo, mes, día, año)calcula el timestamp de una fecha concreta. Convierte los parámetros a(int)si vienen de formularios.checkdate($mes, $dia, $año)valida si una fecha es correcta, incluidos los años bisiestos.strtotime("tomorrow"),strtotime("next Monday")y expresiones similares convierten descripciones en inglés a timestamps.strftime()permite localización pero está obsoleta. Para manipulación cómoda de fechas,DateTimeyDateTimeZoneson la opción moderna recomendada.
En la próxima lección: más sobre fechas en PHP: funciones avanzadas, errores comunes y cómo mostrar fechas en español sin strftime().