get startdate and enddate for current quarter php

前端 未结 19 1548
悲哀的现实
悲哀的现实 2020-12-29 10:58

I am trying to set a start date and end date by the quarter.

For example, I am working on a reporting system where i need to report data for quarter 1, quarter 2, qu

相关标签:
19条回答
  • 2020-12-29 11:23

    This was my solution.

    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);
    }
    
    0 讨论(0)
  • 2020-12-29 11:24

    A versatile version would be:

        $date = new DateTime(/* you may insert a date here, else its now */);
        //$date->modify('-3 months'); // you may want last quarter or any other modifcation
        $quarter = ceil($date->format('n')/3);
    
        $start = new DateTime();
        $start->setDate($date->format('Y'), (($quarter*3)-2), 1)->setTime(0, 0, 0, 0);
    
        $end = new DateTime();
        $end->setDate($date->format('Y'), ($quarter*3), 1);
        $end->setDate($date->format('Y'), ($quarter*3), $end->format('t'))->setTime(0, 0, 0, 0);
    
        echo $start->format('Y-m-d');
        echo $end->format('Y-m-d');
    

    this is simple yet effective. It let's you choose the input date and make relative adaptions with modify.

    0 讨论(0)
  • 2020-12-29 11:24

    You can simply this greatly using basic math.

    Each Month number minus 1 % 3 will tell how many months you are offset from the current quarter..

    /**
     * @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];
    }
    
    0 讨论(0)
  • 2020-12-29 11:25

    Try to use DateTime function. For your example, is look like:

    case 'this_month':
        $start_date = new DateTime('first day of this month');
        $end_date = new DateTime('last day of this month');
    break;
    case 'last_month':
        $start_date = new DateTime('first day of next month');
        $end_date = new DateTime('last day of next month');
    break;
    
    echo $start_date->format(DATE_FORMAT);
    echo $end_date->format(DATE_FORMAT);
    

    And if you want to get the first and last days of quarter, try to use:

     $start_date = new DateTime('first day of January');
     $end_date = new DateTime('last day of March');
    
     echo $start_date->format(DATE_FORMAT);
     echo $end_date->format(DATE_FORMAT);
    

    Or use function strtotime. Example with strtotime:

    $quarter_start = strtotime('first day of January');
    $quarter_end = strtotime('last day of March');
    
    echo date(DATE_FORMAT, $quarter_start);
    echo date(DATE_FORMAT, $quarter_end);
    
    0 讨论(0)
  • 2020-12-29 11:25

    Just wanted to point SynaTree's solution doesn't work for every last 3rd month in quarter.

    Here's a modified solution using DateTime.

    $now = new DateTimeImmutable();
    $offset = ($now->format('n') - 1) % 3;
    $start = $now->modify("first day of -{$offset} month midnight");
    $endExcluded = $start->modify("+3 month");
    $endIncluded = $start->modify("+3 month -1 second");
    

    $endExcluded works well when for DatePeriod loops, where the end date is excluded when time is 00:00:00.

    0 讨论(0)
  • 2020-12-29 11:27
    /**
    * 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,
        );
    }
    

    I develop this function to deal with quarter in any way: relative (this, previous, first, last) and fixed.

    Examples:

    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'
    

    Waiting this help someone ;)

    0 讨论(0)
提交回复
热议问题