DateInterval::createFromDateString

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

DateInterval::createFromDateStringEstablece un objeto DateInterval desde las partes relativas de una cadena

Descripción

Estilo orientado a objetos

public static function DateInterval::createFromDateString(string $datetime): DateInterval

Estilo procedimental

Usas los analizadores de fecha/hora como los usados en el constructor de DateTimeImmutable para crear un DateInterval desde las partes relativas de la cadena analizada.

Parámetros

datetime

Una fecha con partes relativas. Específicamente, los formatos relativos admitidos por el analizador utilizados por DateTimeImmutable, DateTime, y strtotime() serán los empleados para construir el objeto DateInterval

Para usar un string con formato ISO-8601 como P7D, debes usar DateInterval::__construct().

Valores devueltos

Devuelve DateInterval en caso de éxito. Estilo procedimental retorna false en caso de error.

Errores/Excepciones

Solo en la API Orientada a Objetos: Si se pasa una cadena de fecha/hora inválida, se lanza DateMalformedIntervalStringException.

Historial de cambios

Versión Descripción
8.4.0 Ahora tiene un tipo de retorno tentativo de DateInterval. Anteriormente era DateInterval|false.
8.3.0 DateInterval::createFromDateString() ahora lanza DateMalformedIntervalStringException si se pasa una cadena inválida. Anteriormente, devolvía false, y emitía una advertencia. date_interval_create_from_date_string() no ha cambiado.
8.2.0 Las propiedades from_string y date_string solo serán visibles cuando se crea un DateInterval con este método.

Ejemplos

Ejemplo #1 Analizando intervalos de fechas válidos

<?php
// Cada conjunto de intervalos es equivalente.
$i = new DateInterval('P1D');
$i = DateInterval::createFromDateString('1 day');

$i = new DateInterval('P2W');
$i = DateInterval::createFromDateString('2 weeks');

$i = new DateInterval('P3M');
$i = DateInterval::createFromDateString('3 months');

$i = new DateInterval('P4Y');
$i = DateInterval::createFromDateString('4 years');

$i = new DateInterval('P1Y1D');
$i = DateInterval::createFromDateString('1 year + 1 day');

$i = new DateInterval('P1DT12H');
$i = DateInterval::createFromDateString('1 day + 12 hours');

$i = new DateInterval('PT3600S');
$i = DateInterval::createFromDateString('3600 seconds');

Ejemplo #2 Analizando combinaciones e intervalos negativos

<?php
$i = DateInterval::createFromDateString('62 weeks + 1 day + 2 weeks + 2 hours + 70 minutes');
echo $i->format('%d %h %i'), "\n";

$i = DateInterval::createFromDateString('1 year - 10 days');
echo $i->format('%y %d'), "\n";

El ejemplo anterior mostrará:

449 2 70
1 -10

Ejemplo #3 Analizando intervalos de fechas relativas especiales

<?php
$i = DateInterval::createFromDateString('last day of next month');
var_dump($i);

$i = DateInterval::createFromDateString('last weekday');
var_dump($i);

Resultado del ejemplo anterior en PHP 8.2:

object(DateInterval)#1 (2) {
  ["from_string"]=>
  bool(true)
  ["date_string"]=>
  string(22) "last day of next month"
}
object(DateInterval)#2 (2) {
  ["from_string"]=>
  bool(true)
  ["date_string"]=>
  string(12) "last weekday"
}

Resultado del ejemplo anterior en PHP 8 es similar a:

object(DateInterval)#1 (16) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(1)
  ["d"]=>
  int(0)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["f"]=>
  float(0)
  ["weekday"]=>
  int(0)
  ["weekday_behavior"]=>
  int(0)
  ["first_last_day_of"]=>
  int(2)
  ["invert"]=>
  int(0)
  ["days"]=>
  bool(false)
  ["special_type"]=>
  int(0)
  ["special_amount"]=>
  int(0)
  ["have_weekday_relative"]=>
  int(0)
  ["have_special_relative"]=>
  int(0)
}
object(DateInterval)#2 (16) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(0)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["f"]=>
  float(0)
  ["weekday"]=>
  int(0)
  ["weekday_behavior"]=>
  int(0)
  ["first_last_day_of"]=>
  int(0)
  ["invert"]=>
  int(0)
  ["days"]=>
  bool(false)
  ["special_type"]=>
  int(1)
  ["special_amount"]=>
  int(-1)
  ["have_weekday_relative"]=>
  int(0)
  ["have_special_relative"]=>
  int(1)
}
add a note

User Contributed Notes 2 notes

up
3
felix dot edelmann at check24 dot de
1 year ago
Please note that Daylight Saving Time (DST) transitions only work as expected when using new \DateInterval(), not \DateInterval::createFromDateString().

<?php
$now = new \DateTimeImmutable("2025-03-29 13:00:00", new DateTimeZone('Europe/Berlin'));
var_dump($now);
// 2025-03-29 13:00:00

var_dump($now->add(\DateInterval::createFromDateString('1440 minutes')));
// 2025-03-30 13:00:00
var_dump($now->add(new \DateInterval('PT1440M')));
// 2025-03-30 14:00:00

// these are not equivalent:
var_dump(\DateInterval::createFromDateString('1440 minutes'));
var_dump(new \DateInterval('PT1440M'));
?>
up
0
daniel at justathought dot dev
11 hours ago
This builds on [felix dot edelmann at check24 dot de]'s note about Daylight Saving Time (DST) transitions.

TLDR: it seems that **using the time component of an ISO duration** string is what switches-on time-zone awareness.  At least in this case, "*duration* string" may understate its meaning/effect.

Expand on Felix's code a little and a pattern starts to emerge:

<?php

$timeZone = new DateTimeZone('Europe/Berlin');

$beforeChangeover = new DateTimeImmutable('2025-03-29 13:00:00', $timeZone);

// To recap:

print_r($beforeChangeover->add(new DateInterval('P1D')));                            // => 2025-03-30 13:00
print_r($beforeChangeover->add(new DateInterval('PT1440M')));                        // => 2025-03-30 14:00 (+1 hour!)
print_r($beforeChangeover->add(new DateInterval('PT24H')));                          // => 2025-03-30 14:00 (+1 hour!)

print_r($beforeChangeover->add(DateInterval::createFromDateString('1 day')));        // => 2025-03-30 13:00
print_r($beforeChangeover->add(DateInterval::createFromDateString('1440 minute')));  // => 2025-03-30 13:00
print_r($beforeChangeover->add(DateInterval::createFromDateString('24 hour')));      // => 2025-03-30 13:00

print_r($beforeChangeover->modify('+1 day'));                                        // => 2025-03-30 13:00
print_r($beforeChangeover->modify('+1440 minute'));                                  // => 2025-03-30 13:00
print_r($beforeChangeover->modify('+24 hour'));                                      // => 2025-03-30 13:00

// diff():

print_r(new DateTimeImmutable('2025-03-30 13:00:00', $timeZone)->diff($beforeChangeover));  // => 1d 0h
print_r(new DateTimeImmutable('2025-03-30 14:00:00', $timeZone)->diff($beforeChangeover));  // => 1d 1h
?>