Fecha y hora
Nette ofrece dos clases para trabajar con la fecha y la hora: Nette\Utils\DateTimeImmutable (inmutable, recomendada) y Nette\Utils\DateTime (mutable). Ambas extienden las clases nativas de PHP, así que todos los métodos nativos siguen disponibles, y añaden las mismas dos mejoras.
Primera: son estrictas. Mientras que PHP acepta en silencio fechas inválidas como 0000-00-00 (que
convierte en -0001-11-30) o 2024-02-31 (que convierte en 2024-03-02), estas clases lanzan
una excepción.
Segunda: corrigen el comportamiento durante los cambios de hora (horario de verano), donde en PHP nativo sumar un tiempo
relativo (por ejemplo, +100 minutes) puede dar una hora anterior a la de
sumar un periodo más corto (por ejemplo, +50 minutes). Estas clases garantizan que la aritmética funcione de forma
intuitiva y que +100 minutes sea siempre más que +50 minutes.
Instalación:
composer require nette/utils
¿Inmutable o mutable?
La clase DateTimeImmutable está disponible desde la versión 4.1.5 y es la opción recomendada. Cada método
modificador devuelve una instancia nueva en lugar de cambiar la original, de modo que un objeto que haya guardado o pasado
a una función nunca puede cambiar de forma inesperada:
use Nette\Utils\DateTimeImmutable;
$date = new DateTimeImmutable('2024-02-26');
$next = $date->modify('+1 day');
echo $date; // 2024-02-26 00:00:00 (sin cambios)
echo $next; // 2024-02-27 00:00:00 (un objeto nuevo)
DateTime es mutable: la misma llamada cambia el objeto en el sitio. No está obsoleta, pero para el código nuevo
se prefiere la variante inmutable.
use Nette\Utils\DateTime;
$date = new DateTime('2024-02-26');
$date->modify('+1 day');
echo $date; // 2024-02-27 00:00:00 (el original ha cambiado)
Como ambas clases extienden las nativas, sigue usando los métodos que ya conoce: format(),
getTimestamp(), add(), sub(), diff(), setTimezone(), los
operadores de comparación, etc. En DateTimeImmutable, todos los métodos modificadores devuelven una instancia
nueva. El resto de esta página describe solo lo que Nette añade por encima; salvo que se indique lo contrario, todo funciona
igual en ambas clases.
Creación de objetos
static from (string|int|\DateTimeInterface|null $time): static
Crea un objeto a partir de una cadena, de una marca de tiempo UNIX o de otro objeto DateTimeInterface. null significa la hora actual. Lanza una excepción
si la fecha y la hora no son válidas.
DateTimeImmutable::from(1_138_013_640); // desde un timestamp UNIX, con la zona horaria predeterminada
DateTimeImmutable::from('1994-02-26 04:15:32'); // desde una cadena
DateTimeImmutable::from('1994-02-26'); // desde una fecha, la hora será 00:00:00
DateTimeImmutable::from(null); // la fecha y la hora actuales
static fromParts (int $year, int $month, int $day, int $hour=0, int $minute=0, float $second=0.0): static
Crea un objeto a partir de sus partes, o lanza una excepción si la fecha y la hora no son válidas.
DateTimeImmutable::fromParts(1994, 2, 26, 4, 15, 32);
static createFromFormat (string $format, string $datetime, string|\DateTimeZone|null $timezone=null): static|false
Amplía el método nativo DateTime::createFromFormat con la posibilidad de indicar la zona horaria como cadena.
DateTimeImmutable::createFromFormat('d.m.Y', '26.02.1994', 'Europe/London');
Validación estricta
Una fecha o una hora inválidas nunca se ajustan en silencio: siempre lanzan una excepción. Esto vale para todas las formas
de crear o modificar un objeto: el constructor, from(), fromParts() y los métodos
setDate() y setTime().
new DateTimeImmutable('2024-02-31'); // lanza excepción (febrero no tiene día 31)
DateTimeImmutable::fromParts(2024, 2, 31); // lanza excepción
$date->setDate(2024, 2, 31); // lanza excepción
$date->setTime(25, 0); // lanza excepción (no existe la hora 25)
Salida como cadena y JSON
__toString() devuelve la fecha y la hora en el formato Y-m-d H:i:s, así que un objeto se puede
imprimir o concatenar directamente:
echo $date; // '2017-02-03 04:15:32'
Ambas clases implementan JsonSerializable y se serializan al formato ISO 8601, de uso habitual en JavaScript:
echo json_encode($date); // '"2017-02-03T04:15:32+01:00"'
Funciones adicionales de DateTime
La clase mutable DateTime incorpora algunos miembros de más que solo tienen sentido en un objeto mutable y que,
por tanto, no forman parte de DateTimeImmutable.
Su método from() trata además un número pequeño como un desplazamiento en segundos respecto a la hora actual.
La variante inmutable omite este atajo a propósito: allí, un número es siempre una marca de tiempo literal.
DateTime::from(42); // la hora actual más 42 segundos
modifyClone(string $modify=''): static devuelve una copia modificada y deja intacto el original. En un objeto
mutable ofrece lo que modify() le da de serie en el inmutable:
$original = DateTime::from('2017-02-03');
$clone = $original->modifyClone('+1 day');
$original->format('Y-m-d'); // '2017-02-03' (sin cambios)
$clone->format('Y-m-d'); // '2017-02-04'
DateTime::relativeToSeconds(string $relativeTime): int convierte una cadena de tiempo
relativo en segundos:
DateTime::relativeToSeconds('1 minute'); // 60
DateTime::relativeToSeconds('-1 hour'); // -3600
Por último, DateTime define las constantes MINUTE, HOUR, DAY,
WEEK, MONTH y YEAR, que expresan una duración en segundos; MONTH y
YEAR son promedios, así que úselas solo para estimaciones aproximadas.