Apuntes sobre Php

Lleva décadas en el obituario y sigue aquí.

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, DateTime y DateTimeZone son 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().

TOP