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. También veremos clases modernas como DateTime
.
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. Pero puedes especificar la zona horaria a usar por defecto con date_default_timezone_set
. Puedes consultar una lista de las zonas disponibles
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):
Modificador Descripción Ejemplo
/*
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, requiere soporte de localización en el sistema operativo del servidor. La disponibilidad de locales puede variar. Opciones comunes:
/*
%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 ofrece una forma más robusta y orientada a objetos para trabajar con fechas y horas, incluyendo soporte para zonas horarias. Es importante recordar que los métodos como modify() devuelven un nuevo objeto DateTime a menos que se use la sintaxis $fecha->modify('+1 day'), que modifica el objeto original.
<?php
$fecha = new DateTime("2025-05-05");
echo $fecha->format("Y-m-d"); // 2025-05-05
$fecha->modify("+1 day"); // Modifica el objeto $fecha
echo $fecha->format("Y-m-d"); // 2025-05-06
$otraFecha = new DateTime("2025-05-05");
$fechaFutura = $otraFecha->modify("+1 week"); // $fechaFutura es un nuevo objeto DateTime
echo $fechaFutura->format("Y-m-d"); // 2025-05-12
?>
Ejemplo con zonas horarias:
<?php
$zonaHorariaNuevaYork = new DateTimeZone("America/New_York");
$fechaNuevaYork = new DateTime("now", $zonaHorariaNuevaYork);
echo $fechaNuevaYork->format("Y-m-d H:i:s T"); // Ejemplo: 2025-05-05 12:10:50 EDT (la hora puede variar)
$zonaHorariaMadrid = new DateTimeZone("Europe/Madrid");
$fechaMadrid = new DateTime("now", $zonaHorariaMadrid);
echo $fechaMadrid->format("Y-m-d H:i:s T"); // Ejemplo: 2025-05-05 18:10:50 CEST (la hora puede variar)
?>
En el siguiente tema veremos la forma recoendada actual para mostrar la fecha, asi como varias funciones relacionadas útiles.
Añadimos una lista de los errores mas comunes que cometemos al trabajar con fechas