How to calculate the time of each year between two dates?

Asked

Viewed 1,614 times

10

I need to take two dates and calculate the time period each year in isolation. For example: between dates 12/06/2012 and 12/06/2017 the correct exit would be:

2012 = 5 meses e 12 dias
2013 = 12 meses
2014 = 12 meses
2015 = 12 meses
2016 = 12 meses
2017 = 5 meses e 12 dias

To find the total time between two dates I do so:

$inicio = strtotime(12-01-2012); // transformando em time
$fim = strtotime(12-06-2017); // transformando em time
$intervalo = $fim - $inicio;

And then just convert and stuff:

$dias = floor($intervalo / (60 * 60 * 24));

But then to take the period of each year alone I am not able to imagine how to do it. I thought of comparing the dates, and then creating for each year a different calculation (repeating everything...), but there must be a simpler way... Any idea?

  • but from what I understand you only need to calculate the period of the first and last year, the others will be all 12 months, no?

  • if it is in days you have to calculate all periods

  • But by what he presented as correct output would be in months, so it does not matter if a month had 28 or 31 days, closed is month and a year 12 months

  • 1

    has waste in days

  • But only in the first and last, so I would only need the 12-01-2012 - 01-01-2012 and of 12-06-2017 - 01-01-2017 the others would be 12 full months with no residue

  • 1

    this exit for 2012 is not right, 2012 = 5 months and 12 days, see that from JULY to the end of the year are already 6 months and still have the days of June

  • I don’t know if you could use some lib, but this would help you a lot: https://github.com/briannesbitt/Carbon

  • 2

    Related: https://answall.com/q/70473/132

Show 3 more comments

2 answers

7


example - ideone

$date1 = "12/06/2012";
$date1 = str_replace("/", "-", $date1);
// data americana
$dateInicio = date('Y-m-d', strtotime($date1));

$date2 = "12/06/2017";
$date2 = str_replace("/", "-", $date2);
// data americana
$dateFim =  date('Y-m-d', strtotime($date2));

$time1=strtotime($date1);
// ano data inicial
$year1=date("Y",$time1);

$time2=strtotime($date2);
// ano data final
$year2=date("Y",$time2);

$difAno=$year2-$year1;
// se a diferença em anos for maior que 0 calculamos ano inicial e final
if ($difAno>0){
    // para ano inicial
    $fim = ($year1."-12-31");
    $datetime1 = new DateTime($dateInicio);
    $datetime2 = new DateTime($fim);
    $interval = $datetime1->diff($datetime2);
    echo "Ano: ".($year1)." - ";
    echo $interval->format('%m Meses %d dias');

    echo "<br>";

    // para ano final
    $inicio = ($year2."-01-01");
    $datetime1 = new DateTime($inicio);
    $datetime2 = new DateTime($dateFim);
    $interval = $datetime2->diff($datetime1);
    echo "Ano: ".($year2)." - ";
    echo $interval->format('%m Meses %d dias');

    echo "<br>";

}

// se a diferença entre os anos for maior que 1 fazemos um loop para calcular os demais
if ($difAno>1){
    for ($x = 1; $x <= $difAno-1; $x++) {

        echo "Ano: ".($year1+$x)." - ";
        echo date("z", mktime(0,0,0,12,31,($year1+$x))) + 1;
        echo " = 12 meses <br>";

    }
}
  • If we use this format of dd-mm-yyyy we will have errors, so we use the function date() which returns PHP dates in the format you want. date()

  • $interval->format - Formats a range.

The "Unix Era" began on January 1, 1970, and thanks to it, we can perform precise calculations of date. The function mktime() returns the total of seconds that have passed since the beginning of the Unix Age. The function date() can format dates based on the Unix era!

As the questioner comments

é que preciso incluir o dia final

simply include in the code the following line

$dateFim = date('Y-m-d', strtotime($dateFim. ' + 1 days'));

