WP Cron job every 1st and 15th of the month

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;

}

Related posts

2 comments

  1. 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.

  2. 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' );
    

Comments are closed.