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.

versión: 4.x