Fecha en PHP
Guía sobre las funciones de fecha en PHP: date(), time(), strtotime(), mktime() y la API orientada a objetos DateTime y DateTimeImmutable.
Introducción
Casi toda aplicación necesita leer, formatear o hacer aritmética con fechas: entradas de registro, etiquetas de "publicado hace 3 días", programación, comprobaciones de expiración. PHP ofrece dos conjuntos de herramientas paralelos para esto:
- Funciones procedurales basadas en el timestamp Unix — un entero que cuenta los segundos desde el 1 de enero de 1970, 00:00:00 UTC.
time(),date(),strtotime()ymktime()pertenecen a este grupo. - La API orientada a objetos
DateTime—DateTime,DateTimeImmutable,DateTimeZoneyDateInterval— que es más segura para aritmética y manejo de zonas horarias.
Esta página cubre las funciones y clases más utilizadas, cuándo elegir cada una, y el error de zona horaria que sorprende a casi todo el mundo.
Una nota sobre las zonas horarias
Por defecto, PHP usa la zona horaria configurada en php.ini (la opción date.timezone). Si no está configurada, es posible obtener resultados inconsistentes entre servidores. Establécela explícitamente al inicio del script, o pasa un DateTimeZone a cada objeto:
date_default_timezone_set('UTC');Consulta PHP Timezones para ver la lista completa de identificadores válidos y cómo convertir entre zonas.
La función date()
date(string $format, ?int $timestamp = null) formatea un timestamp en una cadena legible por humanos. Si se omite el timestamp, usa la hora actual. Esta es la función principal para mostrar fechas.
echo date('Y-m-d H:i:s'); // e.g. 2023-10-25 14:30:00
echo date('l, F j, Y'); // e.g. Wednesday, October 25, 2023La cadena format se construye con marcadores de posición de un solo carácter. Los más comunes:
| Carácter | Significado | Ejemplo |
|---|---|---|
Y | Año de 4 dígitos | 2023 |
m | Mes, con ceros | 10 |
d | Día del mes, con ceros | 25 |
H | Hora, 24h, con ceros | 14 |
i | Minutos, con ceros | 30 |
s | Segundos, con ceros | 00 |
l | Nombre completo del día de la semana | Wednesday |
F | Nombre completo del mes | October |
Para imprimir una letra literal que también sea un carácter de formato, escápala con una barra inversa: date('\T\o\d\a\y: Y-m-d').
La función time()
time() devuelve el timestamp Unix actual como un entero. Úsala cuando necesites un "ahora" numérico para almacenar, comparar o hacer aritmética.
$now = time();
echo $now; // an integer such as 1698241800
// One hour from now:
echo date('Y-m-d H:i:s', $now + 3600);Dado que un timestamp es simplemente un entero de segundos, puedes sumar o restar duraciones directamente (+ 3600 para una hora, + 86400 para un día). Para algo más complejo que unos pocos desplazamientos fijos, prefiere la aritmética con DateTime que se muestra a continuación.
La función strtotime()
strtotime(string $datetime, ?int $baseTimestamp = null) convierte una fecha/hora textual en inglés a un timestamp, devolviendo false en caso de fallo. Entiende tanto cadenas absolutas como frases relativas.
echo strtotime('2023-10-25 14:30:00'); // 1698244200 (UTC)
echo "\n";
var_dump(strtotime('next monday')); // a future timestamp, or false if unparseable$tomorrow = strtotime('+1 day');
echo date('Y-m-d', $tomorrow);Siempre verifica que el resultado no sea false antes de usarlo, ya que un error tipográfico falla silenciosamente en lugar de lanzar una excepción.
La función mktime()
mktime(int $hour, int $minute, int $second, int $month, int $day, int $year) construye un timestamp a partir de componentes individuales. El orden de los argumentos es primero la hora y luego la fecha.
$timestamp = mktime(0, 0, 0, 12, 31, 2023);
echo date('Y-m-d', $timestamp); // 2023-12-31mktime() normaliza los valores fuera de rango, lo cual es útil: mktime(0, 0, 0, 13, 1, 2023) convierte el "mes 13" en enero de 2024.
La clase DateTime
new DateTime(string $datetime = 'now', ?DateTimeZone $timezone = null) envuelve una fecha en un objeto que puedes formatear, comparar y modificar con llamadas a métodos. (La función date_create() es un alias procedural del mismo constructor.)
$date = new DateTime('2023-10-25', new DateTimeZone('UTC'));
echo $date->format('Y-m-d'); // 2023-10-25DateTime es mutable — métodos como modify() modifican el objeto en su lugar. Eso es el origen de errores sutiles cuando un objeto se comparte, razón por la que la versión inmutable que se muestra a continuación suele ser preferida.
La clase DateTimeImmutable
DateTimeImmutable tiene la misma API que DateTime, pero cada método de modificación devuelve un nuevo objeto y deja el original intacto. Para el código moderno, esta es la opción más segura por defecto.
$date = new DateTimeImmutable('2023-10-25');
$newDate = $date->modify('+1 day');
echo $date->format('Y-m-d'); // 2023-10-25 (unchanged)
echo "\n";
echo $newDate->format('Y-m-d'); // 2023-10-26El método DateTime::format()
format(string $format) convierte un objeto DateTime o DateTimeImmutable en una cadena. Acepta los mismos caracteres de formato que la función date().
$date = new DateTimeImmutable('2023-10-25 14:30:00');
echo $date->format('l, F j, Y'); // Wednesday, October 25, 2023Aritmética y diferencias de fechas
La API orientada a objetos destaca para la aritmética. Usa DateInterval (cadenas de duración ISO-8601) para sumar o restar, y diff() para comparar dos fechas:
$start = new DateTimeImmutable('2023-10-25');
$later = $start->add(new DateInterval('P10D')); // P10D = 10 days
echo $later->format('Y-m-d'); // 2023-11-04
$diff = $start->diff(new DateTimeImmutable('2023-12-31'));
echo "\n" . $diff->days . ' days apart'; // 67 days apartElegir la herramienta correcta
- ¿Necesitas un "ahora" formateado rápidamente? Usa
date(). - ¿Almacenas o comparas un momento de forma numérica? Usa
time()/ timestamps Unix. - ¿Analizas entrada del usuario o de registros? Usa
strtotime()(y verifica si devuelvefalse). - ¿Haces aritmética, diferencias o conversiones de zona horaria? Usa
DateTimeImmutableconDateInterval.
Errores comunes
- Zona horaria no configurada. Sin
date_default_timezone_set()o un valor enphp.ini, los resultados varían según el servidor. Configúrala una vez, al inicio. strtotime()devuelvefalsepara cadenas no reconocidas — nunca lanza excepciones, así que valida siempre.DateTimees mutable.modify()muta el original; usaDateTimeImmutablepara evitar sorpresas con estado compartido.- Los timestamps son segundos en UTC. Al formatearlos con
date()se aplica la zona horaria actual, por lo que el mismo entero se representa de forma diferente según tu configuración.
Conclusión
PHP ofrece un kit de herramientas procedural para timestamps (date(), time(), strtotime(), mktime()) y uno orientado a objetos (DateTime, DateTimeImmutable). Apóyate en los timestamps simples para mostrar y almacenar datos, y en DateTimeImmutable para aritmética y lógica con zonas horarias. Para profundizar más, consulta PHP Date and Time, la referencia de date(), strtotime() y mktime().