我发送了一个较早的日期,它会返回从较早日期到今天的时间段,这些时间段缩短了几十天。
2016年1月14日示例
我需要结果如下:
- 2016年1月11日至2016年1日20日
- 2016年1月21日至2016年1日31日
- 2016年2月1日至2016年2月份10日
- 2016年2月11日至2016年2月份20日
- 2016年2月21日至2016年2月份29日
- 2016年3月1日至2016年3月份10日
- 2016年3月11日至2016年3月份20日
- 2016年3月21日至2016年3月份31日
- 2016年4月1日至2016年4月份10日
- 2016年4月11日至2016年4日20日
这里是我的代码:
function date_interval($startTime = false){
if( ! $startTime){
return array();
} else {
if(date('d',$startTime) < 10){
$actual = mktime(0, 0, 0, date('m',$startTime), 1, date('Y',$startTime));
} elseif(date('d',$startTime) < 20){
$actual = mktime(0, 0, 0, date('m',$startTime), 10, date('Y',$startTime));
} else {
$actual = mktime(0, 0, 0, date('m',$startTime), 20, date('Y',$startTime));
}
if(date('d',time()) < 10) {
$target = mktime(0, 0, 0, date('m',time()), 10, date('Y',time()));
} elseif(date('d',time()) < 20) {
$target = mktime(0, 0, 0, date('m',time()), 20, date('Y',time()));
} else {
$target = mktime(0, 0, 0, date('m',time())+1, 1, date('Y',time()));
}
$current = $actual;
$last = $actual;
while($current < $target) {
if(date('d',$current) < 10){
$current = mktime(0, 0, 0, date('m',$current), 10, date('Y',$current));
} elseif(date('d',$current) < 20){
$current = mktime(0, 0, 0, date('m',$current), 20, date('Y',$current));
} else {
$current = mktime(0, 0, 0, date('m',$current)+1, 1, date('Y',$current));
}
$dateTime[date("Y-m-d", $last) .'~'. date("Y-m-d", $current)] = date('d M Y',$last) . ' - ' . date('d M Y',$current));
$last = $current;
}
}
return $dateTime;
}
Datetime是php中的宠儿类,它很好地解决了这类问题。在这里,您将startdate作为DATETIME对象提供给函数,函数会抛出一堆列表标记。
在循环中,startDay首先通过增加10天来进行跳跃,然后增加一天来避免重叠。如果你想要最后一行,从上次开始到今天的时间段(不到十天),你可以添加这样的内容:
$return .= '<li>From '.$startDay->format('d M Y').' to '.$today->format('d M Y').'</li>';
环路后
function date_interval(DATETIME $startDay = NULL)
{
if( NULL == $startDay){
return array(); }
$return = '';
$today = new DATETIME('now');
while( $today->diff( $startDay )->format('%a%') > 10 )
{
$return .= '<li>From '.$startDay->format('d M Y').' to ';
$startDay->modify('+10 days');
$return .= $startDay->format('d M Y').'</li>
';
$startDay->modify('+1 day');
}
return $return;
}
我修改了上述更通用的解决方案,以实现您所描述的:
<?php
function date_interval(DATETIME $startDay = NULL)
{
if( NULL == $startDay){
return array(); }
$return = '';
$today = new DATETIME('now');
$startMonth = new DateTime('first day of '.$startDay->format('M Y') );
$firstRun = TRUE;
while( $today > $startDay )
{
$return .= '<li>From '.$startDay->format('d M Y').' to ';
if( $firstRun == TRUE ){
if( (int)$startDay->format('d') > 10 )
$startMonth->modify('+10 days');
if( (int)$startDay->format('d') > 20 )
$startMonth->modify('+10 days');
$startDay = $startMonth;
$firstRun = FALSE;
}
$lastOfMonth = new DateTime('last day of '.$startDay->format('M Y') );
if( $lastOfMonth->diff( $startDay )->format('%a%') > 10 )
$startDay->modify('+9 days');
else
$startDay = $lastOfMonth;
$return .= $startDay->format('d M Y').'</li>
';
$startDay->modify('+1 day');
}
return $return;
}
echo date_interval( date_create_from_format('Y-m-d','2016-01-21') )."'n";
?>
使用DateTime
:查看此函数
function date_interval( $start = Null )
{
if( !$start ) return array();
$cur = new DateTime( sprintf( '%s-%02d', $start->format('Y-m'), [1,11,21,21][ floor(($start->format('j')-1)/10) ] ) );
$end = new DateTime();
$retval = [];
while( $cur <= $end )
{
$key = $cur->format( 'Y-m-d~' );
$val = $cur->format( 'd M Y - ' );
if( $cur->format( 'j' ) > 20 ) $cur->modify( 'last day of this month' );
else $cur->modify( '+ 9 days' );
$retval[ $key.$cur->format( 'Y-m-d' ) ] = $val.$cur->format( 'd M Y' );
$cur->modify( '+ 1 days' );
}
return $retval;
}
这样称呼它:
$startDate = '14/01/2016';
$array = date_interval( DateTime::createFromFormat( 'd/m/Y', $startDate ) );
print_r( $array );
根据您的键/值模式,得到的数组是:
Array
(
[2016-01-11~2016-01-20] => 11 Jan 2016 - 20 Jan 2016
[2016-01-21~2016-01-31] => 21 Jan 2016 - 31 Jan 2016
[2016-02-01~2016-02-10] => 01 Feb 2016 - 10 Feb 2016
[2016-02-11~2016-02-20] => 11 Feb 2016 - 20 Feb 2016
[2016-02-21~2016-02-29] => 21 Feb 2016 - 29 Feb 2016
[2016-03-01~2016-03-10] => 01 Mar 2016 - 10 Mar 2016
[2016-03-11~2016-03-20] => 11 Mar 2016 - 20 Mar 2016
[2016-03-21~2016-03-31] => 21 Mar 2016 - 31 Mar 2016
[2016-04-01~2016-04-10] => 01 Apr 2016 - 10 Apr 2016
[2016-04-11~2016-04-20] => 11 Apr 2016 - 20 Apr 2016
[2016-04-21~2016-04-30] => 21 Apr 2016 - 30 Apr 2016
)
我们只对一个日期($cur
)进行操作,该日期最初是根据传递的参数创建的;我们使用数组[1,11,21,21]
设置月份的日期,并通过原始日期的四舍五入除以10来选择键(在您的示例中,(14-1)/10=1.3,四舍五五入为1,即[1,11,21,21]
数组中的11)。这是解决第31天异常的快速方法。
然后我们执行一个循环,直到$cur
日期大于今天日期:我们创建键和值的起始部分,我们修改$cur
添加它九天或选择上个月的日期,我们创建返回数组的完整键和值。在每个循环结束时,我们将$cur
增加1天。