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

Task Scheduling quarterly running on June? #19532

Closed
okmkey45 opened this issue Jun 8, 2017 · 22 comments
Closed

Task Scheduling quarterly running on June? #19532

okmkey45 opened this issue Jun 8, 2017 · 22 comments

Comments

@okmkey45
Copy link

okmkey45 commented Jun 8, 2017

  • Laravel Version: 5.2
  • PHP Version: 5.6.20
  • Database Driver & Version: mysql

Description:

I want a task scheduling running every three months (Jan, Apr, Jul, Oct). So looking the documentation and the code, the method "quarterly" seemed to work for me. So I used it like this:

$schedule->command('command-name')->quarterly();

But something weird happened. The task was triggered on Jun 1st. Why? does it affect when I set the kernel.php configuration? My timezone is America/bogota

Steps To Reproduce:

Well, this could be hard. Use the quarterly method on a scheduled task and wait?

@themsaid
Copy link
Member

themsaid commented Jun 8, 2017

The CRON expression seems correct to me 0 0 1 */3 * *, check your server time.

@it-can
Copy link
Contributor

it-can commented Jun 8, 2017

Shouldnt it be

0 0 1 */3 *

@themsaid
Copy link
Member

themsaid commented Jun 8, 2017

The last place is optional and it represents the year.

@okmkey45
Copy link
Author

okmkey45 commented Jun 9, 2017

checking the server time, it is set UTC. But in my config/app.php I set America/Bogota.

But even with this, the task is triggered one month earlier

@themsaid
Copy link
Member

themsaid commented Jun 9, 2017

Weird, I don't seem to have an explanation for that, only thing I can think of is if your server date is not correct so it thinks we are in july.

@decadence
Copy link
Contributor

Taylor just merged my PR with method that shows next time Event will run. There is example for debug. You can try it to see if dates are expected.
#19537

@themsaid
Copy link
Member

@okmkey45 any updates on this, testing on local machine as well as a Forge server shows that quarterly schedules for the beginning of next month. Must be something with your environment.

@okmkey45
Copy link
Author

I checked my server configuration time and my laravel application configuration and it seems to be set right. The only thing that I can do for now is that the task triggers on july 1st and I hope it works.

@themsaid
Copy link
Member

Ok I'm going to close this issue for now since nobody can replicate, please feel free to ping me if you ever found what was wrong.

@haakym
Copy link
Contributor

haakym commented Jun 14, 2017

@okmkey45 you said you wanted the task to run on the following months January, April, July, October. I ran the following code and found that $event->quarterly() will run on March, June (which is when your task ran), September, December.

I've written the console output as comments for each respective var_dump():

class CronQuarterlyTest extends TestCase
{
    use DatabaseMigrations;

    /** @test */
    public function test_a_quarterly_schedule()
    {
    	date_default_timezone_set('America/Bogota');

        $event = new \Illuminate\Console\Scheduling\Event(m::mock('Illuminate\Console\Scheduling\Mutex'), 'php -i');
        
        $event->quarterly();

        var_dump($event->nextRunDate('2016-12-01')->format('Y-m-d')); // 2017-03-01 <- March
        var_dump($event->nextRunDate('2017-01-01')->format('Y-m-d')); // 2017-03-01 <- March
        var_dump($event->nextRunDate('2017-02-01')->format('Y-m-d')); // 2017-03-01 <- March
        var_dump($event->nextRunDate('2017-03-01')->format('Y-m-d')); // 2017-06-01 <- June
        var_dump($event->nextRunDate('2017-04-01')->format('Y-m-d')); // 2017-06-01 <- June
        var_dump($event->nextRunDate('2017-05-01')->format('Y-m-d')); // 2017-06-01 <- June
        var_dump($event->nextRunDate('2017-06-01')->format('Y-m-d')); // 2017-09-01 <- September
        var_dump($event->nextRunDate('2017-07-01')->format('Y-m-d')); // 2017-09-01 <- September
        var_dump($event->nextRunDate('2017-08-01')->format('Y-m-d')); // 2017-09-01 <- September
        var_dump($event->nextRunDate('2017-09-01')->format('Y-m-d')); // 2017-12-01 <- December
        var_dump($event->nextRunDate('2017-10-01')->format('Y-m-d')); // 2017-12-01 <- December
        var_dump($event->nextRunDate('2017-11-01')->format('Y-m-d')); // 2017-12-01 <- December
        var_dump($event->nextRunDate('2017-12-01')->format('Y-m-d')); // 2018-03-01 <- December
    }
}

