当给定一个n个日期的列表时,可以是后续日期只是普通的随机日期;生成适当的人类可读字符串的最佳方法是什么。
我举个例子:
2016-02-13, 2016-02-14, 2016-02-15, 2016-02-16
应表示为:
feb 13th '16 - feb 16th '16
将日期转换为人类可读的对应项很容易;我对某种算法感兴趣,可以将日期数组减少到尽可能短的解决方案。
当列表包含"漏洞"时,事情开始变得困难:
2016-02-13, 2016-02-14, 2016-02-15, 2016-03-02, 2016-03-03
feb 13th '16 - feb 15th '16 & mar 2nd '16 - mar 3rd '16
我已经为此打破了一段时间;我没有进一步打破列表,排序它,让它独一无二,看看中间有多少天,然后检查一下有多少元素。
但是解决"漏洞"问题更难...而且我的解决方案不是水密的。
关于如何处理这个问题的任何想法?
写得很匆忙,所以请仔细检查,尤其是夏令时的情况。主要思想是我们需要获取间隔:
<?php
date_default_timezone_set('UTC');
$dates=explode(', ',
'2015-02-13, 2015-02-14, 2015-02-15, 2015-02-16, 2016-02-13, 2016-02-14, 2016-02-15, 2016-03-02, 2016-03-03');
$intervals = Array();
$t0 = -1;
$t = $t0;
if(count($dates))
foreach($dates as $d)
{
$t00 = strtotime("$d -1 day");
if($t != $t00)
{
if($t0 != -1)
{
if($t == $t0)
$intervals[]=date("M jS 'y",$t0);
else
$intervals[]=date("M jS 'y",$t0) . ' - ' . date("M jS 'y",$t);
}
$t = strtotime($d);
$t0 = $t;
}
else
$t = strtotime($d);
}
if ($t0 != $t)
$intervals[]=date("M jS 'y",$t0) . ' - ' . date("M jS 'y",$t);
echo join(" & ", $intervals);
结果:
Feb 13th '15 - Feb 16th '15 & Feb 13th '16 - Feb 15th '16 & Mar 2nd '16 - Mar 3rd '16
在@kay27的帮助下,引入了搜索间隔的想法,这就是我现在创建间隔列表的方式。假设这是一个雄辩模型中的方法,$this->data
.并使用碳来制作漂亮的日期修饰符。
public function fd($format = 'Y-m-d')
{
$dates = [];
$intervals = [];
foreach ($this->data as $d) {
$dates[] = 'Carbon::parse($d->datum);
}
// sort the dates..
// init
$i=0;
$t=0;
$peil = $dates[$i];
$intervals[$t] = [$peil];
// loop through the dates starting from 0+1, as we already
// 'processed' the first entry.
for ($i=1; $i < count($dates); $i++) {
// when not equal; then we will need to create a new inTerval,
// so we increase the index:
if ($peil != $dates[$i]->copy()->subDay()) {
$t++;
}
// adding the date to the appropriate interval.
$intervals[$t][] = $dates[$i];
// the reference date, as-in the last date added to the list.
$peil = $dates[$i];
}
// do some formatting on the intervals
return $intervals;
}