Then we will have as a result in the ideone

    $dateFim ="";

    $date1 = "12/06/2012";
    $date1 = str_replace("/", "-", $date1);
    // data americana
    $dateInicio = date('Y-m-d', strtotime($date1));

    $date2 = "12/06/2017";
    $date2 = str_replace("/", "-", $date2);
    // data americana
    $dateFim =  date('Y-m-d', strtotime($date2));
    $dateFim = date('Y-m-d', strtotime($dateFim. ' + 1 days'));

    $time1=strtotime($date1);
    // ano data inicial
    $year1=date("Y",$time1);

    $time2=strtotime($date2);
    // ano data final
    $year2=date("Y",$time2);

    $difAno=$year2-$year1;
    // se a diferença em anos for maior que 0 calculamos ano inicial e final
    if ($difAno>0){
        // para ano inicial
        $fim = ($year1."-12-31");
        $datetime1 = new DateTime($dateInicio);
        $datetime2 = new DateTime($fim);
        $interval = $datetime1->diff($datetime2);
        echo "Ano: ".($year1)." - ";
        echo $interval->format('%m Meses %d dias');

        echo "<br>";

        // para ano final
        $inicio = ($year2."-01-01");
        $datetime1 = new DateTime($inicio);
        $datetime2 = new DateTime($dateFim);
        $interval = $datetime2->diff($datetime1);
        echo "Ano: ".($year2)." - ";
        echo $interval->format('%m Meses %d dias');

        echo "<br>";

    }

    // se a diferença entre os anos for maior que 1 fazemos um loop para calcular os demais
    if ($difAno>1){
        for ($x = 1; $x <= $difAno-1; $x++) {

            echo "Ano: ".($year1+$x)." - ";
            echo date("z", mktime(0,0,0,12,31,($year1+$x))) + 1;
            echo " = 12 meses <br>";

        }
    }
  • I think that’s right Leo! It was really cool, I’ll test better tomorrow, but for now it’s my +1. Thanks anyway!

  • 1

    I made a small correction in for ($x = 1; $x <= $difAno-1; $x++) {.. so it does not iterate the last year it had been previously calculated

  • So, I did some tests here and it got really good, I’m still modifying some things and testing, but I’m already marking as solved here. I just made a small adjustment on the final date, because it has to pick from the beginning of the year until the final date, so it was like this $fim = ($year2."-01-01");. It is missing a day in the result ( gives 5 months and 11 days, and I wanted to include the final day), but now are just a few details... worth even, I’ll shipar a reward when give the minimum time... Hugs.

  • @gustavox calculator online from 01-01-2017 to 12-06-2017 gives 05 and 11 see http://pt.calcuworld.com/calendarios/calculara-de-tempo-entre-duas-dates/

  • Hehehe, big fool in the final period, I edited the answer // for final year

  • So Leo, about the 11 days, is that I need to include the final day, so following this answer from @rray did $datetime->add(new DateInterval('P1D')); and beauty. The date itself is 'wrong', but as I use it only for this calculation so there is no problem, the important thing is the result... Thank you very much.

  • 1

    @gustavox edited the answer adding 1 day at the end date

Show 2 more comments

2

Good from what I understand you would need to calculate only the first and last year because the others would be wasted since the result is predicted.

But if you insist, play the years in an array then run a foreach with the calculation, I did not test if its calculation is right but assuming that it is I think the logic is more or less this:

// Faz uma função para preencher o array com os anos entre o menor e o maior.. 
$anos = array(02-06-2012,01-01-2013,01-01-2014,01-01-2015,01-01-2016,01-01-2017,12-06-2017)

// Outra função pra atribuir o ano do menor ao inicio
$inicio = strtotime(01-01-2012);

foreach($anos as $ano){
    $fim = strtotime($ano);
    $intervalo = $fim - $inicio;
    //Aqui não sei se quer imprimir ou oq, mas coloca um array pra guardar ou imprime
    $dias = floor($intervalo / (60 * 60 * 24)); 
    $inicio = $fim;
}
  • 1

    Matthew, it’s not working, the results are always 0 for echo $dias, I think because you’re using the date in the dd/mm/yyyy pattern but you helped clear the ideas here, it’s mine +1. Thanks.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.