我正在处理的事情要么发生在一个单一的一天(前。5/20)或多天(例如。8/25、8/26、8/27、9/3)。
例如,考虑到在8/25、8/26、8/27和9/3期间举行的为期4天的活动,我想重复如下:
Aug 25-27, Sep 3我想要密码:
这很容易通过使用date()格式的单日事件来完成,但是在必要时可以使用多个日期智能地生成这样的格式吗?
发布于 2021-10-08 22:12:01
我创建了一个函数,它应该基于一个DateTime对象数组输出所需的字符串。我在函数中放置了一些内联注释,以指示在给定时间发生了什么。
function produceDateString(array $dates): string
{
// sort the dates
sort($dates);
// create an array of arrays that contain ranges of consecutive days
$ranges = [];
$currentRange = [];
foreach ($dates as $date) {
if(empty($currentRange) || consecutive(end($currentRange), $date)) {
$currentRange[] = $date;
} else {
$ranges[] = $currentRange;
$currentRange = [$date];
}
}
$ranges[] = $currentRange;
// create the output string
$output = '';
$previous = null;
foreach ($ranges as $range) {
// add a comma between each range
if (!empty($output)) {
$output .= ', ';
}
// the long format should be used on the first occurrence of the loop
// or when the month of first date in the range doesn't match
// the month of the last date in the previous range
$format = $previous === null || end($previous)->format('m') !== reset($range)->format('m')
? 'M. j'
: 'j';
// the output differes when there are 1 or multiple dates in a range
if (count($range) > 1) {
// the output differs when the end and start are in the sane month
$output .= sameMonth(reset($range), end($range))
? reset($range)->format($format).'-'.end($range)->format('j')
: reset($range)->format('M. j').'-'.end($range)->format('M. j');
} else {
$output .= reset($range)->format($format);
}
$previous = $range;
}
return $output;
}
function consecutive(DateTime $t1, DateTime $t2): bool
{
$t1->setTime(0, 0, 0, 0);
$t2->setTime(0, 0, 0, 0);
return(abs($t2->getTimestamp() - $t1->getTimestamp()) < 87000);
}
function sameMonth(DateTime $t1, DateTime $t2): bool
{
return $t1->format('Y-m') === $t2->format('Y-m');
}我制作了一个小3v4l来向您展示它是如何准确地工作的。不要犹豫,如果你可能有任何问题,这是如何运作。
https://stackoverflow.com/questions/68926248
复制相似问题