1

Trying to set up custom schedules for WP Cron, knowing that they use an interval is it even possible to set up a cron job for every first of the month? As well as every fifteenth. This is what I have so far:

private function cron_schedules( $schedules ) {

    $midnight = strtotime( "midnight", current_time( 'timestamp' ) );
    $first = strtotime( 'first day of this month', $midnight );
    $fifteenth = $first + (7 * 24 * 60 * 60) * 2;

    $schedules['1st'] = array(
        'interval'  => $first,
        'display'   => __('1st of every month'),
    );

    $schedules['15th'] = array(
        'interval'  => $fifteenth,
        'display'   => __('15th of every month'),
    );

    $schedules['weekly'] = array(
        'interval'  => ( 7 * 24 * 60 * 60 ),
        'display'   => __('Weekly'),
    );

    $schedules['biweekly'] = array(
        'interval'  => ( 7 * 24 * 60 * 60 ) * 2,
        'display'   => __('Biweekly'),
    );

    return $schedules;

}
3

wp_cron operates on intervals and there is no interval that will hit exactly the first day and the 15th of every month.

You could run your wp-cron job every day and check the date, similar to this but with a simple callback like:

cron_callback_wpse_113675() {
  $date = date('d');
  if ('01' == $date || '15' == $date) {
    // run your function
  }
}

Or, use wp_schedule_single_event with a more complicated callback. Something like this:

function cron_callback_v2_wpse_113675() {
  $date = date('d');
  if (!wp_next_scheduled(cron_callback_v2_wpse_113675)) {
    $date = ($date < 15) ? '15' : '01';
  }
  if ('01' == $date || '15' == $date) {
    // run your function
    switch ($date) {
      case '01' :
        wp_schedule_single_event( strtotime('+14 days',strtotime('first day of')), 'cron_callback_v2_wpse_113675' );
      break;
      case '15' :
        wp_schedule_single_event( strtotime('first day of'), 'cron_callback_v2_wpse_113675' );
      break;
    }
  }
}

Barely Completely untested. Possibly buggy. Caveat emptor. No refunds.

  • Thanks for the answer! I found this as well wordpress.stackexchange.com/questions/41541/… wondering if I can set up my own custom scheduler. What are your thoughts? – souporserious Sep 11 '13 at 17:11
  • I have seen that 'transient' solution before but I don't see the advantage over using wp_schedule_single_event as above, assuming that untested code actually works. Maybe I am missing something though. – s_ha_dum Sep 11 '13 at 17:22
  • Testing your first example right now, I'll let you know how it goes. Just wanted to see your thoughts on the other post. Thanks. – souporserious Sep 11 '13 at 17:25
  • Tested out and seems to working great so far. Thanks for the help! – souporserious Sep 13 '13 at 18:51
  • I think it's not necessary to run any job every day, but we can use wp_schedule_single_event and call it again when our function is finished to shedule the next job – Fanky Jul 6 '17 at 16:21
1

I encountered a similar issue but needed to fire an event on the last day of the month. I figured out an alternate solution that would work for this and my issue. Instead of modifying the schedules, I used the daily schedule to simply fire my monthly actions if necessary.

First I added code like this to my plugin activation to setup the daily check

function my_activation(){
    // Set the cron job for the monthly cron
    if( ! wp_next_scheduled ( 'maybe_monthly_cron' ) ) {
        // This will trigger an action that will fire the "monthly_cron" action on the last day of each month at 4:00 am UTC
        wp_schedule_event( strtotime('04:00:00'), 'daily', 'maybe_monthly_cron');
    }
}
register_activation_hook( __FILE__, 'my_activation' );

Then I added a job to run daily to see if it needed to fire the monthly cron

// Check if we need to fire the monthly cron action "monthly_cron"
function maybe_run_monthly_cron(){
    $now = strtotime();
    $this_day = date( 'j', $now );
    $days_this_month = date( 't', $now );
    if( $this_day == $days_this_month ){
        do_action( 'monthly_cron' );
    }
}
add_action( 'maybe_monthly_cron', 'maybe_run_monthly_cron' );

To adjust this to fire on the 1st & 15th, you could just adjust the code above to something like this:

// Check if we need to fire the monthly cron action "monthly_cron"
function maybe_run_monthly_cron(){
    $now = strtotime();
    $this_day = date( 'j', $now );
    if( in_array( $this_day, array( 1, 15 ) ) ){
        do_action( 'monthly_cron' );
    }
}
add_action( 'maybe_monthly_cron', 'maybe_run_monthly_cron' );

Then you can just use the "monthly_cron" action to perform your actions like this:

function my_monthly_cron(){
    // Execute monthly or bimonthly code here...
}
add_action( 'monthly_cron', 'my_monthly_cron' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.