格式化日期时间间隔,最小差异为

时间:2017-06-10 12:11:19

标签: php datetime date-difference

found这个非常好的PHP脚本可以将任何日期时间转换为相对字符串,例如:

'2013-05-01 00:22:35'  ->  '3 months ago'

这很酷,但我想"欺骗"该函数使得即使日期是20分钟,该函数返回1 hour ago而不是20 minutes ago。因此,我希望强制执行1小时的最小差异,即使差异小于该值。

供参考,这是功能。

function time_elapsed_string($datetime, $full = false) {
  $now = new DateTime;
  $ago = new DateTime($datetime);
  $diff = $now->diff($ago);

  $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';
}

我尝试了很多不同的东西,但没有真正有效。

如何执行最小差异1小时?

3 个答案:

答案 0 :(得分:1)

天:如果DateInterval对象是由DateTime :: diff()创建的,那么这是开始日期和结束日期之间的总天数。否则,天数将是假的。 http://php.net/manual/en/class.dateinterval.php

因为我们知道它不会是假的,所以只有在0时它才会被评估为假。

if($diff->days) {
    $diff->w = floor($diff->d / 7);
    $diff->d -= $diff->w * 7;
} else /* less than a day's difference */ if(!$diff->h && ($diff->i || $diff->s)) /* less than an hour's difference */ {
    $diff->h = 1;
    $diff->i = 0;
    $diff->s = 0;
}

答案 1 :(得分:1)

找出差异后,只需检查最大差异是否仅为几分钟或几秒。如果是这样,请返回所需的最少1小时。

// here is your foreach loop

// check if less than 1 hour, if so, return that
$keys = array_keys($string);
if ($keys[0] === 'i' || $keys[0] === 's') {
  return 'less than 1 hour ago';
}

Try it online!
我把时间贴在这个例子中。当你在1小时后查看它时,你将不得不将测试用例修改为UTC时间内不到1小时的DateTime。

测试案例。现在是UTC格式2017-06-10 12:45:00。

time_elapsed_string("2017-06-10 12:11:19"); // less than 1 hour ago
time_elapsed_string("2017-06-10 11:44:00"); // 1 hour ago
time_elapsed_string("2017-06-10 11:44:00", true); // 1 hour, 1 minute ago
time_elapsed_string("2017-06-09 11:45:00", true); // 1 day, 1 hour ago
time_elapsed_string("2017-06-09 11:45:00"); // 1 day ago

答案 2 :(得分:0)

我在原始代码中添加了一些改进。我还从您的函数中删除了full选项,因为我认为您不打算将它用于您的情况。如果我的内联评论无法解释我的过程,请询问。

代码:(Demo

function time_elapsed_string($datetime){
    $now=new DateTime;  // current datetime
    $ago=new DateTime($datetime);  // user datetime
    if($now<$ago){return "Unexpected future datetime value";}
    $diff=$now->diff($ago);  // datetime difference
    $diff->w=intval(floor($diff->d/7));  // add weeks to diff output
    $diff->d-=$diff->w*7;  // reduce days based on weeks calculation
    $units=[
        'y'=>'year',
        'm'=>'month',
        'w'=>'week',
        'd'=>'day',
        'h'=>'hour'
    ];
    $kept_diff=array_intersect_key((array)$diff,$units);  // omit unwanted elements of diff()'s output
    if(!max($kept_diff)){  // if y, m, w, d, & h all = 0, show default
        return 'default: 1 hour ago';  // inserted "default: " for demo.  Remove in production.
    }else{
        $diffs=array_filter(array_merge($units,$kept_diff)); // sort by $units order, then omit elements with 0 value
        return current($diffs).' '.$units[key($diffs)].(current($diffs)>1?'s':'').' ago'; // return highest unit data in plain English
    }
}
echo time_elapsed_string('2017-06-30 02:22:35');  // output: 3 weeks ago