我需要显示如下日期范围:
我提供了作为PHP日期对象的开始日期和结束日期。有没有办法可以解析那些用PHP输出的东西?
编辑:我认为你们误解了我的目标。
我有一个WordPress事件插件,可以输出开始日期和结束日期。如果活动的开始日期为2015年5月4日,结束日期为2015年5月7日,我需要显示:
<h4>Event Title</h4>
<p>When: <time>May 4-7, 2015</time></p>
我不需要在给定日期之间显示每个日期;这对我来说很容易理解。
编辑2:好的,只是为了确保我完全清楚:
我使用Tri.be Events插件允许用户创建活动日历。在这个WordPress网站的首页上,我需要显示即将发生的事件列表。每个事件应该像这样输出:
此事件应按如下方式输出:
<article>
<h4><a href="/path/to/event/">Systematic Implementation of Advance Care Planning in a Diverse City</a></h4>
<p>
<a href="/path/to/event/">
Aging in America Conference - Chicago, IL<br />
<time datetime="2015-03-23">March 23-27, 2015</time>
</a>
</p>
</article>
我遇到问题的是<time>
元素。下面的答案似乎表明我想以这种格式输出时间:
<time datetime="2015-03-23">March 23, 2015 - March 27, 2015</time>
这是不正确的。如果那样的情况下,我可以轻松地自己输出这个。正确的格式是:
<time datetime="2015-03-23">March 23-27, 2015</time>
因此,问题是:&#34;如何将两个日期缩小到一个日期范围?&#34;
答案 0 :(得分:1)
编辑2:
我已使用某种日期格式更新了该功能。
输出将是:
活动标题
时间:2010年2月28日 - 2010年3月2日
活动标题
时间:2010年3月4日 - 2010年3月5日
活动标题
时间:2010年12月31日 - 2011年1月5日
修改强>
我发现了这个(通过搜索) - &gt; Check for consecutive dates within a set and return as range
以下代码不是我的。这是来自@Darragh
的旧帖子我对代码做了一些小修改以适应OP的问题。
// assuming a chronologically
// ordered array of DateTime objects
$dates = array(
new DateTime('2010-02-28'),
new DateTime('2010-03-01'),
new DateTime('2010-03-02'),
new DateTime('2010-03-04'),
new DateTime('2010-03-05'),
new DateTime('2010-12-31'),
new DateTime('2011-01-01'),
new DateTime('2011-01-02'),
new DateTime('2011-01-03'),
new DateTime('2011-01-04'),
new DateTime('2011-01-05'),
);
// process the array
$lastDate = null;
$ranges = array();
$currentRange = array();
foreach ($dates as $date) {
if (null === $lastDate) {
$currentRange[] = $date;
} else {
// get the DateInterval object
$interval = $date->diff($lastDate);
// DateInterval has properties for
// days, weeks. months etc. You should
// implement some more robust conditions here to
// make sure all you're not getting false matches
// for diffs like a month and a day, a year and
// a day and so on...
if ($interval->days === 1) {
// add this date to the current range
$currentRange[] = $date;
} else {
// store the old range and start anew
$ranges[] = $currentRange;
$currentRange = array($date);
}
}
// end of iteration...
// this date is now the last date
$lastDate = $date;
}
// messy...
$ranges[] = $currentRange;
// print dates
foreach ($ranges as $range) {
// there'll always be one array element, so
// shift that off and create a string from the date object
$startDate = array_shift($range);
$str = "<h4>Event title</h4>";
$str .= "<p>When: ";
$str .= "<time>";
$str .= sprintf('%s', $startDate->format('M j, Y'));
// if there are still elements in $range
// then this is a range. pop off the last
// element, do the same as above and concatenate
if (count($range)) {
$endDate = array_pop($range);
$str .= sprintf(' - %s', $endDate->format('M j, Y'));
$str .= "</time></p>";
}
echo "<p>$str</p>";
}
旧答案(基于原始问题)。
$start_date = new DateTime( '2015-05-01' );
$end_date = new DateTime( '2015-05-04' );
$end_date = $end_date->modify( '+1 day' );
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($start_date, $interval ,$end_date);
foreach($daterange as $date){
echo $date->format("M d, Y") . "<br>";
}
// Output
// May 01, 2015
// May 02, 2015
// May 03, 2015
// May 04, 2015
答案 1 :(得分:1)
<article>
<h4><a href="/path/to/event/">Systematic Implementation of Advance Care Planning in a Diverse City</a></h4>
<p>
<a href="/path/to/event/">
Aging in America Conference - Chicago, IL<br />
<time datetime="2015-03-23/2015-03-27">March 23–27 2015</time>
</a>
</p>
</article>
修改强>
使用上面的PHP代码完成示例。
输出
2015年3月23日 - 2015年3月27日
// assuming a chronologically
// ordered array of DateTime objects
$dates = array(
new DateTime('2015-03-23'),
new DateTime('2015-03-24'),
new DateTime('2015-03-25'),
new DateTime('2015-03-26'),
new DateTime('2015-03-27')
);
// process the array
$lastDate = null;
$ranges = array();
$currentRange = array();
foreach ($dates as $date) {
if (null === $lastDate) {
$currentRange[] = $date;
} else {
// get the DateInterval object
$interval = $date->diff($lastDate);
// DateInterval has properties for
// days, weeks. months etc. You should
// implement some more robust conditions here to
// make sure all you're not getting false matches
// for diffs like a month and a day, a year and
// a day and so on...
if ($interval->days === 1) {
// add this date to the current range
$currentRange[] = $date;
} else {
// store the old range and start anew
$ranges[] = $currentRange;
$currentRange = array($date);
}
}
// end of iteration...
// this date is now the last date
$lastDate = $date;
}
// messy...
$ranges[] = $currentRange;
// print dates
foreach ($ranges as $range) {
// there'll always be one array element, so
// shift that off and create a string from the date object
$startDate = array_shift($range);
$str = "<h4>Event title</h4>";
$str .= "<p>When: ";
$str .= "<time>";
$str .= sprintf('%s', $startDate->format('M j, Y'));
// if there are still elements in $range
// then this is a range. pop off the last
// element, do the same as above and concatenate
if (count($range)) {
$endDate = array_pop($range);
$str .= sprintf(' - %s', $endDate->format('M j, Y'));
$str .= "</time></p>";
}
}
echo "<time datetime=".$startDate->format('M j, Y')."/".$endDate->format('M j, Y').">".$startDate->format('M j, Y')."–".$endDate->format('M j, Y')."</time>";
//OUTPUT
// Mar 23, 2015–Mar 27, 2015
答案 2 :(得分:0)
这是最简单的解决方案:
$dtStart = new DateTime('2015-05-05');
$dtEnd = new DateTime('2015-05-07');
while ($dtStart <= $dtEnd) {
echo $dtStart->format('Y-m-d') . "\n";
$dtStart->modify('+1 day');
}
// Output:
// 2015-05-05
// 2015-05-06
// 2015-05-07
$dtStart = new DateTime('2015-12-30');
$dtEnd = new DateTime('2016-01-01');
while ($dtStart <= $dtEnd) {
echo $dtStart->format('Y-m-d') . "\n";
$dtStart->modify('+1 day');
}
// Output:
// 2015-12-30
// 2015-12-31
// 2016-01-01