2016-04-19 12 views
0

私は以前の日付を送信し、それよりも早い日付と今日の間の期間を数十日短縮します。私は正確に以下のようになるように結果を必要14/01/2016datetime:月を10日間に分割

例:

  • 2016年1月11日2016年1月20から
  • 2016年1月21日2016年1月31日
  • 01年2月20日~2010年2月10日
  • 2016年2月11日2016年3月31に2016年3月
  • 2016年3月21日20 2016年3月
  • 2016年3月11日〜10 2016年2月
  • 2016年3月1日〜29 2016年2月
  • 2016年2月21日〜20
  • 2016年4月10日に
  • 2016年4月1日に
  • 2016年4月11日〜20 2016年4月

ここに私のコード:

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; 
} 
+0

このようにすることを嫌う必要があります。次回は 'DateTime()'を使います。 *ずっと簡単。 –

答えて

1

Datetimeはこのタイプの問題をうまく解決するPHPのダーリンクラスです。 ここでは、DATETIMEオブジェクトとして関数に開始日付を渡し、関数はリストタグのスタックをスローします。

ループでは、最初にジャンプを行うために10日を追加し、次にオーバーラップを避けるために1つを追加することによって、startDayを修正します。 あなたが最後startDayから(10日少ないし)の期間で最終行をしたい場合は、のようなものを追加することができ、今日まで:ループ

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; 
} 

後、私は上記より変更

$return .= '<li>From '.$startDay->format('d M Y').' to '.$today->format('d M Y').'</li>'; 

<?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"; 

?> 
+0

このコードのしくみを説明してください。それともどのように問題を解決するのか? –

+0

を見てくださいhttps://eval.in/556396 – infotech

+0

https://eval.in/556397 私は明示的に(コードとテキストで)、この関数はdatetimeオブジェクトと共に最初のパラメータとして使用されると述べています。 関数の最初の行を調べてください - 今は見えますか? – Max

0

DateTimeを使用してこの機能を参照してください:

012あなたが記述を正確に何をすべきかの一般的なソリューション
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 
) 

我々が最初に作成され、1日($cur)上でのみ動作します渡された議論から;配列[1,11,21,21]を使用して、元の日の10で切り捨て除算してキーを選択します(あなたの例では、(14-1)/ 10 = 1.3、丸められた1、すなわち[1,11,21,21]の11)。これは、の31日目のの例外を解決する簡単な方法です。

$cur日付が今日の日付よりも大きくなるまでループを実行します。キーと値の開始部分を作成し、$curを9日追加するか、先月の日付を選択して、返された配列の完全なキーと値を作成します。各ループの最後に、$curを1日増分します。

関連する問題