DateInterval 不添加日期并且没有错误?
DateInterval doesnt add a date and no errors?
我想把假期一分为二,给定中间的日期。
$splitdate = new DateTime($_POST['date']);
// Split date = 2020-08-04
$holiday1end = $holiday2start = $splitdate;
$holiday1end->sub(new DateInterval('P1D'));
$holiday2start->add(new DateInterval('P1D'));
echobr("Holiday 1: ".$holiday1end->format("Y-m-d"));
echobr("Then " . $splitdate->format("Y-m-d"));
echobr("Holiday 1: " . $holiday2start->format("Y-m-d");
这是我得到的输出:
Holiday 1: 2020-08-04
Then 2020-08-04
Holiday 1: 2020-08-04
这没有意义,最初我将 DateInterval 设置为 'P1D' 但那没有用,所以我尝试删除两天,但我仍然没有得到任何更改或错误。我在这里做错了什么?
编辑清楚:$holiday1end 应该比 $splitdate 少一天,
$holiday2start 应该比 $splitdate 多一天,但两者都没有改变。
看来当你这样做的时候,
$splitdate = new DateTime('2010-12-31');
$holiday1end = $holiday2start = $splitdate;
$splitdate
中的对象实例作为对其他变量的引用传递。由于您 sub
tracting 和 add
ing 的天数相同,因此代码似乎无法正常工作。然而它工作正常但由于同一对象的共享/引用实例,所有效果都适用于同一对象。
但是,如果您执行类似下面的操作,您会注意到日期增加了 1 天(基本上减去了 2 天,然后又增加了 3 天)。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = $holiday2start = $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P3D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
如果将 DateTime
个对象实例分开,您将获得所需的结果。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = new DateTime($date);
$holiday2start = new DateTime($date);
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 1: " . $holiday2start->format("Y-m-d")."\n";
添加为新答案,而不是改写/改写旧答案。
正如@Álvaro González 在我的另一个回答中所写的 ,在不同变量之间传递对象时,许多语言中的对象的行为与我们所想的有所不同。
引用自PHP.net
One of the key-points of PHP 5 OOP that is often mentioned is that
"objects are passed by references by default". This is not completely
true. This section rectifies that general thought using some examples.
A PHP reference is an alias, which allows two different variables to
write to the same value. As of PHP 5, an object variable doesn't
contain the object itself as value anymore. It only contains an object
identifier which allows object accessors to find the actual object.
When an object is sent by argument, returned or assigned to another
variable, the different variables are not aliases: they hold a copy of
the identifier, which points to the same object.
解释:(从这里我能明白什么)
如果 $var1
包含一个对象并且您尝试使用 assignment operator (=
) 将 $var2
初始化为 $var1
就像 $var2 = $var1
$var1
的内容被复制(由 value 传递)到 $var2
但根据手册,如果是 $var1
,$var1
不包含对象本身作为值,只是一个对象标识符,简单来说,指向实际对象.因此,在上述初始化的情况下,$var1
中的 对象标识符 被复制(由 value 传递)到 $var2
和因为现在两个变量 $var1
、$var2
都包含指向同一个对象的值,所以看起来赋值是由 reference 传递的,而不是由 [= 传递的65=]值.
所以当你这样做时,
$splitdate = new DateTime('2010-12-31');
$holiday1end = $holiday2start = $splitdate;
您实际上是在将同一对象的 对象标识符 复制到其他变量。由于您 sub
tracting 和 add
ing 的天数相同,因此所有这些操作都应用于同一对象。代码似乎无法正常工作,但它可以正常工作。
如果您执行类似下面的操作,您会注意到日期增加了 1 天(基本上减去了 2 天,然后又增加了 3 天)。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = $holiday2start = $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P3D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
如果您将 DateTime
个对象实例分开,您将获得所需的结果。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = new DateTime($date);
$holiday2start = new DateTime($date);
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 1: " . $holiday2start->format("Y-m-d")."\n";
如果要复制对象本身,可以使用 clone,它会生成对象的 浅拷贝 。因此,在 clone
.
问题中使用示例代码
$date = '2010-12-31';
$splitdate = new DateTime($date);
// $holiday1end = clone $splitdate;
// $holiday2start = clone $splitdate;
// OR
// $holiday1end = clone $splitdate;
// $holiday2start = clone $holiday1end;
// OR in one line
$holiday2start = clone $holiday1end = clone $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
您得到了想要的结果(Example)。
我想把假期一分为二,给定中间的日期。
$splitdate = new DateTime($_POST['date']);
// Split date = 2020-08-04
$holiday1end = $holiday2start = $splitdate;
$holiday1end->sub(new DateInterval('P1D'));
$holiday2start->add(new DateInterval('P1D'));
echobr("Holiday 1: ".$holiday1end->format("Y-m-d"));
echobr("Then " . $splitdate->format("Y-m-d"));
echobr("Holiday 1: " . $holiday2start->format("Y-m-d");
这是我得到的输出:
Holiday 1: 2020-08-04
Then 2020-08-04
Holiday 1: 2020-08-04
这没有意义,最初我将 DateInterval 设置为 'P1D' 但那没有用,所以我尝试删除两天,但我仍然没有得到任何更改或错误。我在这里做错了什么?
编辑清楚:$holiday1end 应该比 $splitdate 少一天, $holiday2start 应该比 $splitdate 多一天,但两者都没有改变。
看来当你这样做的时候,
$splitdate = new DateTime('2010-12-31');
$holiday1end = $holiday2start = $splitdate;
$splitdate
中的对象实例作为对其他变量的引用传递。由于您 sub
tracting 和 add
ing 的天数相同,因此代码似乎无法正常工作。然而它工作正常但由于同一对象的共享/引用实例,所有效果都适用于同一对象。
但是,如果您执行类似下面的操作,您会注意到日期增加了 1 天(基本上减去了 2 天,然后又增加了 3 天)。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = $holiday2start = $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P3D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
如果将 DateTime
个对象实例分开,您将获得所需的结果。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = new DateTime($date);
$holiday2start = new DateTime($date);
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 1: " . $holiday2start->format("Y-m-d")."\n";
添加为新答案,而不是改写/改写旧答案。
正如@Álvaro González 在我的另一个回答中所写的
引用自PHP.net
One of the key-points of PHP 5 OOP that is often mentioned is that "objects are passed by references by default". This is not completely true. This section rectifies that general thought using some examples.
A PHP reference is an alias, which allows two different variables to write to the same value. As of PHP 5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.
解释:(从这里我能明白什么)
如果 $var1
包含一个对象并且您尝试使用 assignment operator (=
) 将 $var2
初始化为 $var1
就像 $var2 = $var1
$var1
的内容被复制(由 value 传递)到 $var2
但根据手册,如果是 $var1
,$var1
不包含对象本身作为值,只是一个对象标识符,简单来说,指向实际对象.因此,在上述初始化的情况下,$var1
中的 对象标识符 被复制(由 value 传递)到 $var2
和因为现在两个变量 $var1
、$var2
都包含指向同一个对象的值,所以看起来赋值是由 reference 传递的,而不是由 [= 传递的65=]值.
所以当你这样做时,
$splitdate = new DateTime('2010-12-31');
$holiday1end = $holiday2start = $splitdate;
您实际上是在将同一对象的 对象标识符 复制到其他变量。由于您 sub
tracting 和 add
ing 的天数相同,因此所有这些操作都应用于同一对象。代码似乎无法正常工作,但它可以正常工作。
如果您执行类似下面的操作,您会注意到日期增加了 1 天(基本上减去了 2 天,然后又增加了 3 天)。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = $holiday2start = $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P3D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
如果您将 DateTime
个对象实例分开,您将获得所需的结果。
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = new DateTime($date);
$holiday2start = new DateTime($date);
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 1: " . $holiday2start->format("Y-m-d")."\n";
如果要复制对象本身,可以使用 clone,它会生成对象的 浅拷贝 。因此,在 clone
.
$date = '2010-12-31';
$splitdate = new DateTime($date);
// $holiday1end = clone $splitdate;
// $holiday2start = clone $splitdate;
// OR
// $holiday1end = clone $splitdate;
// $holiday2start = clone $holiday1end;
// OR in one line
$holiday2start = clone $holiday1end = clone $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
您得到了想要的结果(Example)。