Skip to content

Instantly share code, notes, and snippets.

@keesiemeijer
Last active March 18, 2021 08:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keesiemeijer/7563447 to your computer and use it in GitHub Desktop.
Save keesiemeijer/7563447 to your computer and use it in GitHub Desktop.
Gets date ranges for the BETWEEN operator in a WordPress meta query
<?php
/**
* Gets date ranges for the BETWEEN operator in a WordPress meta query.
* WordPress minimum requirements don't let you
* use php DateTime or (some) relative formats for strtotime() which were introduced in php 5.3.
*
* @param string|array $args Arguments.
* @return array Array with two dates.
*/
function get_between_clause_dates( $args ) {
$defaults = array(
'type' => 'month', // month - year, month, day
'start_from' => 'today', // today, type - Start from today, or from first/last day of month/year.
'future_past' => 'past', // past, future - Past or future date range.
'offset' => 0, // 0 = current month (1 = one month from current date etc...).
'duration' => 1, // duration of 1 month (1 or higher).
);
$args = wp_parse_args( $args, $defaults );
if ( !in_array( $args['type'], array( 'year', 'month', 'day' ) ) ) {
$args['type'] = 'month';
}
if ( !in_array( $args['start_from'], array( 'today', 'type' ) ) ) {
$args['start_from'] = 'today';
}
if ( !in_array( $args['future_past'], array( 'future', 'past' ) ) ) {
$args['future_past'] = 'past';
}
$args['offset'] = absint( $args['offset'] );
$args['duration'] = absint( $args['duration'] );
$args['duration'] = ( $args['duration'] ) ? $args['duration'] : 1;
extract( $args );
// start from today
$start_date = getdate();
if ( ( 'type' == $start_from ) && ( 'day' != $type ) ) {
// start from this year, month
if ( 'past' == $future_past ) {
// into the past (start from last day of current type)
switch ( $type ) {
case 'year':
$start_date['mon'] = 12;
$start_date['mday'] = 31;
break;
case 'month':
// get last day of month with offset
$last_day = date( "t", mktime( 0, 0, 0, $start_date['mon'], 1, $start_date['year'] ) );
$start_date['mday'] = $last_day;
break;
}
} else {
// into the future (start from first day of current type)
switch ( $type ) {
case 'year': $start_date['mon'] = $start_date['mday'] = 1;
case 'month': $start_date['mday'] = 1; break;
}
}
}
if ( $offset > 0 ) {
$start_date = get_date_offset( $start_date, $args );
}
$args['offset'] = $duration;
$end_date = get_date_offset( $start_date, $args, true );
$start_date = $start_date['year'] . '-' . zeroise( $start_date['mon'], 2 ) . '-' . zeroise( $start_date['mday'], 2 );
$end_date = $end_date['year'] . '-' . zeroise( $end_date['mon'], 2 ) . '-' . zeroise( $end_date['mday'], 2 );
if ( 'past' == $future_past ) {
return array( $end_date, $start_date );
} else {
return array( $start_date, $end_date );
}
}
/**
* Gets a date with an offset.
*
* @param array $date Date array from the getdate() function.
* @param array $args Arguments.
* @param bool $end_date If this is an end date or a start date. Default: false.
* @return array getdate() array with an offset date.
*/
function get_date_offset( $date, $args, $end_date = false ) {
extract( $args );
if ( 'past' == $future_past ) {
switch ( $type ) {
case 'year':
case 'month':
$_type = ( 'month' == $type ) ? 'mon' : $type;
$date[ $_type ] = $date[ $_type ] - $offset;
if ( ( $start_from == 'type' ) && $end_date ) { // end date in the past
$date['mday'] = 1;
$date['mon'] = $date['mon'] + 1;
}
break;
case 'day':
$date['mday'] = $date['mday'] - $offset;
break;
}
} else {
// future
switch ( $type ) {
case 'year':
case 'month':
$_type = ( 'month' == $type ) ? 'mon' : $type;
$date[ $_type ] = $date[ $_type ] + $offset;
if ( ( $start_from == 'type' ) && $end_date ) { // end date in the futue
$date['mday'] = 0; // -1day
}
break;
case 'day': $date['mday'] = $date['mday'] + $offset;
break;
}
}
// check if day is greater than last day of month
if ( ( 'year' == $type ) || ( 'month' == $type ) ) {
// get the total days of the month for this year-month
$last_day_of_month = date( "t", mktime( 0, 0, 0, $date['mon'], 1, $date['year'] ) );
if ( ( $start_from == 'type' ) && ( 'past' == $future_past ) ) {
if ( !$end_date ) // start date
$date['mday'] = $last_day_of_month; // start date
}
// check if day bigger than last day of month
$date['mday'] = ( $date['mday'] > $last_day_of_month ) ? $last_day_of_month : $date['mday'];
}
return getdate( mktime( 0, 0, 0, (int) $date['mon'], $date['mday'], $date['year'] ) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment