为什么日期给我一个错误的日期?
Why does date gives me a wrong date?
我想根据时间戳和其他一些信息计算日期。
我的函数如下所示:
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$days = 0;
$extraDays = 0;
$endOfCurrentMonth = 0;
$tsDay = 86400;
if($endOfMonth){
$endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
//rest of days in current month. In this sample 16 days
}
for($i=0;$i<$extraMonth;$i++){
$x = $i + 1;
$date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add a month
$date->modify("+{$x} month"); // add the month (next month)
$extraDays += date("t", strtotime($date->format("Y-m-d")));
// get the days of the selected month and add them to count
// in this case its 31 + 30 + 31 = 92
}
$days = $endOfCurrentMonth + $extraDays;
// count everything together 16 + 92 = 108 days
return date("d.m.y", $timestamp + ($tsDay*$days));
//returning date with 108 days added.
}
作为示例,我将函数称为:
// the timestamp is 2015-07-15
echo getLastDeliveryDate(1436911200, true, 3);
// should return 2015-10-31
但是这个 return 2015-10-30
我不知道为什么。但是 108 天应该是 2015-10-31
。这里出了什么问题?
如果我打电话给
echo getLastDeliveryDate(1436911200, true, 2);
它是正确的,给了我 2015-09-30
其实我一直想要这个月的最后一天。
编辑:
有线,如果我在这里测试:IDEONE一切正常。我的项目没有:(
您需要在循环之前创建日期时间对象:
$date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add month
// simpler alternative: $date = new DateTime("@$timestamp");
for($i=0;$i<$extraMonth;$i++){
$date->modify("+1 month"); // add the month (next month)
// $extraDays += date("t", strtotime($date->format("Y-m-d")));
// you can reduce this line to:
$extraDays += $date->format("t");
}
// Result: 15-10-31
否则总是添加 31,因为您使用了时间戳的日期 + 1 个月。
注:
您可以将整个函数简化为:
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$date = new DateTime("@$timestamp");
$date->modify("+$extraMonth month");
if ($endOfMonth)
$date->modify("last day of this month");
return $date->format("d.m.y");
}
问题是夏令时。您在 2015 年 10 月 25 日失去了一个小时。由于您的时间戳恰好是 0:00:00,因此您失去了一个小时,导致“30.10.2015 23:00:00”实际上应该是 0:00:00
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$days = 0;
$extraDays = 0;
$endOfCurrentMonth = 0;
$tag = 86400;
if(date( 'H',$timestamp)==0){$timestamp+=3601;}
if($endOfMonth){
$endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
}
$date = new DateTime(date("Y-m-d", $timestamp));
for($i=0;$i<$extraMonth;$i++){
$date->modify("+1 month");
$extraDays += $date->format("t");
}
$days = $endOfCurrentMonth + $extraDays;
return date("d.m.y", $timestamp + ($tag*$days));
}
echo getLastDeliveryDate(1436911200, true, 3);
如果您的日期时间固定为 0:00:00,此代码通过增加一小时零一秒来解决此问题。当您不关心时间本身时,此解决方案将解决您的问题并且在任何情况下都是可行的。如果您关心时间,则必须检查您是否处于夏令时并采取相应措施。
我想根据时间戳和其他一些信息计算日期。
我的函数如下所示:
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$days = 0;
$extraDays = 0;
$endOfCurrentMonth = 0;
$tsDay = 86400;
if($endOfMonth){
$endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
//rest of days in current month. In this sample 16 days
}
for($i=0;$i<$extraMonth;$i++){
$x = $i + 1;
$date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add a month
$date->modify("+{$x} month"); // add the month (next month)
$extraDays += date("t", strtotime($date->format("Y-m-d")));
// get the days of the selected month and add them to count
// in this case its 31 + 30 + 31 = 92
}
$days = $endOfCurrentMonth + $extraDays;
// count everything together 16 + 92 = 108 days
return date("d.m.y", $timestamp + ($tsDay*$days));
//returning date with 108 days added.
}
作为示例,我将函数称为:
// the timestamp is 2015-07-15
echo getLastDeliveryDate(1436911200, true, 3);
// should return 2015-10-31
但是这个 return 2015-10-30
我不知道为什么。但是 108 天应该是 2015-10-31
。这里出了什么问题?
如果我打电话给
echo getLastDeliveryDate(1436911200, true, 2);
它是正确的,给了我 2015-09-30
其实我一直想要这个月的最后一天。
编辑:
有线,如果我在这里测试:IDEONE一切正常。我的项目没有:(
您需要在循环之前创建日期时间对象:
$date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add month
// simpler alternative: $date = new DateTime("@$timestamp");
for($i=0;$i<$extraMonth;$i++){
$date->modify("+1 month"); // add the month (next month)
// $extraDays += date("t", strtotime($date->format("Y-m-d")));
// you can reduce this line to:
$extraDays += $date->format("t");
}
// Result: 15-10-31
否则总是添加 31,因为您使用了时间戳的日期 + 1 个月。
注:
您可以将整个函数简化为:
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$date = new DateTime("@$timestamp");
$date->modify("+$extraMonth month");
if ($endOfMonth)
$date->modify("last day of this month");
return $date->format("d.m.y");
}
问题是夏令时。您在 2015 年 10 月 25 日失去了一个小时。由于您的时间戳恰好是 0:00:00,因此您失去了一个小时,导致“30.10.2015 23:00:00”实际上应该是 0:00:00
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$days = 0;
$extraDays = 0;
$endOfCurrentMonth = 0;
$tag = 86400;
if(date( 'H',$timestamp)==0){$timestamp+=3601;}
if($endOfMonth){
$endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
}
$date = new DateTime(date("Y-m-d", $timestamp));
for($i=0;$i<$extraMonth;$i++){
$date->modify("+1 month");
$extraDays += $date->format("t");
}
$days = $endOfCurrentMonth + $extraDays;
return date("d.m.y", $timestamp + ($tag*$days));
}
echo getLastDeliveryDate(1436911200, true, 3);
如果您的日期时间固定为 0:00:00,此代码通过增加一小时零一秒来解决此问题。当您不关心时间本身时,此解决方案将解决您的问题并且在任何情况下都是可行的。如果您关心时间,则必须检查您是否处于夏令时并采取相应措施。