Как мне глубоко скопировать объект DateTime? - PullRequest
111 голосов
/ 05 апреля 2010
$date1 = $date2 = new DateTime();
$date2->add(new DateInterval('P3Y'));

Теперь $date1 и $date2 содержат одну и ту же дату - через три года. Я хотел бы создать две отдельные даты: одну, которая анализируется из строки, а другая с добавлением трех лет. В настоящее время я взломал это так:

$date2 =  new DateTime($date1->format(DateTime::ISO8601));

но это похоже на ужасный взлом. Есть ли «правильный» способ глубокого копирования объекта DateTime?

Ответы [ 5 ]

151 голосов
/ 05 апреля 2010
$date1 = new DateTime();
$date2 = new DateTime();
$date2->add(new DateInterval('P3Y'));

Обновление:

Если вы хотите скопировать, а не ссылаться на существующий объект DT, используйте clone, а не =.

$a = clone $b;

96 голосов
/ 28 марта 2013

Клонировать дату с помощью оператора clone :

$date1 = new DateTime();
$date2 = clone $date1;
$date2->add(new DateInterval('P3Y'));

Клоны по умолчанию мелкие, но достаточно глубокие для DateTime. В ваших собственных объектах вы можете определить магический метод __clone() для клонирования свойств (то есть дочерних объектов), которые имеют смысл клонировать при изменении родительского объекта.

(Я не уверен, почему документация считает хорошим примером необходимости клонировать объект - GTK. Кто использует GTK в PHP?)

38 голосов
/ 10 февраля 2015

Введен PHP 5.5.0 DateTimeImmutable . add и modify методы этого класса возвращают новые объекты.

$date1 = new DateTimeImmutable();
$date2 = $date1->add(new DateInterval('P3Y'));
5 голосов
/ 01 октября 2018

TLDR:

$date1 = new DateTime();
$date2 = (clone $date1)->modify('+3 years');

( Глубокое копирование DateTime делает (в настоящее время) нет смысл )

Просто так:)

Пояснение "php создать объект datetime из другого datetime":

  1. Ключевое слово clone делает обычную мелкую копию - для этого случая достаточно (почему => см. Ниже)
  2. Обтекание его () вычисляет выражение, возвращающее вновь созданный объект, по clone
  3. ->modify() поэтому вызывается и модифицирует новый объект
  4. DateTime::modify(...) документы:

    Возвращает объект DateTime для объединения методов или FALSE при ошибке.

  5. $date2 теперь содержит только что созданный и измененный клон / копию, а $date1 остается неизменным

Почему вам не нужно глубоко скопировать сюда:

Глубокое копирование / клонирование необходимо только тогда, когда вам нужно скопировать цели со свойствами, ссылками , но это:

class TestDateTime extends DateTime{
  public function test(){
   //*this* way also outputs private variables if any...
   print_r( get_object_vars($this) );    
  }
}
$test = (new TestDateTime())->test();

выходы: * * тысяча пятьдесят-четырь

Array
(
    [date] => 2018-10-01 11:31:29.000000
    [timezone_type] => 3
    [timezone] => UTC
)

поэтому нет ссылок => нет необходимости глубоко копировать.

1 голос
/ 11 сентября 2017

Вы должны изменить DateTime на DateTimeImmutable

// from date time
$date = \DateTimeImmutable::createFromMutable($mutableDate)

тогда вы можете вызывать любой метод на DateTime, не беспокоясь об его изменении

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...