我正在尝试使用DateTime查找两个日期之间的天数差异。我了解还有其他几篇文章介绍了如何执行此操作。但是,运行代码时收到错误消息。我认为这可能是格式问题,但我很茫然。
如您所见,我已尝试将$ orderdate格式化为文档中建议的Y-m-d格式。它似乎正在解决问题。我想念什么吗?根据文档,这应该可以正常工作。
$orderdate = strip_tags(str_replace(array('"', "'"), "", str_replace(array("\n", "\r"), ' ', $_POST['pickupship-date'])));
$orderdate = $conn->real_escape_string($orderdate);
$orderdate = date( "Y-m-d", strtotime($orderdate) );
echo $orderdate;
date_default_timezone_set('America/Chicago');
$completiondate = date("m/d/Y");
$completiondate = date( "Y-m-d", strtotime($completiondate) );
echo $completiondate;
$duration = $orderdate->diff($completiondate);
$duration->format('%R%a days');
echo $duration;
编辑:我已经根据收到的建议更新了代码。 echo $ orderdate和echo $ completiondate完全按预期输出。但是,对于$ duration,我什么也没得到。
答案 0 :(得分:0)
这是最终对我有用的代码:
$orderdate = strip_tags(str_replace(array('"', "'"), "", str_replace(array("\n", "\r"), ' ', $_POST['pickupship-date'])));
$orderdate = $conn->real_escape_string($orderdate);
$completiondate = new DateTime('now', new DateTimeZone('America/Chicago'));
$completiondate = $completiondate->format('Y-m-d');
$orderdate = new DateTime($orderdate);
$completiondate = new DateTime($completiondate);
$duration = $orderdate->diff($completiondate);
$duration = $duration->format('%R%a days');
答案 1 :(得分:0)
目前尚不清楚您想用此代码实现什么。它所做的大部分操作都不正确或不需要。
$orderdate = strip_tags(str_replace(array('"', "'"), "", str_replace(array("\n", "\r"), ' ', $_POST['pickupship-date'])));
您应该为pickupship-date
字段设置固定格式。像Y-m-d
(或m/d/Y
,如果您更喜欢它)之类的东西坚持下去。在日期时间字段中使用引号,撇号,换行符或HTML标记没有任何意义。如果输入值与预期格式不匹配,则显示错误并在此处停止处理。
$orderdate = $conn->real_escape_string($orderdate);
仅对用于构建SQL查询的数据使用DB字符串转义功能。此操作对于您下面对$orderdate
进行的操作没有任何意义。
您应该使用准备好的SQL查询来保护应用程序免受SQL注入,而不是通过转义字符串来随意转义和构建查询。
$completiondate = date("m/d/Y"); $completiondate = date( "Y-m-d", strtotime($completiondate) );
date("m/d/Y")
使用m/d/Y
格式将当前日期和时间格式化为字符串。
strtotime($completionDate)
则相反;它将尝试将刚刚生成的字符串解析回当前时间,并返回数字(自1970-01-01 00:00:00 UTC
起的秒数)。
然后,date("Y-m-d", ...)
生成另一个文本格式,表示刚刚解析的日期和时间。总之,这两行与$completiondate = date('Y-m-d');
$duration = $orderdate->diff($completiondate);
这是完全错误的。 $orderdate
是一个字符串,它没有diff()
方法(它没有任何方法,字符串不是PHP中的对象)。
此外,DateTime::diff()
需要另一个DateTime
对象作为参数。
$duration->format('%R%a days');
此行是正确的(但只有在正确创建$duration
且当前不会发生的情况下,此行才有效。)
因为它是2019年而不是2009年,所以您应该远离旧的date & time functions(它们不知道如何处理时区,而且无论如何它们都很尴尬),并且仅使用DateTime
类(和its friends)。
您需要的代码如下:
// The timezone
$tz = new DateTimeZone('America/Chicago');
// Parse the input value, get a DateTime object back, or FALSE on error
$orderDate = date_create($_POST['pickupship-date'], $tz);
if (! $orderDate) {
// The input value does not look like a valid date
// Display an error, stop the processing here
// ...
}
// Get the current date & time
$processingDate = new DateTime('now', $tz);
// Compute the difference
$duration = $orderdate->diff($completionDate);
// Format the difference for display
$duration->format('%R%a days')
通话:
date_create($_POST['pickupship-date'], $tz)
几乎与以下内容相同:
new DateTime($_POST['pickupship-date'], $tz)
,但如果输入值无效,它将返回FALSE
。
无法使用new
来获取表示无效输入的值。
使用new DateTime()
时,代码看起来更简洁,但只有在已经(通过其他方式)验证了传递给它的值之后,它才能按预期工作。如果输入的字符串不是有效日期,则新的DateTime
对象将用1970-01-01 00:00:00
或其他您不希望/期望的值初始化。
date_create()
通过在输入字符串不是有效的日期和时间时返回FALSE
来防止这种情况。
两种方式都接受multiple formats作为参数,包括部分日期和时间表示以及几乎所有英语文本日期时间描述(例如'yesterday noon'
)。
如果要为输入字符串使用固定格式,则可以使用DateTime::createFromFormat()
。
它使用一个附加参数(第一个参数)作为格式字符串(采用date()
或DateTime::format()
接受的格式),并且仅在输入字符串与提供的字符串匹配时返回DateTime
对象格式(否则为FALSE
)。
答案 2 :(得分:0)
让您的生活变得简单,并使用DateTime类,它将为您做很多事情。 重要:date()函数返回一个字符串,而不是某些Date对象。 所以
$orderdate = date( "Y-m-d", strtotime($orderdate) );
$orderdate->diff
区别字符串而不是你想要的东西。
<?php
$_POST['pickupship-date'] = "2018-03-04";
$replaceNewLines = str_replace(array("\n", "\r"), ' ', $_POST['pickupship-date']);
//not necessary when you use prepared statements. Always use prepared statements!!!
// $replaceQuotes = str_replace(array('"', "'"), "", $replaceNewLines);
$orderdate = strip_tags($replaceNewLines);
//always use prepared statements, then you don't have to do this
//$orderdate = $conn->real_escape_string($orderdate);
// strtotime not necessary $orderdate = date( "Y-m-d ", strtotime($orderdate) );
$orderdate = new DateTime($orderdate);
echo '$orderdate :';
var_dump($orderdate->format("Y-m-d"));
date_default_timezone_set('America/Chicago');
$completiondate = new DateTime();
echo '$completiondate :';
var_dump( $completiondate->format("Y-m-d"));
$duration = $orderdate->diff($completiondate);
echo '$duration :';
var_dump($duration->format('%d days'));