| Current File : /home/bwalansa/www/wp-content/plugins/the-events-calendar/src/Tribe/Date_Utils.php |
<?php
/**
* Date utility functions used throughout TEC + Addons
*/
// Don't load directly
if ( ! defined( 'ABSPATH' ) ) {
die( '-1' );
}
if ( ! class_exists( 'Tribe__Events__Date_Utils' ) ) {
class Tribe__Events__Date_Utils {
// Default formats, they are overridden by WP options or by arguments to date methods
const DATEONLYFORMAT = 'F j, Y';
const TIMEFORMAT = 'g:i A';
const HOURFORMAT = 'g';
const MINUTEFORMAT = 'i';
const MERIDIANFORMAT = 'A';
const DBDATEFORMAT = 'Y-m-d';
const DBDATETIMEFORMAT = 'Y-m-d H:i:s';
const DBTIMEFORMAT = 'H:i:s';
const DBYEARMONTHTIMEFORMAT = 'Y-m';
/**
* Get the datepicker format, that is used to translate the option from the DB to a string
*
* @param int $translate The db Option from datepickerFormat
* @return string|array If $translate is not set returns the full array, if not returns the `Y-m-d`
*/
public static function datepicker_formats( $translate = null ) {
$formats = array(
'Y-m-d',
'n/j/Y',
'm/d/Y',
'j/n/Y',
'd/m/Y',
'n-j-Y',
'm-d-Y',
'j-n-Y',
'd-m-Y',
);
if ( is_null( $translate ) ) {
return $formats;
}
return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[0];
}
/**
* As PHP 5.2 doesn't have a good version of `date_parse_from_format`, this is how we deal with
* possible weird datepicker formats not working
*
* @param string $format The weird format you are using
* @param string $date The date string to parse
*
* @return string A DB formated Date, includes time if possible
*/
public static function datetime_from_format( $format, $date ) {
// Reverse engineer the relevant date formats
$keys = array(
// Year with 4 Digits
'Y' => array( 'year', '\d{4}' ),
// Year with 2 Digits
'y' => array( 'year', '\d{2}' ),
// Month with leading 0
'm' => array( 'month', '\d{2}' ),
// Month without the leading 0
'n' => array( 'month', '\d{1,2}' ),
// Month ABBR 3 letters
'M' => array( 'month', '[A-Z][a-z]{2}' ),
// Month Name
'F' => array( 'month', '[A-Z][a-z]{2,8}' ),
// Day with leading 0
'd' => array( 'day', '\d{2}' ),
// Day without leading 0
'j' => array( 'day', '\d{1,2}' ),
// Day ABBR 3 Letters
'D' => array( 'day', '[A-Z][a-z]{2}' ),
// Day Name
'l' => array( 'day', '[A-Z][a-z]{5,8}' ),
// Hour 12h formatted, with leading 0
'h' => array( 'hour', '\d{2}' ),
// Hour 24h formatted, with leading 0
'H' => array( 'hour', '\d{2}' ),
// Hour 12h formatted, without leading 0
'g' => array( 'hour', '\d{1,2}' ),
// Hour 24h formatted, without leading 0
'G' => array( 'hour', '\d{1,2}' ),
// Minutes with leading 0
'i' => array( 'minute', '\d{2}' ),
// Seconds with leading 0
's' => array( 'second', '\d{2}' ),
);
$date_regex = "/{$keys['Y'][1]}-{$keys['m'][1]}-{$keys['d'][1]}( {$keys['H'][1]}:{$keys['i'][1]}:{$keys['s'][1]})?$/";
// if the date is already in Y-m-d or Y-m-d H:i:s, just return it
if ( preg_match( $date_regex, $date ) ) {
return $date;
}
// Convert format string to regex
$regex = '';
$chars = str_split( $format );
foreach ( $chars as $n => $char ) {
$last_char = isset( $chars[ $n - 1 ] ) ? $chars[ $n - 1 ] : '';
$skip_current = '\\' == $last_char;
if ( ! $skip_current && isset( $keys[ $char ] ) ) {
$regex .= '(?P<' . $keys[ $char ][0] . '>' . $keys[ $char ][1] . ')';
} else if ( '\\' == $char ) {
$regex .= $char;
} else {
$regex .= preg_quote( $char );
}
}
$dt = array();
// Now try to match it
if ( preg_match( '#^' . $regex . '$#', $date, $dt ) ){
// Remove unwanted Indexes
foreach ( $dt as $k => $v ){
if ( is_int( $k ) ){
unset( $dt[ $k ] );
}
}
// We need at least Month + Day + Year to work with
if ( ! checkdate( $dt['month'], $dt['day'], $dt['year'] ) ){
return false;
}
} else {
return false;
}
$dt['month'] = str_pad( $dt['month'], 2, '0', STR_PAD_LEFT );
$dt['day'] = str_pad( $dt['day'], 2, '0', STR_PAD_LEFT );
$formatted = '{year}-{month}-{day}' . ( isset( $dt['hour'], $dt['minute'], $dt['second'] ) ? ' {hour}:{minute}:{second}' : '' );
foreach ( $dt as $key => $value ) {
$formatted = str_replace( '{' . $key . '}', $value, $formatted );
}
return $formatted;
}
/**
* Returns the date only.
*
* @param int|string $date The date (timestamp or string).
* @param bool $isTimestamp Is $date in timestamp format?
* @param string|null $format The format used
*
* @return string The date only in DB format.
*/
public static function date_only( $date, $isTimestamp = false, $format = null ) {
$date = $isTimestamp ? $date : strtotime( $date );
if ( is_null( $format ) ) {
$format = self::DBDATEFORMAT;
}
return date( $format, $date );
}
/**
* Returns the date only.
*
* @param string $date The date.
*
* @return string The time only in DB format.
*/
public static function time_only( $date ) {
return date( self::DBTIMEFORMAT, strtotime( $date ) );
}
/**
* Returns the hour only.
*
* @param string $date The date.
*
* @return string The hour only.
*/
public static function hour_only( $date ) {
return date( self::HOURFORMAT, strtotime( $date ) );
}
/**
* Returns the minute only.
*
* @param string $date The date.
*
* @return string The minute only.
*/
public static function minutes_only( $date ) {
return date( self::MINUTEFORMAT, strtotime( $date ) );
}
/**
* Returns the meridian (am or pm) only.
*
* @param string $date The date.
*
* @return string The meridian only in DB format.
*/
public static function meridian_only( $date ) {
return date( self::MERIDIANFORMAT, strtotime( $date ) );
}
/**
* Returns the number of seconds (absolute value) between two dates/times.
*
* @param string $date1 The first date.
* @param string $date2 The second date.
*
* @return int The number of seconds between the dates.
*/
public static function time_between( $date1, $date2 ) {
return abs( strtotime( $date1 ) - strtotime( $date2 ) );
}
/**
* The number of days between two arbitrary dates.
*
* @param string $date1 The first date.
* @param string $date2 The second date.
*
* @return int The number of days between two dates.
*/
public static function date_diff( $date1, $date2 ) {
// Get number of days between by finding seconds between and dividing by # of seconds in a day
$days = self::time_between( $date1, $date2 ) / ( 60 * 60 * 24 );
return $days;
}
/**
* Returns the last day of the month given a php date.
*
* @param int $timestamp THe timestamp.
*
* @return string The last day of the month.
*/
public static function get_last_day_of_month( $timestamp ) {
$curmonth = date( 'n', $timestamp );
$curYear = date( 'Y', $timestamp );
$nextmonth = mktime( 0, 0, 0, $curmonth + 1, 1, $curYear );
$lastDay = strtotime( date( Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_FORMAT, $nextmonth ) . ' - 1 day' );
return date( 'j', $lastDay );
}
/**
* Returns true if the timestamp is a weekday.
*
* @param int $curDate A timestamp.
*
* @return bool If the timestamp is a weekday.
*/
public static function is_weekday( $curdate ) {
return in_array( date( 'N', $curdate ), array( 1, 2, 3, 4, 5 ) );
}
/**
* Returns true if the timestamp is a weekend.
*
* @param int $curDate A timestamp.
*
* @return bool If the timestamp is a weekend.
*/
public static function is_weekend( $curdate ) {
return in_array( date( 'N', $curdate ), array( 6, 7 ) );
}
/**
* Gets the last day of the week in a month (ie the last Tuesday). Passing in -1 gives you the last day in the month.
*
* @param int $curdate A timestamp.
* @param int $day_of_week The index of the day of the week.
*
* @return int The timestamp of the date that fits the qualifications.
*/
public static function get_last_day_of_week_in_month( $curdate, $day_of_week ) {
$nextdate = mktime( date( 'H', $curdate ), date( 'i', $curdate ), date( 's', $curdate ), date( 'n', $curdate ), self::get_last_day_of_month( $curdate ), date( 'Y', $curdate ) );;
while ( date( 'N', $nextdate ) != $day_of_week && $day_of_week != - 1 ) {
$nextdate = strtotime( date( Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_FORMAT, $nextdate ) . ' - 1 day' );
}
return $nextdate;
}
/**
* Gets the first day of the week in a month (ie the first Tuesday).
*
* @param int $curdate A timestamp.
* @param int $day_of_week The index of the day of the week.
*
* @return int The timestamp of the date that fits the qualifications.
*/
public static function get_first_day_of_week_in_month( $curdate, $day_of_week ) {
$nextdate = mktime( 0, 0, 0, date( 'n', $curdate ), 1, date( 'Y', $curdate ) );
while ( ! ( $day_of_week > 0 && date( 'N', $nextdate ) == $day_of_week ) &&
! ( $day_of_week == - 1 && self::is_weekday( $nextdate ) ) &&
! ( $day_of_week == - 2 && self::is_weekend( $nextdate ) ) ) {
$nextdate = strtotime( date( Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_FORMAT, $nextdate ) . ' + 1 day' );
}
return $nextdate;
}
/**
* From http://php.net/manual/en/function.date.php
*
* @param int $number A number.
*
* @return string The ordinal for that number.
*/
public static function number_to_ordinal( $number ) {
$output = $number . ( ( ( strlen( $number ) > 1 ) && ( substr( $number, - 2, 1 ) == '1' ) ) ?
'th' : date( 'S', mktime( 0, 0, 0, 0, substr( $number, - 1 ), 0 ) ) );
return apply_filters( 'tribe_events_number_to_ordinal', $output, $number );
}
/**
* check if a given string is a timestamp
*
* @param $timestamp
*
* @return bool
*/
public static function is_timestamp( $timestamp ) {
if ( is_numeric( $timestamp ) && (int) $timestamp == $timestamp && date( 'U', $timestamp ) == $timestamp ) {
return true;
}
return false;
}
/**
* Accepts a string representing a date/time and attempts to convert it to
* the specified format, returning an empty string if this is not possible.
*
* @param $dt_string
* @param $new_format
*
* @return string
*/
public static function reformat( $dt_string, $new_format ) {
$timestamp = strtotime( $dt_string );
$revised = date( $new_format, $timestamp );
return $revised ? $revised : '';
}
/**
* Accepts a numeric offset (such as "4" or "-6" as stored in the gmt_offset
* option) and converts it to a strtotime() style modifier that can be used
* to adjust a DateTime object, etc.
*
* @param $offset
*
* @return string
*/
public static function get_modifier_from_offset( $offset ) {
$modifier = '';
$offset = (float) $offset;
// Separate out hours, minutes, polarity
$hours = (int) $offset;
$minutes = (int) ( ( $offset - $hours ) * 60 );
$polarity = ( $offset >= 0 ) ? '+' : '-';
// Correct hours and minutes to positive values
if ( $hours < 0 ) $hours *= -1;
if ( $minutes < 0 ) $minutes *= -1;
// Form the modifier string
if ( $hours >= 0 ) $modifier = "$polarity $hours hours ";
if ( $minutes > 0 ) $modifier .= "$minutes minutes";
return $modifier;
}
/**
* Returns the weekday of the 1st day of the month in
* "w" format (ie, Sunday is 0 and Saturday is 6) or
* false if this cannot be established.
*
* @param mixed $month
* @return int|bool
*/
public static function first_day_in_month( $month ) {
try {
$date = new DateTime( $month );
$day_1 = new DateTime( $date->format( 'Y-m-01 ' ) );
return $day_1->format( 'w' );
}
catch ( Exception $e ) {
return false;
}
}
/**
* Returns the weekday of the last day of the month in
* "w" format (ie, Sunday is 0 and Saturday is 6) or
* false if this cannot be established.
*
* @param mixed $month
* @return int|bool
*/
public static function last_day_in_month( $month ) {
try {
$date = new DateTime( $month );
$day_1 = new DateTime( $date->format( 'Y-m-t' ) );
return $day_1->format( 'w' );
}
catch ( Exception $e ) {
return false;
}
}
/**
* Returns the day of the week the week ends on, expressed as a "w" value
* (ie, Sunday is 0 and Saturday is 6).
*
* @param int $week_starts_on
*
* @return int
*/
public static function week_ends_on( $week_starts_on ) {
if ( --$week_starts_on < 0 ) $week_starts_on = 6;
return $week_starts_on;
}
/**
* Helper method to convert EventAllDay values to a boolean
*
* @param mixed $all_day_value Value to check for "all day" status. All day values: (true, 'true', 'TRUE', 'yes')
*
* @return boolean Is value considered "All Day"?
*/
public static function is_all_day( $all_day_value ) {
$all_day_value = trim( $all_day_value );
return (
'true' === strtolower( $all_day_value )
|| 'yes' === strtolower( $all_day_value )
|| true === $all_day_value
|| 1 == $all_day_value
);
}
/**
* Given 2 datetime ranges, return whether the 2nd one occurs during the 1st one
* Note: all params should be unix timestamps
*
* @param integer $range_1_start timestamp for start of the first range
* @param integer $range_1_end timestamp for end of the first range
* @param integer $range_2_start timestamp for start of the second range
* @param integer $range_2_end timestamp for end of the second range
*
* @return bool
*/
public static function range_coincides( $range_1_start, $range_1_end, $range_2_start, $range_2_end ) {
// Initialize the return value
$range_coincides = false;
/**
* conditions:
* range 2 starts during range 1 (range 2 start time is between start and end of range 1 )
* range 2 ends during range 1 (range 2 end time is between start and end of range 1 )
* range 2 encloses range 1 (range 2 starts before range 1 and ends after range 1)
*/
$range_2_starts_during_range_1 = $range_2_start >= $range_1_start && $range_2_start < $range_1_end;
$range_2_ends_during_range_1 = $range_2_end > $range_1_start && $range_2_end <= $range_1_end;
$range_2_encloses_range_1 = $range_2_start < $range_1_start && $range_2_end > $range_1_end;
if ( $range_2_starts_during_range_1 || $range_2_ends_during_range_1 || $range_2_encloses_range_1 ) {
$range_coincides = true;
}
return $range_coincides;
}
// DEPRECATED METHODS
// @codingStandardsIgnoreStart
/**
* Deprecated camelCase version of self::date_only
*
* @param int|string $date The date (timestamp or string).
* @param bool $isTimestamp Is $date in timestamp format?
*
* @return string The date only in DB format.
*/
public static function dateOnly( $date, $isTimestamp = false ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_only' );
return self::date_only( $date, $isTimestamp );
}
/**
* Deprecated camelCase version of self::time_only
*
* @param string $date The date.
*
* @return string The time only in DB format.
*/
public static function timeOnly( $date ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_only' );
return self::time_only( $date );
}
/**
* Deprecated camelCase version of self::hour_only
*
* @param string $date The date.
*
* @return string The hour only.
*/
public static function hourOnly( $date ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::hour_only' );
return self::hour_only( $date );
}
/**
* Deprecated camelCase version of self::minutes_only
*
* @param string $date The date.
*
* @return string The minute only.
*/
public static function minutesOnly( $date ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::minutes_only' );
return self::minutes_only( $date );
}
/**
* Deprecated camelCase version of self::meridian_only
*
* @param string $date The date.
*
* @return string The meridian only in DB format.
*/
public static function meridianOnly( $date ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::meridian_only' );
return self::meridian_only( $date );
}
/**
* Returns the end of a given day.
*
* @deprecated since 3.10 - use tribe_event_end_of_day()
* @todo remove in 4.1
*
* @param int|string $date The date (timestamp or string).
* @param bool $isTimestamp Is $date in timestamp format?
*
* @return string The date and time of the end of a given day
*/
public static function endOfDay( $date, $isTimestamp = false ) {
_deprecated_function( __METHOD__, '3.10', 'tribe_event_end_of_day' );
if ( $isTimestamp ) {
$date = date( self::DBDATEFORMAT, $date );
}
return tribe_event_end_of_day( $date, self::DBDATETIMEFORMAT );
}
/**
* Returns the beginning of a given day.
*
* @deprecated since 3.10
* @todo remove in 4.1
*
* @param int|string $date The date (timestamp or string).
* @param bool $isTimestamp Is $date in timestamp format?
*
* @return string The date and time of the beginning of a given day.
*/
public static function beginningOfDay( $date, $isTimestamp = false ) {
_deprecated_function( __METHOD__, '3.10', 'tribe_event_beginning_of_day' );
if ( $isTimestamp ) {
$date = date( self::DBDATEFORMAT, $date );
}
return tribe_event_beginning_of_day( $date, self::DBDATETIMEFORMAT );
}
/**
* Deprecated camelCase version of self::time_between
*
* @param string $date1 The first date.
* @param string $date2 The second date.
*
* @return int The number of seconds between the dates.
*/
public static function timeBetween( $date1, $date2 ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_between' );
return self::time_between( $date1, $date2 );
}
/**
* Deprecated camelCase version of self::date_diff
*
* @param string $date1 The first date.
* @param string $date2 The second date.
*
* @return int The number of days between two dates.
*/
public static function dateDiff( $date1, $date2 ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_diff' );
return self::date_diff( $date1, $date2 );
}
/**
* Deprecated camelCase version of self::get_last_day_of_month
*
* @param int $timestamp THe timestamp.
*
* @return string The last day of the month.
*/
public static function getLastDayOfMonth( $timestamp ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_month' );
return self::get_last_day_of_month( $timestamp );
}
/**
* Deprecated camelCase version of self::is_weekday
*
* @param int $curDate A timestamp.
*
* @return bool If the timestamp is a weekday.
*/
public static function isWeekday( $curdate ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekday' );
return self::is_weekday( $curdate );
}
/**
* Deprecated camelCase version of self::is_weekend
*
* @param int $curDate A timestamp.
*
* @return bool If the timestamp is a weekend.
*/
public static function isWeekend( $curdate ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekend' );
return self::is_weekend( $curdate );
}
/**
* Deprecated camelCase version of self::get_last_day_of_week_in_month
*
* @param int $curdate A timestamp.
* @param int $day_of_week The index of the day of the week.
*
* @return int The timestamp of the date that fits the qualifications.
*/
public static function getLastDayOfWeekInMonth( $curdate, $day_of_week ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_week_in_month' );
return self::get_last_day_of_week_in_month( $curdate, $day_of_week );
}
/**
* Deprecated camelCase version of self::get_first_day_of_week_in_month
*
* @param int $curdate A timestamp.
* @param int $day_of_week The index of the day of the week.
*
* @return int The timestamp of the date that fits the qualifications.
*/
public static function getFirstDayOfWeekInMonth( $curdate, $day_of_week ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_fist_day_of_week_in_month' );
return self::get_first_day_of_week_in_month( $curdate, $day_of_week );
}
/**
* Deprecated camelCase version of self::number_to_ordinal
*
* @param int $number A number.
*
* @return string The ordinal for that number.
*/
public static function numberToOrdinal( $number ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::number_to_ordinal' );
return self::number_to_ordinal( $number );
}
/**
* Deprecated camelCase version of self::is_timestamp
*
* @param $timestamp
*
* @return bool
*/
public static function isTimestamp( $timestamp ) {
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_timestamp' );
return self::is_timestamp( $timestamp );
}
// @codingStandardsIgnoreEnd
}
}