Karem
Karem

Reputation: 18103

Calculate days in months between two dates with PHP

I have a period with startdate of 2016-12-26 and end date 2017-03-04.

Now I would like to find out how many days in each months there is, from a given period. Expected output from the above period dates (array):

2016-12: 5
2017-01: 31
2017-02: 28
2017-03: 4

How can I accomplish this cleanest way? I have tried to:

  1. first looking at the period_start, get the days = 26 and
  2. find out the start/end dates of the months between 2016-12 and 2017-03, to then calculate the days here (31 respectively 28 in february)
  3. then finally calculating the 4 days in 2017-03.

But is there any cleaner/better way?

Upvotes: 2

Views: 1087

Answers (5)

Michał Chwedkowski
Michał Chwedkowski

Reputation: 1

i used Carbon (https://carbon.nesbot.com/docs/) but you can do it with any other time lib.

$startDate = Carbon::createFromFormat('!Y-m-d', '2017-01-11');;
$endDate = Carbon::createFromFormat('!Y-m-d', '2018-11-13');;

$diffInMonths = $endDate->diffInMonths($startDate);

for ($i = 0; $i <= $diffInMonths; $i++) {
    $start = $i == 0 ? $startDate->copy()->addMonth($i) : $startDate->copy()->addMonth($i)->firstOfMonth();
    $end = $diffInMonths == $i ? $endDate->copy() : $start->copy()->endOfMonth();

    echo $end->format('Y-m') . ' ' . ($end->diffInDays($start) + 1) . PHP_EOL;
}

Upvotes: 0

Niklesh Raut
Niklesh Raut

Reputation: 34914

This is long but easy to understand that how to achieve you your goal

<?php
  function getMonthDays($start,$end){
    if($start < $end){
      $start_time = strtotime($start);
      $last_day_of_start = strtotime(date("Y-m-t",$start_time));
      $start_month_days = ($last_day_of_start - $start_time)/(60*60*24);
      echo date("Y-m",$start_time).": ".$start_month_days."\n";
      $days = "";
      $start = date("Y-m-d", strtotime("+1 month", $start_time));
      $start_time = strtotime($start);
      while($start < $end){
        $month = date("m",$start_time);
        $year = date("Y",$start_time);
        $days = date('t', mktime(0, 0, 0, $month, 1, $year));
        echo date("Y-m",$start_time).": ".$days."\n";
        $start = date("Y-m-d", strtotime("+1 month", $start_time));
        $start_time = strtotime($start);
      }
      echo date("Y-m",strtotime($end)).": ".date("d",strtotime($end))."\n";

    }else{
      echo "Wrong Input";
    }
  }
  getMonthDays('2016-12-26','2017-03-04');
?>

live demo : https://eval.in/781724

Function returns array : https://eval.in/781741

Upvotes: 1

lazyCoder
lazyCoder

Reputation: 2561

@Karem hope this logic will help you, this is working case for all your conditions please try this below one:

<?php
$startDate = '2016-12-26';
$endDate = '2017-03-04';
$varDate = $startDate;
while($varDate < $endDate){
    $d = date('d', strtotime($varDate));
    $Y = date('Y', strtotime($varDate));
    $m = date('m', strtotime($varDate));
    $days = cal_days_in_month(CAL_GREGORIAN,$m,$Y);
    $time = strtotime($varDate);
    if($varDate == $startDate){
        $time = strtotime(date('Y-m-01', $time));
        $days = $days - $d;
    }
    else if(date("Y-m", strtotime($varDate)) == date("Y-m", strtotime($endDate))){
        $days = date("j", strtotime($endDate));
    }
    echo date('Y-m', strtotime($varDate)). ": ".$days."<br>";
    $varDate = date('Y-m-d', strtotime("+1 month", $time));
}

Upvotes: 1

Qirel
Qirel

Reputation: 26450

This can be achieved easily using the DateTime class. Create the objects, and use DateTime::diff() on them, then use the days property.

$start = new DateTime("2016-12-26");
$end = new DateTime("2017-03-04");

echo $start->diff($end)->days; // Output: 68

Live demo

Upvotes: 2

Gopi Chand
Gopi Chand

Reputation: 174

<?php
$d1 = strtotime('2016-12-26');
$d2 = strtotime('2017-03-04');
echo floor(($d2 - $d1)/(60*60*24));
?>

Upvotes: 0

Related Questions