Bug #50559 [Com]: Clone is not implemented for DateInterval and DatePeriod
| From: | anatoliy at ukhvanovy dot name | Date: | Sun, 30 Oct 2016 15:08:47 +0000 |
| Subject: | Bug #50559 [Com]: Clone is not implemented for DateInterval and DatePeriod | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-205072@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=50559&edit=1
ID: 50559
Comment by: anatoliy at ukhvanovy dot name
Reported by: sr at emini dot dk
Summary: Clone is not implemented for DateInterval and
DatePeriod
Status: Assigned
Type: Bug
Package: Date/time related
Operating System: Fedora 10
PHP Version: 5.3.1
Assigned To: derick
Block user comment: N
Private report: N
New Comment:
There's a WORKAROUND.
If you var_export the instance, then it won't be empty anymore, and you can clone it. Consider
the following code:
<?php
header('Content-Type:text/plain');
$originalInstance = new DateInterval('P1D');
// Original instance is not initialized yet.
// You cannot clone it now, otherwise you'll get an empty copy.
$copyCreatedBeforeOriginalInstanceIsInitialized =
clone $originalInstance;
echo PHP_EOL, 'This copy is empty: ';
var_export($copyCreatedBeforeOriginalInstanceIsInitialized);
// Now, let's initialize original instance by var_export'ing it.
// We don't want to output the var_export's result -
// it is used only to initialize our instance, not to output it.
$doNotEchoVarExport = true;
var_export($originalInstance, $doNotEchoVarExport);
// That's all! For now, original instance is already initialized,
// and we may clone it â we'll get correct copy.
$copyCreatedAfterOriginalInstanceIsInitialized =
clone $originalInstance;
// Now, let's see what we've got:
echo PHP_EOL, 'Original instance is OK: ';
var_export($originalInstance);
echo PHP_EOL, 'Empty copy is still empty: ';
var_export($copyCreatedBeforeOriginalInstanceIsInitialized);
echo PHP_EOL, 'Correct copy is OK: ';
var_export($copyCreatedAfterOriginalInstanceIsInitialized);
// DateInterval behaves like Schrödinger's cat:
// the action of observation affects the phenomenon being observed.
// (var_export'ing the state of DateInterval affects its state.)
?>
The code above produces the following output:
This copy is empty: DateInterval::__set_state(array(
))
Original instance is OK: DateInterval::__set_state(array(
'y' => 0,
'm' => 0,
'd' => 1,
'h' => 0,
'i' => 0,
's' => 0,
'weekday' => 0,
'weekday_behavior' => 0,
'first_last_day_of' => 0,
'invert' => 0,
'days' => false,
'special_type' => 0,
'special_amount' => 0,
'have_weekday_relative' => 0,
'have_special_relative' => 0,
))
Empty copy is still empty: DateInterval::__set_state(array(
))
Correct copy is OK: DateInterval::__set_state(array(
'y' => 0,
'm' => 0,
'd' => 1,
'h' => 0,
'i' => 0,
's' => 0,
'weekday' => 0,
'weekday_behavior' => 0,
'first_last_day_of' => 0,
'invert' => 0,
'days' => false,
'special_type' => 0,
'special_amount' => 0,
'have_weekday_relative' => 0,
'have_special_relative' => 0,
))
Previous Comments:
------------------------------------------------------------------------
[2013-08-07 20:09:36] kofkof at laposte dot net
If I swap lines 2 and 3 in the bug description code, this way:
$dateInterval1 = new DateInterval('P1D');
var_dump($dateInterval1);
$dateInterval2 = clone $dateInterval1;
var_dump($dateInterval2);
... then $dateInterval2 is not empty (as displayed by var_dump()). However, when
I try to use it:
$d = new DateTime();
$d->add($dateInterval2);
... then I get "Warning: DateTime::add(): The DateInterval object has not been
correctly initialized by its constructor in..."
(PHP 5.4.11 on Mac OS 10.7.5)
------------------------------------------------------------------------
[2011-05-06 11:14:51] giorgio dot liscio at email dot it
on windows 7 + apache2 + php 5.3.6
apache crashes when
$cl = clone $dateIntervalObject;
in any scope, in any function, on an empty page too.
i tried to provide a backtrace but something goes wrong
i can't convert the generated .dmp file to a readable dump to attach here
------------------------------------------------------------------------
[2010-03-08 10:59:43] yoarvi at gmail dot com
Did you forget to attach the script?
------------------------------------------------------------------------
[2010-03-07 20:24:53] derick@php.net
This patch causes issues. If I try the attached script I end up in an infinite loop.
------------------------------------------------------------------------
[2010-01-27 13:47:00] yoarvi at gmail dot com
The following patch implements the logic to clone DatePeriod and DateInterval objects and also
includes a test case:
Index: ext/date/php_date.c
===================================================================
--- ext/date/php_date.c (revision 293574)
+++ ext/date/php_date.c (working copy)
@@ -2213,7 +2213,9 @@
zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std,
Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
- /** FIX ME ADD CLONE STUFF **/
+ new_obj->diff = timelib_rel_time_clone(old_obj->diff);
+ new_obj->initialized = 1;
+
return new_ov;
}
@@ -2283,7 +2285,27 @@
zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std,
Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
- /** FIX ME ADD CLONE STUFF **/
+ new_obj->start = timelib_time_ctor();
+ *new_obj->start = *old_obj->start;
+ if (old_obj->start->tz_abbr) {
+ new_obj->start->tz_abbr = strdup(old_obj->start->tz_abbr);
+ }
+ if (old_obj->start->tz_info) {
+ new_obj->start->tz_info = old_obj->start->tz_info;
+ }
+ new_obj->end = timelib_time_ctor();
+ *new_obj->end = *old_obj->end;
+ if (old_obj->end->tz_abbr) {
+ new_obj->end->tz_abbr = strdup(old_obj->end->tz_abbr);
+ }
+ if (old_obj->end->tz_info) {
+ new_obj->end->tz_info = old_obj->end->tz_info;
+ }
+ new_obj->interval = timelib_rel_time_clone(old_obj->interval);
+ new_obj->recurrences = old_obj->recurrences;
+ new_obj->include_start_date = old_obj->include_start_date;
+ new_obj->initialized = 1;
+
return new_ov;
}
Index: ext/date/tests/bug50559.phpt
===================================================================
--- ext/date/tests/bug50559.phpt (revision 0)
+++ ext/date/tests/bug50559.phpt (revision 0)
@@ -0,0 +1,131 @@
+--TEST--
+Bug #50559 (Clone is not implemented for DateInterval and DatePeriod)
+--FILE--
+<?php
+date_default_timezone_set('Asia/Calcutta');
+
+# Test DateInterval cloning
+$dateInterval1 = new \DateInterval('P1D');
+$dateInterval2 = clone $dateInterval1;
+echo "============================\n";
+echo "DateInterval (original)\n";
+var_dump($dateInterval1);
+echo "============================\n";
+echo "DateInterval (clone)\n";
+var_dump($dateInterval2);
+
+# Test DatePeriod cloning
+$begin = new DateTime('2007-12-31');
+$end = new DateTime('2009-12-31 23:59:59');
+$interval = DateInterval::createFromDateString('last thursday of next month');
+$datePeriod1 = new \DatePeriod($begin, $interval, $end,
+ DatePeriod::EXCLUDE_START_DATE);
+$datePeriod2 = clone $datePeriod1;
+
+echo "============================\n";
+echo "DatePeriod (original)\n";
+foreach ($datePeriod1 as $p) {
+ echo $p->format("l Y-m-d H:i:s\n");
+}
+
+echo "============================\n";
+echo "DatePeriod (clone)\n";
+foreach ($datePeriod2 as $p) {
+ echo $p->format("l Y-m-d H:i:s\n");
+}
+echo "============================\n";
+?>
+--EXPECT--
+============================
+DateInterval (original)
+object(DateInterval)#1 (8) {
+ ["y"]=>
+ int(0)
+ ["m"]=>
+ int(0)
+ ["d"]=>
+ int(1)
+ ["h"]=>
+ int(0)
+ ["i"]=>
+ int(0)
+ ["s"]=>
+ int(0)
+ ["invert"]=>
+ int(0)
+ ["days"]=>
+ int(0)
+}
+============================
+DateInterval (clone)
+object(DateInterval)#2 (8) {
+ ["y"]=>
+ int(0)
+ ["m"]=>
+ int(0)
+ ["d"]=>
+ int(1)
+ ["h"]=>
+ int(0)
+ ["i"]=>
+ int(0)
+ ["s"]=>
+ int(0)
+ ["invert"]=>
+ int(0)
+ ["days"]=>
+ int(0)
+}
+============================
+DatePeriod (original)
+Thursday 2008-01-31 00:00:00
+Thursday 2008-02-28 00:00:00
+Thursday 2008-03-27 00:00:00
+Thursday 2008-04-24 00:00:00
+Thursday 2008-05-29 00:00:00
+Thursday 2008-06-26 00:00:00
+Thursday 2008-07-31 00:00:00
+Thursday 2008-08-28 00:00:00
+Thursday 2008-09-25 00:00:00
+Thursday 2008-10-30 00:00:00
+Thursday 2008-11-27 00:00:00
+Thursday 2008-12-25 00:00:00
+Thursday 2009-01-29 00:00:00
+Thursday 2009-02-26 00:00:00
+Thursday 2009-03-26 00:00:00
+Thursday 2009-04-30 00:00:00
+Thursday 2009-05-28 00:00:00
+Thursday 2009-06-25 00:00:00
+Thursday 2009-07-30 00:00:00
+Thursday 2009-08-27 00:00:00
+Thursday 2009-09-24 00:00:00
+Thursday 2009-10-29 00:00:00
+Thursday 2009-11-26 00:00:00
+Thursday 2009-12-31 00:00:00
+============================
+DatePeriod (clone)
+Thursday 2008-01-31 00:00:00
+Thursday 2008-02-28 00:00:00
+Thursday 2008-03-27 00:00:00
+Thursday 2008-04-24 00:00:00
+Thursday 2008-05-29 00:00:00
+Thursday 2008-06-26 00:00:00
+Thursday 2008-07-31 00:00:00
+Thursday 2008-08-28 00:00:00
+Thursday 2008-09-25 00:00:00
+Thursday 2008-10-30 00:00:00
+Thursday 2008-11-27 00:00:00
+Thursday 2008-12-25 00:00:00
+Thursday 2009-01-29 00:00:00
+Thursday 2009-02-26 00:00:00
+Thursday 2009-03-26 00:00:00
+Thursday 2009-04-30 00:00:00
+Thursday 2009-05-28 00:00:00
+Thursday 2009-06-25 00:00:00
+Thursday 2009-07-30 00:00:00
+Thursday 2009-08-27 00:00:00
+Thursday 2009-09-24 00:00:00
+Thursday 2009-10-29 00:00:00
+Thursday 2009-11-26 00:00:00
+Thursday 2009-12-31 00:00:00
+============================
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=50559
--
Edit this bug report at https://bugs.php.net/bug.php?id=50559&edit=1