Trabajar con fechas en PHP

Si bien PHP cuenta con un montón de funciones relacionadas con fechas, la posibilidad de trabajar con objetos DateTime nos permite resolver un montón de pequeños problemitas de una forma mucho más sencilla y elegante.

Por ejemplo, algunas operaciones básicas:

// por compatibilidad, es mejor siempre especificar la zona horaria
$timezone = new DateTimeZone('America/Santiago');

// crear un objeto de fecha/hora a partir de un string de tiempo válido
// también podría ser un DATETIME de MySQL, p.ej: '2013-09-30 13:14:46'
$some_date = new DateTime('now', $timezone);

// también puedes construir una fecha a partir de un formato específico:
$another_date = DateTime::createFromFormat('d-m-Y', '25-01-1900', $timezone);

// o tomar un camino más largo
$some_other_date = new DateTime(NULL, $timezone);
$some_other_date->setDate( 1986, 4, 26 );
$some_other_date->setTime( 16, 58, 0 );

// luego, puedes obtener la fecha en distintos formatos
$formatted_date = $some_date->format('Y-m-d');
$formatted_date_2 = $another_date->format('c');
$tiempo_unix = $some_date->format('U');

La diferencia entre los objetos DateTime y los objetos DateTimeImmutable es que estos últimos no modifican al mismo objeto, sino que sus métodos retornan un nuevo objeto.

De esta manera, intervalos de tiempo se hace muy sencillo:

// todas las definiciones de intervalo van precedidas de "P" y luego las cantidades y unidades correspondientes
$un_dia = new DateInterval('P1D');
// no se pueden mezclar días con semanas
$dos_meses_y_medio = new DateInterval('P2M2W');
// al usar un intervalo de tiempo, se debe usar "T" antes del rango de tiempo
$un_dia_y_medio = new DateInterval('P1DT12H');
$tres_horas_y_cuarto = DateInterval('PT3H30M');

$ahora = new DateTime('now', new DateTimeZone('America/Santiago'));
// OJO: los métodos de DateTime modifican el objeto original
// agregar 1 día a "ahora"
$ahora->add( $un_dia );
// ... luego, restar 1 día y medio
$ahora->sub( $un_dia_y_medio );
// ... y luego, agregar dos meses y medio
$ahora->add( $dos_meses_y_medio );
// en todos los casos estamos trabajando sobre la misma fecha

// ... o se puede utilizar un objeto DateTimeImmutable
$ahora = new DateTimeImmutable('now', new DateTimeZone('America/Santiago'));
// con DateTimeImmutable, los métodos retornan un nuevo objeto
$manana = $ahora->add( $un_dia );
// dos meses y medio más
$despues = $ahora->add( $dos_meses_y_medio );

Por cierto, en Javascript también puedes trabajar con objetos de fecha/hora de una forma similar.