получить startdate и enddate для текущего квартала php

Я пытаюсь установить дату начала и дату окончания в квартал.

например, я работаю над системой отчетности, где мне нужно сообщить данные за квартал 1, квартал 2, квартал 3 и квартал 4.

Первый Квартал-Январь-Март

Второй Квартал-Апрель-Июнь

Третий Квартал - Июль - Сентябрь!--2-->

Четверть Четвертого-Октябрь-Декабрь

У меня есть, например, некоторые случаи для текущего месяца и предыдущего месяц, как показано ниже.

   case 'this_month':
      $start_date = date(DATE_FORMAT, mktime(0, 0, 0, date("m"), 1, date("Y")));
      $end_date = date(DATE_FORMAT, mktime(0, 0, 0, date("m"), date("d"), date("Y")));
    break;
    case 'last_month':
      $start_date = date(DATE_FORMAT, mktime(0, 0, 0, date("m") - 1, 1, date("Y")));
      $end_date = date(DATE_FORMAT, mktime(0, 0, 0, date("m"), 0, date("Y")));
    break;

но теперь мне нужно добавить чехлы для этот и последний квартал и я не уверен, как это сделать, чтобы он отражал правильный диапазон кварталов.

Какие Идеи?

14 ответов


это this quarter.

 case 'this_quarter':

          $current_month = date('m');
          $current_year = date('Y');
          if($current_month>=1 && $current_month<=3)
          {
            $start_date = strtotime('1-January-'.$current_year);  // timestamp or 1-Januray 12:00:00 AM
            $end_date = strtotime('1-April-'.$current_year);  // timestamp or 1-April 12:00:00 AM means end of 31 March
          }
          else  if($current_month>=4 && $current_month<=6)
          {
            $start_date = strtotime('1-April-'.$current_year);  // timestamp or 1-April 12:00:00 AM
            $end_date = strtotime('1-July-'.$current_year);  // timestamp or 1-July 12:00:00 AM means end of 30 June
          }
          else  if($current_month>=7 && $current_month<=9)
          {
            $start_date = strtotime('1-July-'.$current_year);  // timestamp or 1-July 12:00:00 AM
            $end_date = strtotime('1-October-'.$current_year);  // timestamp or 1-October 12:00:00 AM means end of 30 September
          }
          else  if($current_month>=10 && $current_month<=12)
          {
            $start_date = strtotime('1-October-'.$current_year);  // timestamp or 1-October 12:00:00 AM
            $end_date = strtotime('1-January-'.($current_year+1));  // timestamp or 1-January Next year 12:00:00 AM means end of 31 December this year
          }



        break;

обновление : 2 и за last quarter

case 'last_quarter':

          $current_month = date('m');
          $current_year = date('Y');

          if($current_month>=1 && $current_month<=3)
          {
            $start_date = strtotime('1-October-'.($current_year-1));  // timestamp or 1-October Last Year 12:00:00 AM
            $end_date = strtotime('1-January-'.$current_year);  // // timestamp or 1-January  12:00:00 AM means end of 31 December Last year
          } 
          else if($current_month>=4 && $current_month<=6)
          {
            $start_date = strtotime('1-January-'.$current_year);  // timestamp or 1-Januray 12:00:00 AM
            $end_date = strtotime('1-April-'.$current_year);  // timestamp or 1-April 12:00:00 AM means end of 31 March
          }
          else  if($current_month>=7 && $current_month<=9)
          {
            $start_date = strtotime('1-April-'.$current_year);  // timestamp or 1-April 12:00:00 AM
            $end_date = strtotime('1-July-'.$current_year);  // timestamp or 1-July 12:00:00 AM means end of 30 June
          }
          else  if($current_month>=10 && $current_month<=12)
          {
            $start_date = strtotime('1-July-'.$current_year);  // timestamp or 1-July 12:00:00 AM
            $end_date = strtotime('1-October-'.$current_year);  // timestamp or 1-October 12:00:00 AM means end of 30 September
          }



        break;

