Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

End of month method doesn't consider leap year. #62

Open
takumi-dev opened this issue Jan 20, 2016 · 4 comments
Open

End of month method doesn't consider leap year. #62

takumi-dev opened this issue Jan 20, 2016 · 4 comments

Comments

@takumi-dev
Copy link
Contributor

Hi, I am working with this library for my product. It is awesome.
Now, I found an issue with leap year.

This is a test code.

$now = new \Moment\Moment('2016-01-31', 'Asia/Tokyo');
echo $now->subtractDays(1)->addDays(1)->startOf('day')->cloning()
->startOf('month')->addMonths(1)->setDay('30')->subtractMonths(1)->endOf('month')->format();
//It shows "2016-02-28T23:59:59+0000"
//expected is "2016-02-29T23:59:59+0000"

This will only happen when I set TimeZone at first.
If I didn't set TimeZone at first, it will not happen.

I used hack like this.

$now = new \Moment\Moment('2016-01-31', 'Asia/Tokyo');
echo $now->subtractDays(1)->addDays(1)->startOf('day')->cloning()
->startOf('month')->addMonths(1)->setDay('30')->subtractMonths(1)->endOf('month')->endOf('month')->format();
//call endOf('month') twice.
//It shows "2016-02-29T23:59:59+0000"

Thanks.

@fightbulc
Copy link
Owner

Hey Takumi. Will take a look asap. Also, are u able to add a Japanese translation?

@takumi-dev
Copy link
Contributor Author

Hi fightbulc, I've made a translation.
I will be glad if it helps you.

Thanks for your developing.

@fightbulc
Copy link
Owner

@takumi-dev, I hope you don't do all these transformations you put up there as your test code. Do you have a real-world example where you don't get the expected result?

@takumi-dev
Copy link
Contributor Author

@fightbulc, Sure. So far no problem for my product.
I just call endOf('month') twice. I don't know why it works, but it works.

Here is a real-world example.

$rows = array();

$start = '2016-01-31';
$end = '2016-04-30';

$timezone = 'Asia/Tokyo';
$subjectFormat = __('for %s~%s');
$dateFormat = __('Y-m-d');

$now = new \Moment\Moment($start, $timezone);
$until = new \Moment\Moment($end, $timezone);

$now->subtractDays(1);
$noDate = false;
while( $now->isBefore($until) )
{
    $now->addDays(1)->startOf('day');
    $next = $now->cloning()->startOf('month');
    if( (string)$now->getDay() === '01' )
    {
        $next->endOf('month');
        if( $noDate )
        {
            $next->setDay($until->getDay());
            $noDate = false;
        }
    }
    else
    {
        $next->addMonths(1)->setDay($until->getDay());
        if( $next->getDay() !== $until->getDay() )
        {
            $next->subtractMonths(1)->endOf('month');
        }
        if( $next->cloning()->endOf('month')->format() === $next->format() )
        {
            $noDate = true;
        }
    }

    $subject = sprintf($subjectFormat, $now->format(__('m/d')), $next->format(__('m/d')));
    $rows []= $subject;

    $now = $next;
}
print_r($rows);

/*
*  expected: Array ( [0] => for 01/31~02/29 [1] => for 03/01~03/30 [2] => for 03/31~04/30 )
*  real:     Array ( [0] => for 01/31~02/28 [1] => for 02/29~03/30 [2] => for 03/31~04/30 )
*/

These codes are for generating rows of a document for kind of estimation.
usage:
for 01/31-02/29 $100
for 03/01~03/30 $150

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants