devmyb
devmyb

Reputation: 375

Issue with DatePeriod Class Output

I'm using DatePeriod to get date difference between two dates but it creates issue when I need to get data Year based format. Following is my work

$start_date = '2016-08-29 21:47:33';
$end_date = '2018-04-28 17:30:55';

function getDateRange($start_date, $end_date, $type, $format = 'Y-m-d')
{
    $period = new DatePeriod(
        new DateTime($start_date),
        new DateInterval("P1{$type}"),
        new DateTime($end_date)
    );

    $dates = [];

    foreach($period as $dt)
    {
        $dates[] = $dt->format("$format");
    }

    return $dates;
}

print_r(getDateRange($start_date, $end_date, 'Y', 'Y'));

According to my function it should return

Array
(
    [0] => 2016
    [1] => 2017
    [2] => 2018
)

But its been outputting only two of them

Array
(
    [0] => 2016
    [1] => 2017
)

If I'm using output format with Month & Year i.e. M Y with interval of Month then it works fine output for that

print_r(getDateRange($start_date, $end_date, 'M', 'M Y'));

Array
(
    [0] => Aug 2016
    [1] => Sep 2016
    [2] => Oct 2016
    [3] => Nov 2016
    [4] => Dec 2016
    [5] => Jan 2017
    [6] => Mar 2017
    [7] => Apr 2017
    [8] => May 2017
    [9] => Jun 2017
    [10] => Jul 2017
    [11] => Aug 2017
    [12] => Sep 2017
    [13] => Oct 2017
    [14] => Nov 2017
    [15] => Dec 2017
    [16] => Jan 2018
    [17] => Feb 2018
    [18] => Mar 2018
    [19] => Apr 2018
)

Upvotes: 0

Views: 70

Answers (2)

Rahul
Rahul

Reputation: 18567

I have modified changes as per documentation link,

Here is the code,

function getDateRange($start_date, $end_date, $type, $format = 'Y-m-d')
{
    $start_date = date_create_from_format("Y-m-d H:i:s", $start_date);
    $end_date = date_create_from_format("Y-m-d H:i:s", $end_date);
    $endDateInt = new DateInterval( "P1Y" );
    $end_date->add( $endDateInt );
    $period = new DatePeriod(
        $start_date,
        new DateInterval("P1{$type}"),
        $end_date
    );
    $dates = [];
    
    foreach($period as $dt)
    {
        $dates[] = $dt->format("$format");
    }

    return $dates;
}
$start_date = '2016-08-29 21:47:33';
$end_date = '2018-04-28 17:30:55';
print_r(getDateRange($start_date, $end_date, 'Y', 'Y'));

Here is working link.

Upvotes: 2

ishegg
ishegg

Reputation: 9957

You can see the reason why in your second output. The last date goes only until April, and the first one is in August. So it's indeed not two full years, and your first result is correct. If you want to make it be the number of "years involved", without regard for actual difference, you could simulate this by setting the second date to the same day and month as the first one, if $type is Y:

<?php
$start_date = '2016-08-29 23:47:33';
$end_date = '2018-09-28 17:30:55';

function getDateRange($start_date, $end_date, $type, $format = 'Y-m-d')
{
    $start = new DateTime($start_date);
    $end = new DateTime($end_date);
    if ($type === "Y") {
        $start->setTime(0, 0, 0);
        $end->setDate($end->format("Y"), $start->format("m"), $start->format("d"));
        $end->setTime(0, 0, 1);
    }
    $period = new DatePeriod(
        $start,
        new DateInterval("P1{$type}"),
        $end
    );

    $dates = [];

    foreach($period as $dt)
    {
        $dates[] = $dt->format("$format");
    }

    return $dates;
}

print_r(getDateRange($start_date, $end_date, 'Y', 'Y'));

Demo

Upvotes: 2

Related Questions