/**
* Compute the start and end date of some fixed o relative quarter in a specific year.
* @param mixed $quarter  Integer from 1 to 4 or relative string value:
*                        'this', 'current', 'previous', 'first' or 'last'.
*                        'this' is equivalent to 'current'. Any other value
*                        will be ignored and instead current quarter will be used.
*                        Default value 'current'. Particulary, 'previous' value
*                        only make sense with current year so if you use it with
*                        other year like: get_dates_of_quarter('previous', 1990)
*                        the year will be ignored and instead the current year
*                        will be used.
* @param int $year       Year of the quarter. Any wrong value will be ignored and
*                        instead the current year will be used.
*                        Default value null (current year).
* @param string $format  String to format returned dates
* @return array          Array with two elements (keys): start and end date.
*/
public static function get_dates_of_quarter($quarter = 'current', $year = null, $format = null)
{
    if ( !is_int($year) ) {        
       $year = (new DateTime)->format('Y');
    }
    $current_quarter = ceil((new DateTime)->format('n') / 3);
    switch (  strtolower($quarter) ) {
    case 'this':
    case 'current':
       $quarter = ceil((new DateTime)->format('n') / 3);
       break;

    case 'previous':
       $year = (new DateTime)->format('Y');
       if ($current_quarter == 1) {
          $quarter = 4;
          $year--;
        } else {
          $quarter =  $current_quarter - 1;
        }
        break;

    case 'first':
        $quarter = 1;
        break;

    case 'last':
        $quarter = 4;
        break;

    default:
        $quarter = (!is_int($quarter) || $quarter < 1 || $quarter > 4) ? $current_quarter : $quarter;
        break;
    }
    if ( $quarter === 'this' ) {
        $quarter = ceil((new DateTime)->format('n') / 3);
    }
    $start = new DateTime($year.'-'.(3*$quarter-2).'-1 00:00:00');
    $end = new DateTime($year.'-'.(3*$quarter).'-'.($quarter == 1 || $quarter == 4 ? 31 : 30) .' 23:59:59');

    return array(
        'start' => $format ? $start->format($format) : $start,
        'end' => $format ? $end->format($format) : $end,
    );
}

Я разрабатываю эту функцию, чтобы иметь дело с кварталом любым способом: относительным (этот, предыдущий, первый, последний) и фиксированным.

примеры:

get_dates_of_quarter();
//return current quarter start and end dates

get_dates_of_quarter(2);
//return 2nd quarter start and end dates of current year

get_dates_of_quarter('first', 2010, 'Y-m-d');
//return start='2010-01-01' and end='2014-03-31'

get_dates_of_quarter('current', 2009, 'Y-m-d');
//Supposing today is '2014-08-22' (3rd quarter), this will return
//3rd quarter but of year 2009.
//return start='2009-07-01' and end='2009-09-30'

get_dates_of_quarter('previous');
//Supposing today is '2014-02-18' (1st quarter), this will return
//return start='2013-10-01' and end='2013-12-31'

ждем эту помощь кому-то ;)


о:

$offset = (date('n')%3)-1; // modulo ftw
$start = new DateTime("first day of -$offset month midnight");
$offset = 3-(date('n')%3); // modulo ftw again
$end = new DateTime("last day of +$offset month midnight");

простой код:

$current_quarter = ceil(date('n') / 3);
$first_date = date('Y-m-d', strtotime(date('Y') . '-' . (($current_quarter * 3) - 2) . '-1'));
$last_date = date('Y-m-t', strtotime(date('Y') . '-' . (($current_quarter * 3)) . '-1'));

некоторые ответы слишком сложны IMO

public function getStartOfQuarter()
{
     return date(sprintf('Y-%s-01', floor((date('n') - 1) / 3) * 3 + 1));
}

public function getEndOfQuarter()
{
    return date(sprintf('Y-%s-t', floor((date('n') + 2) / 3) * 3));
}

попробуйте использовать DateTime


это может быть намного проще, я думаю.

function get_this_quarter() {
    $current_month = date('m');
    $current_quarter_start = ceil($current_month/4)*3+1; // get the starting month of the current quarter
    $start_date = date("Y-m-d H:i:s", mktime(0, 0, 0, $current_quarter_start, 1, date('Y') ));
    $end_date = date("Y-m-d H:i:s", mktime(0, 0, 0, $current_quarter_start+3, 1, date('Y') ));
    // by adding or subtracting from $current_quarter_start within the mktime function you can get any quarter of any year you want.
    return array($start_date, $end_date);
}

это работает так же хорошо без всех операторов if и намного более гибко. Как упоминалось в комментариях в коде, вы можете легко изменить $current_quarter_variable в соответствии с вашими потребностями.

надеюсь, что это помогает!


простой пример:

define('DATE_FORMAT', 'Y-m-d');

