====== 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]]