====== PHP snippets: Fechas ======
===== Creación =====
Fecha actual:
$fecha = new DateTime();
Cualquier fecha:
$fecha = new DateTime("2020-03-01");
A partir de cualquier fecha con cierto formato:
$fecha = DateTime::createFromFormat("d/m/Y H:i:s", "20/10/2021 10:45:11");
Primer día del mes en curso:
$fecha = new DateTime("first day of this month");
Primer día del mes pasado:
$fecha = new DateTime("first day of last month");
Último día del mes en curso:
$fecha = new DateTime("last day of this month");
Último día del mes pasado:
$fecha = new DateTime("last day of last month");
Último domingo:
$fecha = date("Y-m-d", strtotime("last week sunday"));
Para más información, se pueden consultar los [[https://www.php.net/manual/es/datetime.formats.relative.php|diferentes formatos relativos de fecha/hora]] que entiende el analizador de ''strtotime()'', ''DateTime'' y ''date_create()''
==== Semanas ====
Semana y año de una fecha:
semana_anterior = date("W", strtotime("-1 week");
ano_semana_anterior = date("o", strtotime("-1 week");
Año según el número de la semana ISO-8601. Esto tiene el mismo valor que ''Y'', excepto que si el número de la semana ISO (''W'') pertenece al año anterior o siguiente, se usa ese año en su lugar
Fecha de inicio de cierta semana del año:
$ano = 2022;
$semana = 49;
$fecha_inicio_semana = date("Y-m-d", strtotime($ano . "W" . $semana)); // 2022-12-05
* [[https://stackoverflow.com/questions/1659551/how-to-get-the-first-day-of-a-given-week-number-in-php-multi-platform|How to get the first day of a given week number in PHP (multi-platform)?]]
===== Intervalos =====
Establecen una cantidad de tiempo (sigue la norma [[https://en.wikipedia.org/wiki/ISO_8601|ISO 8601]])
* [[https://www.webfx.com/blog/web-design/php-dateinterval-class/|An Introduction to the PHP DateInterval Class]]
$duracion= new DateInterval("P15D"); // 15 días
$fecha= new DateTime();
echo "Hoy es {$fecha->format("Y-m-d")}";
// Dentro de 15 días será:
$fecha->add($duracion);
echo "En 15 días será {$fecha->format("Y-m-d")}";
* https://www.php.net/manual/en/dateinterval.format.php
==== Tiempo entre fechas ====
Días entre fechas
$fecha1 = new DateTime();
$fecha2 = new DateTime();
// Creamos una duración de 1 año, 1 mes y 2 días.
$intervalo = new DateInterval("P1Y1M2D");
$fecha2->add($intervalo);
// Objeto DateInterval con información del intervalo de tiempo
$diferencia = $fecha1->diff($fecha2);
// Días entre fechas
echo $diferencia->days;
Segundos entre fechas:
date_default_timezone_set('Europe/Madrid'); //set your desired timezone
$now = new DateTime( 'NOW' );
$future = new DateTime( '2015/10/09 15:20:00' );
$diffSeconds = $now->getTimestamp() - $future->getTimestamp();
# 2220
Segundos entre fechas y horario:
// Adaptado de https://github.com/RCrowt/working-hours-calculator/
// $working_hours es un array que contiene los segundos desde media noche hasta el
// inicio de la jornada y desde media noche hasta el final de la jornada a contabilizar
function getWorkingHoursInSeconds(DateTime $start, DateTime $end, array $working_hours) {
$seconds = 0; // Total working seconds
// Calculate the Start Date (Midnight) and Time (Seconds into day) as Integers.
$start_date = clone $start;
$start_date = $start_date->setTime(0, 0, 0)->getTimestamp();
$start_time = $start->getTimestamp() - $start_date;
// Calculate the Finish Date (Midnight) and Time (Seconds into day) as Integers.
$end_date = clone $end;
$end_date = $end_date->setTime(0, 0, 0)->getTimestamp();
$end_time = $end->getTimestamp() - $end_date;
// For each Day
for ($today = $start_date; $today <= $end_date; $today += 86400) {
// Set the office hours start/finish.
$today_start = $working_hours[0];
$today_end = $working_hours[1];
// Adjust Start/Finish times on Start/Finish Day.
if ($today === $start_date) $today_start = min($today_end, max($today_start, $start_time));
if ($today === $end_date) $today_end = max($today_start, min($today_end, $end_time));
// Add to total seconds.
$seconds += $today_end - $today_start;
}
return $seconds;
}
// Prueba:
$f = new DateTime("2020-11-11 23:00:00", new DateTimeZone("Europe/Madrid"));
$f2 = new DateTime("2020-11-12 08:30:00", new DateTimeZone("Europe/Madrid"));
// Horario de 08:00 a 00:00
$working_hours = [
28800,
86400
];
echo (getWorkingHoursInSeconds($f, $f2, $working_hours ) / 3600) . " horas";
==== Número de lunes entre fechas ====
// Calcular número de lunes entre fechas
function getMondaysInRange($dateFromString, $dateToString) {
$dateFrom = new \DateTime($dateFromString);
$dateTo = new \DateTime($dateToString);
$dates = [];
if ($dateFrom > $dateTo) {
return $dates;
}
if (1 != $dateFrom->format('N')) {
$dateFrom->modify('next monday');
}
while ($dateFrom <= $dateTo) {
$dates[] = $dateFrom->format('Y-m-d');
$dateFrom->modify('+1 week');
}
return $dates;
}
$dateFromString = '2019-01-01';
$dateToString = '2022-01-01';
var_dump(getMondaysInRange($dateFromString, $dateToString));
===== Modificación =====
Añadir 1 día:
$datetime = new DateTime('2013-01-29');
$datetime->modify('+1 day');
echo $datetime->format('Y-m-d H:i:s');
===== Operaciones =====
Diferencia de tiempos en segundos:
$inicio = strtotime("04:30:45");
$fin = strtotime("04:31:46");
$diferencia = ($fin- $inicio);
echo $diferencia . " segundos";
==== Conversiones ====
Para convertir segundos a formato de tiempo (horas, minutos y segundos):
$segundos = 12600;
$horas = floor($segundos/ 3600);
$minutos = floor($segundos / 60 % 60);
$segundos = floor($segundos % 60);
// Obtener formato HH:MM:SS:
$timeFormat = sprintf('%02d:%02d:%02d', $horas, $minutos, $segundos);
==== UTC a otra zona horaria ====
Si tenemos un string con una fecha en UTC, por ejemplo:
2025-08-31 19:57:25.000000 UTC
Para pasarla a la zona horaria de España:
$fechaString = "2025-08-31 19:57:25.000000 UTC";
// Creamos un objeto DateTime indicando explícitamente que la cadena de fecha está en UTC
$fechaUTC = new DateTime($fechaString, new DateTimeZone('UTC'));
$fechaES = clone $fechaUTC;
// Pasamos a la zona horaria de España:
$fechaES->setTimezone(new DateTimeZone('Europe/Madrid'));
PHP maneja automáticamente el cambio horario de verano/invierno (último domingo de marzo,+2h CEST, último domingo de octubre, +1h CET).
El horario de verano en España se cambia el último domingo de marzo y serían 2 horas sobre UTC (UTC+2). En el de invierno, que se cambia el último domingo de octubre, sería 1 hora sobre UTC (UTC+1). Al horario de verano también se le llama **DST**, de //Daylight Saving Time//, que sería algo como "Horario de ahorro de luz diurna".
===== Recursos =====
* [[https://www.webfx.com/blog/web-design/php-dateinterval-class/|An Introduction to the PHP DateInterval Class]]
* [[https://www.php.net/manual/es/datetime.formats.relative.php|Formatos de fecha relativos]]