Perhaps you need to approach the problem with a different solution?

Thanks to @decadence for the nextRunDate method!

@decadence
Copy link
Contributor

In fact I think this is bug with underlying library https://github.com/mtdowling/cron-expression
Resulting expression is: 0 0 1 */3 * which should run on 1, 4, 7, 10 months by the real CRON rules.
But this library assumes start from March and in result we have 3, 6, 9, 12 which is wrong.

Proof (click on next link to see all next dates).
Proof

Only workaround I see is ->cron("0 0 1 1,4,7,10 * *")

@themsaid
Copy link
Member

@decadence interesting, investigating.

@decadence
Copy link
Contributor

decadence commented Jun 14, 2017

Created issue on mtdowling/cron-expression
Then it should be opened I think.

@themsaid
Copy link
Member

@decadence looks like this is intended, asked a few random persons to define quarterly and all said 3,6,9,12 .. I don't think this will change in the framework, you can however describe your own expression using the cron method:

->cron('* * * * *')

@decadence
Copy link
Contributor

decadence commented Jun 14, 2017

I'm disagree.
For 3,6,9,12 you need to set 3-12/3, 0 0 1 */3 * should run on 1, 4, 7, 10.

quarterly is the end or start of quarter: then it should be 1st April 00:00 or 31 March 23:59.
For cron we can't set "last" value so we should use midnight of the next month.
Laravel sets midnight of */3 which would be correct if library handles this in right way.

Now it runs on 1 March 00:00 which is not end or start of quarter at all and that's completely wrong.

@dragonmantank
Copy link
Contributor

Hello! I'm the maintainer of the mtdowling/cron-expression library.

Upon further inspection (and right now going through cronie source code), the behavior of the */x on non-zero fields does seem to be incorrect, so @decadence is probably correct. 0 0 1 */3 * should run on JAN, APR, JUL, OCT.

The fix for this will also impact Day of Month, which also starts with an index of 1 instead of 0, which could be a potentially very breaking change. As the v1.x branch is PHP 5 and no longer maintained, the fix will only be in the upcoming v2.x branch, which is only supporting PHP 7 or higher. It looks like Laravel still requires PHP 5.6, so master or the eventual v2.x release will not work for most people.

As a stop-gap, I'd suggest having the code that generates a quartly cron change to 0 0 1 1-12/3 *, as that will properly step through the range.

@m1guelpf
Copy link
Contributor

Opened #19600 using the solution provided by @dragonmantank

@themsaid
Copy link
Member

themsaid commented Jun 14, 2017

@dragonmantank thanks for reaching out, I understand that for an actual CRON expression 1/3 should run on 1,4,7,10 but I'm saying that changing this now might break some people's apps who rely on the fact that it currently runs on 3,6,9,12.

Thanks again :) moving the discussion to #19600

@dragonmantank
Copy link
Contributor

@themsaid Agreed. The behavior will not be changing for v1.x, which is the version Laravel currently uses. It will be in the upcoming v2.x branch, which is currently master.

@okmkey45
Copy link
Author

so, in conclusion I better use

->cron('* * * * *')

at least for now to solve my problem.

Thanks everyone.

@decadence
Copy link
Contributor

How does it solve your problem if it runs every minute?

@okmkey45
Copy link
Author

I´m sorry. My bad. I mean, I will use the cron method, not that configuration.

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

No branches or pull requests

7 participants