【问题标题】:php split a date range into 2 separate rangesphp 将日期范围拆分为 2 个单独的范围
【发布时间】:2013-11-15 09:14:56
【问题描述】:

我想知道如果满足某些特定条件,是否可以将给定日期范围拆分为 2 个单独的日期范围?

我正在构建一个假期预订系统,如果假期预订超过 2 年,我需要拆分日期。示例:

start date: 22-12-2013
end date: 04-01-2014

对于上面的日期,我想将它们分成 2 个日期范围,所以我最终会得到这样的结果:

start date: 22-12-2013
end date: 31-12-2013

然后:

start date: 01-01-2014
end date: 04-01-2014

这可能吗?如果是这样,有人可以指出我需要在谷歌中搜索的正确方向吗?

【问题讨论】:

  • 所以您需要从给定的日期范围中排除某些日期?
  • 不,基本上当日期范围达到某个日期时(在上面的示例 31-12-2013 中)我需要该日期范围结束。然后使用剩余日期创建另一个新日期范围。这有意义吗?
  • 用月份分割日期还是什么?
  • 年底

标签: php date split


【解决方案1】:

如果你想分割更多的月份,你可以使用这个功能:

function getMonthRanges($start, $end) {
    $timeStart = strtotime($start);
    $timeEnd   = strtotime($end);
    $out       = [];

    $milestones[] = $timeStart;
    $timeEndMonth = strtotime('first day of next month midnight', $timeStart);
    while ($timeEndMonth < $timeEnd) {
        $milestones[] = $timeEndMonth;
        $timeEndMonth = strtotime('+1 month', $timeEndMonth);
    }
    $milestones[] = $timeEnd;

    $count = count($milestones);
    for ($i = 1; $i < $count; $i++) {
        $out[] = [
            'start' => $milestones[$i - 1], // Here you can apply your formatting (like "date('Y-m-d H:i:s', $milestones[$i-1])") if you don't won't want just timestamp
            'end'   => $milestones[$i] - 1
        ];
    }

    return $out;
}

使用:

$result = getMonthRanges('15-11-2014', '19-11-2014');

结果:

Array
(
    [0] => Array
        (
            [start] => 1418594400
            [end] => 1420063199
        )

    [1] => Array
        (
            [start] => 1420063200
            [end] => 1422741599
        )

    [2] => Array
        (
            [start] => 1422741600
            [end] => 1425160799
        )

    [3] => Array
        (
            [start] => 1425160800
            [end] => 1426715999
        )

)

人类可读的结果:

array_walk_recursive($result, 'applyFormat');

function applyFormat(&$item)
{
    $item = date('Y-m-d H:i:s', $item);
}

Array
(
    [0] => Array
        (
            [start] => 2014-12-15 00:00:00
            [end] => 2014-12-31 23:59:59
        )

    [1] => Array
        (
            [start] => 2015-01-01 00:00:00
            [end] => 2015-01-31 23:59:59
        )

    [2] => Array
        (
            [start] => 2015-02-01 00:00:00
            [end] => 2015-02-28 23:59:59
        )

    [3] => Array
        (
            [start] => 2015-03-01 00:00:00
            [end] => 2015-03-18 23:59:59
        )

)

