我有两个表格日期:
Start Date: 2007-03-24
End Date: 2009-06-26
现在我需要通过以下形式找到这两者之间的区别:
2 years, 3 months and 2 days
如何在PHP中执行此操作?
我有两个表格日期:
Start Date: 2007-03-24
End Date: 2009-06-26
现在我需要通过以下形式找到这两者之间的区别:
2 years, 3 months and 2 days
如何在PHP中执行此操作?
当前回答
前段时间,我编写了一个format_date函数,因为它提供了许多关于日期的选项:
function format_date($date, $type, $seperator="-")
{
if($date)
{
$day = date("j", strtotime($date));
$month = date("n", strtotime($date));
$year = date("Y", strtotime($date));
$hour = date("H", strtotime($date));
$min = date("i", strtotime($date));
$sec = date("s", strtotime($date));
switch($type)
{
case 0: $date = date("Y".$seperator."m".$seperator."d",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 1: $date = date("D, F j, Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 2: $date = date("d".$seperator."m".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 3: $date = date("d".$seperator."M".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 4: $date = date("d".$seperator."M".$seperator."Y h:i A",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 5: $date = date("m".$seperator."d".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 6: $date = date("M",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 7: $date = date("Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 8: $date = date("j",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 9: $date = date("n",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 10:
$diff = abs(strtotime($date) - strtotime(date("Y-m-d h:i:s")));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
$date = $years . " years, " . $months . " months, " . $days . "days";
}
}
return($date);
}
其他回答
查看以下链接。这是迄今为止我找到的最好的答案
function dateDiff ($d1, $d2) {
// Return the number of days between the two dates:
return round(abs(strtotime($d1) - strtotime($d2))/86400);
} // end function dateDiff
当你通过日期参数。函数使用PHP ABS()绝对值始终返回正数作为两者之间的天数日期。请记住,两个日期之间的天数不是包括两个日期。因此,如果您正在寻找天数由输入日期之间的所有日期表示,您需要向该函数的结果添加一(1)。例如,差异(由上述函数返回)2013-02-09和2013-02-14之间的值为5。但天数或日期范围2013-02-09-2013-02-14表示的日期为6。
http://www.bizinfosys.com/php/date-difference.html
使用示例:
echo time_diff_string('2013-05-01 00:22:35', 'now');
echo time_diff_string('2013-05-01 00:22:35', 'now', true);
输出:
4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago
功能:
function time_diff_string($from, $to, $full = false) {
$from = new DateTime($from);
$to = new DateTime($to);
$diff = $to->diff($from);
$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;
$string = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
foreach ($string as $k => &$v) {
if ($diff->$k) {
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
} else {
unset($string[$k]);
}
}
if (!$full) $string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . ' ago' : 'just now';
}
我想带来一个稍微不同的视角,这似乎没有被提及。
你可以用声明的方式解决这个问题(就像任何其他问题一样)。重点是问你需要什么,而不是如何到达那里。
在这里,你需要与众不同。但这有什么不同?这是一个间隔,正如在最受欢迎的答案中所提到的。问题是如何获取它。您可以不显式调用diff()方法,而是按开始日期和结束日期创建一个间隔,即按日期范围:
$startDate = '2007-03-24';
$endDate = '2009-06-26';
$range = new FromRange(new ISO8601DateTime($startDate), new ISO8601DateTime($endDate));
所有诸如闰年之类的复杂问题都已经解决了。现在,当您有一个固定开始日期时间的间隔时,您可以获得一个人类可读的版本:
var_dump((new HumanReadable($range))->value());
它输出的正是你所需要的。
如果您需要一些自定义格式,这也不是问题。您可以使用ISO8601格式化类,该类接受具有六个参数的调用:年、月、日、小时、分钟和秒:
(new ISO8601Formatted(
new FromRange(
new ISO8601DateTime('2017-07-03T14:27:39+00:00'),
new ISO8601DateTime('2018-07-05T14:27:39.235487+00:00')
),
function (int $years, int $months, int $days, int $hours, int $minutes, int $seconds) {
return $years >= 1 ? 'More than a year' : 'Less than a year';
}
))
->value();
它的产量超过一年。
有关此方法的更多信息,请查看快速入门条目。
DateInterval很好,但它有几个注意事项:
仅适用于PHP 5.3+(但这真的不再是一个好借口)仅支持年、月、日、小时、分钟和秒(无周)它计算上述所有+天的差异(你不能只计算月的差异)
为了克服这个问题,我编写了以下代码(由@enobrev答案改进而来):
function date_dif($since, $until, $keys = 'year|month|week|day|hour|minute|second')
{
$date = array_map('strtotime', array($since, $until));
if ((count($date = array_filter($date, 'is_int')) == 2) && (sort($date) === true))
{
$result = array_fill_keys(explode('|', $keys), 0);
foreach (preg_grep('~^(?:year|month)~i', $result) as $key => $value)
{
while ($date[1] >= strtotime(sprintf('+%u %s', $value + 1, $key), $date[0]))
{
++$value;
}
$date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
}
foreach (preg_grep('~^(?:year|month)~i', $result, PREG_GREP_INVERT) as $key => $value)
{
if (($value = intval(abs($date[0] - $date[1]) / strtotime(sprintf('%u %s', 1, $key), 0))) > 0)
{
$date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
}
}
return $result;
}
return false;
}
它运行两个循环;第一个算法通过暴力强制处理相对间隔(年和月),第二个算法通过简单的算法计算额外的绝对间隔(因此速度更快):
echo humanize(date_dif('2007-03-24', '2009-07-31', 'second')); // 74300400 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'minute|second')); // 1238400 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'hour|minute|second')); // 20640 hours, 0 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|day')); // 2 years, 129 days
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week')); // 2 years, 18 weeks
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week|day')); // 2 years, 18 weeks, 3 days
echo humanize(date_dif('2007-03-24', '2009-07-31')); // 2 years, 4 months, 1 week, 0 days, 0 hours, 0 minutes, 0 seconds
function humanize($array)
{
$result = array();
foreach ($array as $key => $value)
{
$result[$key] = $value . ' ' . $key;
if ($value != 1)
{
$result[$key] .= 's';
}
}
return implode(', ', $result);
}
我不知道你是否在使用PHP框架,但很多PHP框架都有日期/时间库和助手来帮助你避免重新发明轮子。
例如,CodeIgniter具有timespan()函数。只需输入两个Unix时间戳,就会自动生成如下结果:
1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes
http://codeigniter.com/user_guide/helpers/date_helper.html