当给出可以是后续日期的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
我已经打破了一段时间了;我没有进一步打破清单,订购它,让它独一无二,看看它们之间有多少天,并检查那里有多少元素。
但修复“漏洞”问题更难......我的解决方案不是防水......
有关如何解决此问题的任何想法?
答案 0 :(得分:0)
匆忙写下,所以请仔细检查,尤其是夏令时。主要想法是我们需要获得间隔:
<?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
答案 1 :(得分:0)
在@ kay27的帮助下介绍搜索间隔的想法,这就是我现在创建间隔列表的方法。
假设这是一个雄辩模型中的方法,在$this->data
中有一个数据列表。并使用Carbon生成漂亮的日期修饰符。
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;
}