【讨论】:

    【解决方案2】:

    这是一种非常基本的方法,但我认为研究这样的事情可能会很有趣:

    $date1 = '22-12-2013';
    $date2 = "04-01-2014";
    
    function split_date($d1, $d2)
    {
        $start_year = substr($d1, -4);
        $end_year = substr($d2, -4);
    
        if($end_year > $start_year)
        {
        $d1 .= ' ['.date('d-m-Y',strtotime("last day of December".$start_year)).'] <br />';
        $d2 = '['.date('d-m-Y',strtotime("first day of January".$start_year)).'] ' . $d2;
        }
        return $d1 . $d2;
    }
    
    echo split_date($date1, $date2);
    

    http://www.php.net/manual/en/datetime.formats.relative.php

    【讨论】:

    • 感谢您的回答,当我尝试此操作时,会返回以下日期:22-12-2013 [01-01-1970] [01-01-1970] 04-01-2014跨度>
    • 嗯,可能与时区设置有关。只是为了测试,请尝试在开头添加date_default_timezone_set('America/Los_Angeles');
    • 有没有办法用这个函数单独回显新的日期范围?
    • 你的意思是return array($d1, $d2) 吗?
    【解决方案3】:

    感谢 ilpaijin,这是我想出的:

    $date1 = '22-12-2013';
    $date2 = "04-01-2014";
    
    function split_date($d1, $d2)
    {
        $start_year = substr($d1, -4);
        $end_year = substr($d2, -4);
    
        if($end_year > $start_year)
        {
        $d1 .= ' ['.date('d-m-Y',strtotime("31-12-".$start_year)).'] <br />';
        $d2 = '['.date('d-m-Y',strtotime("01-01-".$start_year."+1 years")).'] ' . $d2;
        }
        return $d1 . $d2;
    }
    
    echo split_date($date1, $date2);
    

    【讨论】:

      【解决方案4】:

      如果有人想将日期范围拆分为任意年,以下是实现。

      $date1 = '22-12-2013';
      $date2 = '04-01-2017';
      $dA = array();
      
      function split_date($d1, $d2, &$dA)
      {
          $start_year = substr($d1, -4);
          $end_year = substr($d2, -4);
      
          if($end_year > $start_year)
          {
          $dA[] = $d1;    
              $dA[] = date('d-m-Y',strtotime("31-12-".$start_year));
              if($end_year - $start_year == 1)
              {
                  $dA[] = date('d-m-Y',strtotime("01-01-".$start_year."+1 years"));
                  $dA[] = $d2;
              }else
              {
                  split_date(date('d-m-Y',strtotime("01-01-".$start_year."+1 years")), $d2, $dA);
              }
          }else if($end_year == $start_year)
          {
              $dA[] = $d1;
              $dA[] = $d2;
          }
      }
      
      split_date($date1, $date2, $dA);
      print_r($dA);
      
      
      //Answer
      
      Array
      (
      [0] => 22-12-2013
      [1] => 31-12-2013
      [2] => 01-01-2014
      [3] => 31-12-2014
      [4] => 01-01-2015
      [5] => 31-12-2015
      [6] => 01-01-2016
      [7] => 31-12-2016
      [8] => 01-01-2017
      [9] => 04-01-2017
      )
      

      【讨论】:

        【解决方案5】:

        非常简单的方法。您可以拆分日期范围支持所有类型的日期格式。

        function split_date($start_date,$end_date){
        
            while($start_date < $end_date){
                $end = date("Y-m-d", strtotime("Last day of December", strtotime($start_date)));
                if($end_date<$end){
                    $end = $end_date;
                }
                $dates[] =array('start'=>$start_date,'end'=>$end);
        
                $start_date =date("Y-m-d", strtotime("+1 day", strtotime($end)));
        
            }
            return $dates; 
        }
        $dates = split_date('2011-01-02','2013-01-04');
        print_r($dates);
        

        输出

        Array
        (
            [0] => Array
                (
                    [start] => 2011-01-02   //start date
                    [end] => 2011-12-31
                )
        
            [1] => Array
                (
                    [start] => 2012-01-01
                    [end] => 2012-12-31
                )
        
            [2] => Array
                (
                    [start] => 2013-01-01
                    [end] => 2013-01-04  //end date
                )
        
        )
        

        【讨论】:

        • 这几乎是最好的答案,但是当范围只是两年之间的一天时,它就会失败。示例: split_date('2021-12-31', '2022-01-01');在这种情况下,该函数只返回一个开始和结束日期为 2021-12-31 的数组。
        • 要更正错误,您应该将第二行更改为while($start_date &lt;= $end_date){
        猜你喜欢
        • 2020-02-28
        • 2013-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多