function get_start_and_end_date($case) {
    $start = 'first day of ';
    $end = 'last day of ';

    if ($case == 'this_quarter') {
        $case = 'quarter_' . ceil((new DateTime)->format('n') / 3);
    }

    switch ($case) {
        case 'prev_month'    : $start .= 'previous month'; $end .= 'previous month'; break;
        default              :
        case 'this_month'    : $start .= 'this month';     $end .= 'this month';     break;
        case 'next_month'    : $start .= 'next month';     $end .= 'next month';     break;
        case 'first_quarter' :
        case 'quarter_1'     : $start .= 'January';        $end .= 'March';          break;
        case 'quarter_2'     : $start .= 'April';          $end .= 'June';           break;
        case 'quarter_3'     : $start .= 'July';           $end .= 'September';      break;
        case 'last_quarter'  :
        case 'quarter_4'     : $start .= 'October';        $end .= 'December';       break;
    }

    return [
        'start' => (new DateTime($start))->format(DATE_FORMAT),
        'end' => (new DateTime($end))->format(DATE_FORMAT),
    ];
}

демо


function getDates( $passedDate = '' ) {
    if( $passedDate == '' ) {
        $v = ceil( date( "m" ) / 3 );
        $y = date( "Y" );
    } else {
        $v = ceil( $month / 3 );
        $y = date( "Y", strtotime( $passedDate ) );
    }
    $y = date( "Y" );
    $m = ( $v * 3 ) - 2;
    $date = $y . '-' . $m . '-' . 01;
    $return['begin'] = date( "Y-m-d", strtotime(  $date ) );
    $return['end'] = date( "Y-m-t", strtotime( $return['begin'] . "+ 2 months"  ) );
    $return['version'] = $y . 'Q' . ceil( date( "m" ) / 4 );
    return $return;
}

эта функция будет возвращать начальную и конечную дату и квартал для текущей даты по умолчанию, однако, если вы хотите, чтобы он для конкретной даты просто пройти месяц к нему.


Это было мое решение.

function getCurrentQuarter($timestamp=false){
    if(!$timestamp)$timestamp=time();
    $day = date('n', $timestamp);
    $quarter = ceil($day/3);
    return $quarter;
}

function getPreviousQuarter($timestamp=false){
    if(!$timestamp)$timestamp=time();
    $quarter = getCurrentQuarter($timestamp) - 1;
    if($quarter < 0){
        $quarter = 4;
    }
    return $quarter;
}

function getNextQuarter($timestamp=false){
    if(!$timestamp)$timestamp=time();
    $quarter = getCurrentQuarter($timestamp) + 1;
    if($quarter > 4){
        $quarter = 0;
    }
    return $quarter;
}

function getFirstAndLastDayOfQuarter($quarter, $year=false){
    if(!$year)$year=date('Y');
    $startDate = new DateTime($year.'-'.($quarter*3-2).'-1');
    //Get first day of first month of next quarter
    $endMonth = $quarter*3+1;
    if($endMonth>12){
        $endMonth = 1;
        $year++;
    }
    $endDate = new DateTime($year.'-'.$endMonth.'-1');
    //Subtract 1 second to get last day of prior month
    $endDate->sub(new DateInterval('PT1S'));
    return array($startDate, $endDate);
}

вы можете просто это значительно использовать basic math.

каждый месяц число минус 1 % 3 покажет, сколько месяцев вы смещены от текущего квартала..

/**
 * @param DateTime $date
 * @return array
 */
function getQuarterRangeFromDate(DateTime $date)
{

    // Clone the date to avoid modifying your date in current context
    $quarter_start = clone($date);

    // Find the offset of months
    $months_offset = ($date->format('m') - 1) % 3;


    // Modify quarter date
    $quarter_start->modify(" - " . $months_offset . " month")
        ->modify("first day of this month");


    $quarter_end = clone($quarter_start);
    $quarter_end->modify("+ 3 month");

    return [$quarter_start, $quarter_end];
}

Я закончил с этим простым решением:

$curQuarter = ceil(date("m")/3);
$startDate = date("Y") . "-" . $curQuarter*3-2 . "-01";
$endDate = date("Y") . "-" . $curQuarter*3 . "-31";

(Да, некоторые месяцы не будут иметь 31 дней, но в моем случае это не имело значения)


$monthsFromStart = (date('n') - 1) % 3; // 0, 1, 2, 0, 1, 2, ...
$monthsToEnd = 2 - $monthsFromStart; // 2, 1, 0, 2, 1, 0, ...

$startDay = new DateTime("first day of -$monthsFromStart month midnight");
$endDay = new DateTime("last day of +$monthsToEnd month midnight");

более простой способ, чтобы получить начало/конец текущего квартала в сроки:

$qtr_start = date("Y-".(ceil(date("n")/3))."-01");

затем просто добавьте 3 месяца в правильном месте, чтобы получить конец:

$qtr_end = date("Y-".(ceil(date("n")/3)+3)."-01");

просто мои два цента.