@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Library function for massive time conversion operations.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date
|
||||
*/
|
||||
class Ai1ec_Date_Converter {
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Registry_Object Instance of objects registry.
|
||||
*/
|
||||
protected $_registry = null;
|
||||
|
||||
/**
|
||||
* Get reference of object registry.
|
||||
*
|
||||
* @param Ai1ec_Registry_Object $registry Injected objects registry.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( Ai1ec_Registry_Object $registry ) {
|
||||
$this->_registry = $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change timezone of times provided.
|
||||
*
|
||||
* @param array $input List of time entries to convert.
|
||||
* @param string $source_tz Timezone to convert from.
|
||||
* @param string $target_tz Timezone to convert to.
|
||||
* @param string $format Format of target time entries.
|
||||
*
|
||||
* @return array List of converted times.
|
||||
*/
|
||||
public function change_timezone(
|
||||
array $input,
|
||||
$source_tz,
|
||||
$target_tz = 'UTC',
|
||||
$format = 'U'
|
||||
) {
|
||||
$output = array();
|
||||
foreach ( $input as $time ) {
|
||||
try {
|
||||
$time_object = $this->_registry->get(
|
||||
'date.time',
|
||||
$input,
|
||||
$source_tz
|
||||
);
|
||||
$output[] = $time_object->format( $format, $target_tz );
|
||||
unset( $time_object );
|
||||
} catch ( Ai1ec_Date_Exception $exception ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper for `DateTimeZone` to extend it with convenient methods
|
||||
*
|
||||
* @author Justas Butkus <justas@butkus.lt>
|
||||
* @since 2013.03.06
|
||||
*
|
||||
* @package AllInOneCalendar
|
||||
* @subpackage AllInOneCalendar.Utility.Time
|
||||
*/
|
||||
class Ai1ec_Date_Date_Time_Zone extends DateTimeZone {
|
||||
|
||||
/**
|
||||
* Map of transitions details for given timestamp
|
||||
* {@see DateTimeZone::getTransitions()} for representation of details.
|
||||
* Return a map of prev(ious), curr(ent) and next transitions for
|
||||
* a given timestamp.
|
||||
*
|
||||
* @NOTICE: if we start accepting PHP 5.3 - update getTransitions
|
||||
* usage, to add offsets.
|
||||
*
|
||||
* @param int $timestamp UNIX timestamp (UTC0) for which to find transitions
|
||||
*
|
||||
* @return array Map of prev|curr|next transitions
|
||||
*/
|
||||
public function getDetailedTransitions( $timestamp ) {
|
||||
$transition_list = $this->getTransitions();
|
||||
$output = array(
|
||||
'prev' => NULL,
|
||||
'curr' => NULL,
|
||||
'next' => NULL,
|
||||
);
|
||||
$previous = $current = NULL;
|
||||
foreach ( $transition_list as $transition ) {
|
||||
if (
|
||||
NULL !== $previous &&
|
||||
$timestamp >= $current['ts'] &&
|
||||
$timestamp < $transition['ts']
|
||||
) {
|
||||
$output['prev'] = $previous;
|
||||
$output['curr'] = $current;
|
||||
$output['next'] = $transition;
|
||||
break;
|
||||
}
|
||||
$previous = $current;
|
||||
$current = $transition;
|
||||
}
|
||||
unset( $previous, $current, $transition_list, $transition );
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base exception for all date/time operation failures.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date.exception
|
||||
*/
|
||||
class Ai1ec_Date_Exception extends Ai1ec_Exception {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Exception to be thrown when timezone operation fails.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date
|
||||
*/
|
||||
class Ai1ec_Date_Timezone_Exception extends Ai1ec_Date_Exception {
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Legacy Time utility.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date
|
||||
*/
|
||||
class Ai1ec_Time_Utility {
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Registry_Object
|
||||
*/
|
||||
static protected $_registry;
|
||||
|
||||
/**
|
||||
* @param Ai1ec_Registry_Object $registry
|
||||
*/
|
||||
static public function set_registry( Ai1ec_Registry_Object $registry ) {
|
||||
self::$_registry = $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy function needed for theme compatibility
|
||||
*
|
||||
* @param string $format
|
||||
* @param int $timestamp
|
||||
* @param bool $is_gmt
|
||||
*/
|
||||
static public function date_i18n(
|
||||
$format,
|
||||
$timestamp = false,
|
||||
$is_gmt = true
|
||||
) {
|
||||
$timezone = ( $is_gmt ) ? 'UTC' : 'sys.default';
|
||||
return self::$_registry->get( 'date.time', $timestamp, $timezone )
|
||||
->format_i18n( $format );
|
||||
}
|
||||
|
||||
}
|
||||
279
wp-content/plugins/all-in-one-event-calendar/lib/date/system.php
Normal file
279
wp-content/plugins/all-in-one-event-calendar/lib/date/system.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrap library calls to date subsystem.
|
||||
*
|
||||
* Meant to increase performance and work around known bugs in environment.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date
|
||||
*/
|
||||
|
||||
class Ai1ec_Date_System extends Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* @var array List of local time (key '0') and GMT time (key '1').
|
||||
*/
|
||||
protected $_current_time = array();
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Cache_Memory
|
||||
*/
|
||||
protected $_gmtdates;
|
||||
|
||||
/**
|
||||
* Initiate current time list.
|
||||
*
|
||||
* @param Ai1ec_Registry_Object $registry
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( Ai1ec_Registry_Object $registry ) {
|
||||
parent::__construct( $registry );
|
||||
$gmt_time = ( version_compare( PHP_VERSION, '5.1.0' ) >= 0 )
|
||||
? time()
|
||||
: gmmktime();
|
||||
$requestTime = isset( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time();
|
||||
$this->_current_time = array(
|
||||
$requestTime,
|
||||
$gmt_time,
|
||||
);
|
||||
$this->_gmtdates = $registry->get( 'cache.memory' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current time UNIX timestamp.
|
||||
*
|
||||
* Uses in-memory value, instead of re-calling `time()` / `gmmktime()`.
|
||||
*
|
||||
* @param bool $is_gmt Set to true to get GMT timestamp.
|
||||
*
|
||||
* @return int Current time UNIX timestamp
|
||||
*/
|
||||
public function current_time( $is_gmt = false ) {
|
||||
return $this->_current_time[(int)( (bool)$is_gmt )];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the associative array of date patterns supported by the plugin.
|
||||
*
|
||||
* Currently the formats are:
|
||||
* array(
|
||||
* 'def' => 'd/m/yyyy',
|
||||
* 'us' => 'm/d/yyyy',
|
||||
* 'iso' => 'yyyy-m-d',
|
||||
* 'dot' => 'm.d.yyyy',
|
||||
* );
|
||||
*
|
||||
* 'd' or 'dd' represent the day, 'm' or 'mm' represent the month, and 'yy'
|
||||
* or 'yyyy' represent the year.
|
||||
*
|
||||
* @return array List of supported date patterns.
|
||||
*/
|
||||
public function get_date_patterns() {
|
||||
return array(
|
||||
'def' => 'd/m/yyyy',
|
||||
'us' => 'm/d/yyyy',
|
||||
'iso' => 'yyyy-m-d',
|
||||
'dot' => 'm.d.yyyy',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get acceptable date format.
|
||||
*
|
||||
* Returns the date pattern (in the form 'd-m-yyyy', for example) associated
|
||||
* with the provided key, used by plugin settings. Simply a static map as
|
||||
* follows:
|
||||
*
|
||||
* @param string $key Key for the date format.
|
||||
*
|
||||
* @return string Associated date format pattern.
|
||||
*/
|
||||
public function get_date_pattern_by_key( $key = 'def' ) {
|
||||
$patterns = $this->get_date_patterns();
|
||||
if ( ! isset( $patterns[$key] ) ) {
|
||||
return (string)current( $patterns );
|
||||
}
|
||||
return $patterns[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Format timestamp into URL safe, user selected representation.
|
||||
*
|
||||
* Returns a formatted date given a timestamp, based on the given date
|
||||
* format, with any '/' characters replaced with URL-friendly '-'
|
||||
* characters.
|
||||
*
|
||||
* @see Ai1ec_Date_System::get_date_patterns() for supported date formats.
|
||||
*
|
||||
* @param int $timestamp UNIX timestamp representing a date.
|
||||
* @param string $pattern Key of date pattern (@see
|
||||
* self::get_date_format_patter()) to
|
||||
* format date with
|
||||
*
|
||||
* @return string Formatted date string.
|
||||
*/
|
||||
public function format_date_for_url( $timestamp, $pattern = 'def' ) {
|
||||
$date = $this->format_date( $timestamp, $pattern );
|
||||
$date = str_replace( '/', '-', $date );
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@see format_date_for_url} just using new DateTime interface.
|
||||
*
|
||||
* @param Ai1ec_Date_Time $datetime Instance of datetime to format.
|
||||
* @param string $pattern Target format to use.
|
||||
*
|
||||
* @return string Formatted datetime string.
|
||||
*/
|
||||
public function format_datetime_for_url(
|
||||
Ai1ec_Date_Time $datetime,
|
||||
$pattern = 'def'
|
||||
) {
|
||||
$date = $datetime->format( $this->get_date_format_patter( $pattern ) );
|
||||
return str_replace( '/', '-', $date );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date formatted with new pattern from a given date and old pattern.
|
||||
*
|
||||
* @see self::get_date_patterns() for supported date formats.
|
||||
*
|
||||
* @param string $date Formatted date string
|
||||
* @param string $old_pattern Key of old date pattern (@see
|
||||
* self::get_date_format_patter())
|
||||
* @param string $new_pattern Key of new date pattern (@see
|
||||
* self::get_date_format_patter())
|
||||
* @return string Formatted date string with new pattern
|
||||
*/
|
||||
public function convert_date_format( $date, $old_pattern, $new_pattern ) {
|
||||
// Convert old date to timestamp
|
||||
$timeArray = date_parse_from_format( $this->get_date_format_patter( $old_pattern ), $date );
|
||||
|
||||
$timestamp = mktime(
|
||||
$timeArray['hour'], $timeArray['minute'], $timeArray['second'],
|
||||
$timeArray['month'], $timeArray['day'], $timeArray['year']
|
||||
);
|
||||
|
||||
// Convert to new date pattern
|
||||
return $this->format_date( $timestamp, $new_pattern );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted date given a timestamp, based on the given date format.
|
||||
*
|
||||
* @see self::get_date_patterns() for supported date formats.
|
||||
*
|
||||
* @param int $timestamp UNIX timestamp representing a date (in GMT)
|
||||
* @param string $pattern Key of date pattern (@see
|
||||
* self::get_date_format_patter()) to
|
||||
* format date with
|
||||
* @return string Formatted date string
|
||||
*/
|
||||
public function format_date( $timestamp, $pattern = 'def' ) {
|
||||
return gmdate( $this->get_date_format_patter( $pattern ), $timestamp );
|
||||
}
|
||||
|
||||
public function get_date_format_patter( $requested ) {
|
||||
$pattern = $this->get_date_pattern_by_key( $requested );
|
||||
$pattern = str_replace(
|
||||
array( 'dd', 'd', 'mm', 'm', 'yyyy', 'yy' ),
|
||||
array( 'd', 'j', 'm', 'n', 'Y', 'y' ),
|
||||
$pattern
|
||||
);
|
||||
return $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns human-readable version of the GMT offset.
|
||||
*
|
||||
* @param string $timezone_name Olsen Timezone name [optional=null]
|
||||
*
|
||||
* @return string GMT offset expression
|
||||
*/
|
||||
public function get_gmt_offset_expr( $timezone_name = null ) {
|
||||
$timezone = $this->get_gmt_offset( $timezone_name );
|
||||
$offset_h = (int)( $timezone / 60 );
|
||||
$offset_m = absint( $timezone - $offset_h * 60 );
|
||||
$timezone = sprintf(
|
||||
Ai1ec_I18n::__( 'GMT%+d:%02d' ),
|
||||
$offset_h,
|
||||
$offset_m
|
||||
);
|
||||
|
||||
return $timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current GMT offset in seconds.
|
||||
*
|
||||
* @param string $timezone_name Olsen Timezone name [optional=null]
|
||||
*
|
||||
* @return int Offset from GMT in seconds.
|
||||
*/
|
||||
public function get_gmt_offset( $timezone_name = null ) {
|
||||
if ( null === $timezone_name ) {
|
||||
$timezone_name = 'sys.default';
|
||||
}
|
||||
$current = $this->_registry->get(
|
||||
'date.time',
|
||||
'now',
|
||||
$timezone_name
|
||||
);
|
||||
return $current->get_gmt_offset();
|
||||
}
|
||||
|
||||
/**
|
||||
* gmgetdate method
|
||||
*
|
||||
* Get date/time information in GMT
|
||||
*
|
||||
* @param int $timestamp Timestamp at which information shall be evaluated
|
||||
*
|
||||
* @return array Associative array of information related to the timestamp
|
||||
*/
|
||||
public function gmgetdate( $timestamp = NULL ) {
|
||||
if ( NULL === $timestamp ) {
|
||||
$timestamp = isset( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time();
|
||||
}
|
||||
if ( NULL === ( $date = $this->_gmtdates->get( $timestamp ) ) ) {
|
||||
$particles = explode(
|
||||
',',
|
||||
gmdate( 's,i,G,j,w,n,Y,z,l,F,U', $timestamp )
|
||||
);
|
||||
$date = array_combine(
|
||||
array(
|
||||
'seconds',
|
||||
'minutes',
|
||||
'hours',
|
||||
'mday',
|
||||
'wday',
|
||||
'mon',
|
||||
'year',
|
||||
'yday',
|
||||
'weekday',
|
||||
'month',
|
||||
0
|
||||
),
|
||||
$particles
|
||||
);
|
||||
$this->_gmtdates->set( $timestamp, $date );
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current rounded time as unix integer.
|
||||
*
|
||||
* @param int $shift Shift value.
|
||||
*
|
||||
* @return int Unix timestamp.
|
||||
*/
|
||||
public function get_current_rounded_time( $shift = 11 ) {
|
||||
return $this->current_time() >> $shift << $shift;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Time and date internationalization management library
|
||||
*
|
||||
* @author Timely Network Inc
|
||||
* @since 2012.10.09
|
||||
*
|
||||
* @package AllInOneCalendar
|
||||
* @subpackage AllInOneCalendar.Lib.Utility
|
||||
*/
|
||||
class Ai1ec_Time_I18n_Utility extends Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* @var char Separator to wrap unique keys and avoid collisions
|
||||
* EOT is used instead of NUL, as NUL is used by `date()`
|
||||
* functions family as guard and causes memory leaks.
|
||||
*/
|
||||
protected $_separator = "\004";
|
||||
|
||||
/**
|
||||
* @var array Map of keys, used by date methods
|
||||
*/
|
||||
protected $_keys = array();
|
||||
|
||||
/**
|
||||
* @var array Map of keys for substition
|
||||
*/
|
||||
protected $_skeys = array();
|
||||
|
||||
/**
|
||||
* @var string Format to use when calling `date_i18n()`
|
||||
*/
|
||||
protected $_format = NULL;
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Memory_Utility Parsed time entries
|
||||
*/
|
||||
protected $_memory = NULL;
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Memory_Utility Parsed format entries
|
||||
*/
|
||||
protected $_transf = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Initialize internal memory objects and date keys.
|
||||
*
|
||||
* @param Ai1ec_Memory_Utility $memory Optionally inject memory to use
|
||||
*
|
||||
* @return void Constructor does not return
|
||||
*/
|
||||
public function __construct(
|
||||
Ai1ec_Registry_Object $registry,
|
||||
Ai1ec_Cache_Memory $memory = null
|
||||
) {
|
||||
parent::__construct( $registry );
|
||||
if ( NULL === $memory ) {
|
||||
$memory = $this->_registry->get( 'cache.memory', 120 ); // 30 * 4
|
||||
}
|
||||
$this->_memory = $memory;
|
||||
$this->_transf = $this->_registry->get( 'cache.memory' );
|
||||
$this->_keys = $this->_initialize_keys();
|
||||
$this->_skeys = $this->_initialize_keys(
|
||||
$this->_separator,
|
||||
$this->_separator
|
||||
);
|
||||
$this->_format = implode( $this->_separator, $this->_keys );
|
||||
}
|
||||
|
||||
/**
|
||||
* format method
|
||||
*
|
||||
* Convenient wrapper for `date_i18n()`, which caches both faster format
|
||||
* version and response for {$timestamp} and {$is_gmt} combination.
|
||||
*
|
||||
* @param string $format Format string to output timestamp in
|
||||
* @param int $timestamp UNIX timestamp to output in given format
|
||||
* @param bool $is_gmt Set to true, to treat {$timestamp} as GMT
|
||||
*
|
||||
* @return string Formatted date-time entry
|
||||
*/
|
||||
public function format( $format, $timestamp = false, $is_gmt = false ) {
|
||||
$time_elements = $this->parse( $timestamp, $is_gmt );
|
||||
$local_format = $this->_safe_format( $format );
|
||||
return str_replace( $this->_skeys, $time_elements, $local_format );
|
||||
}
|
||||
|
||||
/**
|
||||
* parse method
|
||||
*
|
||||
* Parse given timestamp into I18n date/time values map.
|
||||
*
|
||||
* @param int $timestamp Timestamp to parse
|
||||
* @param bool $is_gmt Set to true, to treat value as present in GMT
|
||||
*
|
||||
* @return array Map of date format keys and corresponding time values
|
||||
*/
|
||||
public function parse( $timestamp = false, $is_gmt = false ) {
|
||||
$timestamp = (int)$timestamp;
|
||||
if ( $timestamp <= 0 ) {
|
||||
$timestamp = $this->_registry->get( 'date.system' )->current_time();
|
||||
}
|
||||
$cache_key = $timestamp . "\0" . $is_gmt;
|
||||
if ( NULL === ( $record = $this->_memory->get( $cache_key ) ) ) {
|
||||
$record = array_combine(
|
||||
$this->_keys,
|
||||
explode(
|
||||
$this->_separator,
|
||||
date_i18n( $this->_format, $timestamp, $is_gmt )
|
||||
)
|
||||
);
|
||||
$this->_memory->set( $cache_key, $record );
|
||||
}
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* _safe_format method
|
||||
*
|
||||
* Prepare safe format value, to use in substitutions.
|
||||
* In prepared string special values are wrapped by {$_separator} to allow
|
||||
* fast replacement methods, using binary search.
|
||||
*
|
||||
* @param string $format Given format to polish
|
||||
*
|
||||
* @return string Modified format, with special keys wrapped in bin fields
|
||||
*/
|
||||
protected function _safe_format( $format ) {
|
||||
if ( NULL === ( $safe = $this->_transf->get( $format ) ) ) {
|
||||
$safe = '';
|
||||
$state = 0;
|
||||
$separator = $this->_separator;
|
||||
$length = strlen( $format );
|
||||
for ( $index = 0; $index < $length; $index++ ) {
|
||||
if ( $state > 0 ) {
|
||||
--$state;
|
||||
}
|
||||
$current = $format{$index};
|
||||
if ( 0 === $state ) {
|
||||
if ( '\\' === $current ) {
|
||||
$state = 2;
|
||||
} elseif ( isset( $this->_keys[$current] ) ) {
|
||||
$current = $separator . $current . $separator;
|
||||
}
|
||||
}
|
||||
if ( 2 !== $state ) {
|
||||
$safe .= $current;
|
||||
}
|
||||
}
|
||||
$this->_transf->set( $format, $safe );
|
||||
}
|
||||
return $safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* _initialize_keys method
|
||||
*
|
||||
* Prepare list of keys, used by date functions.
|
||||
* Optionally wrap values (keys are the same, always).
|
||||
*
|
||||
* @param string $prepend Prefix to date key
|
||||
* @param string $append Suffix to date key
|
||||
*
|
||||
* @return array Map of date keys
|
||||
*/
|
||||
protected function _initialize_keys( $prepend = '', $append = '' ) {
|
||||
$keys = array(
|
||||
'd',
|
||||
'D',
|
||||
'j',
|
||||
'l',
|
||||
'N',
|
||||
'S',
|
||||
'w',
|
||||
'z',
|
||||
'W',
|
||||
'F',
|
||||
'm',
|
||||
'M',
|
||||
'n',
|
||||
't',
|
||||
'L',
|
||||
'o',
|
||||
'Y',
|
||||
'y',
|
||||
'a',
|
||||
'A',
|
||||
'B',
|
||||
'g',
|
||||
'G',
|
||||
'h',
|
||||
'H',
|
||||
'i',
|
||||
's',
|
||||
'u',
|
||||
'e',
|
||||
'I',
|
||||
'O',
|
||||
'P',
|
||||
'T',
|
||||
'Z',
|
||||
'c',
|
||||
'r',
|
||||
'U',
|
||||
);
|
||||
$map = array();
|
||||
foreach ( $keys as $key ) {
|
||||
$map[$key] = $prepend . $key . $append;
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
}
|
||||
423
wp-content/plugins/all-in-one-event-calendar/lib/date/time.php
Normal file
423
wp-content/plugins/all-in-one-event-calendar/lib/date/time.php
Normal file
@@ -0,0 +1,423 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Time entity.
|
||||
*
|
||||
* @instantiator new
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date
|
||||
*/
|
||||
class Ai1ec_Date_Time {
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Registry_Object Instance of objects registry.
|
||||
*/
|
||||
protected $_registry = null;
|
||||
|
||||
/**
|
||||
* @var DateTime Instance of date time object used to perform manipulations.
|
||||
*/
|
||||
protected $_date_time = null;
|
||||
|
||||
/**
|
||||
* @var string Olsen name of preferred timezone to use if none is requested.
|
||||
*/
|
||||
protected $_preferred_timezone = null;
|
||||
|
||||
/**
|
||||
* @var bool Set to true when `no value` is set.
|
||||
*/
|
||||
protected $_is_empty = false;
|
||||
|
||||
/**
|
||||
* Initialize local date entity.
|
||||
*
|
||||
* @param Ai1ec_Registry_Object $registry Objects registry instance.
|
||||
* @param string $time For details {@see self::format}.
|
||||
* @param string $timezone For details {@see self::format}.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
Ai1ec_Registry_Object $registry,
|
||||
$time = 'now',
|
||||
$timezone = 'UTC'
|
||||
) {
|
||||
$this->_registry = $registry;
|
||||
$this->set_date_time( $time, $timezone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Since clone is shallow, we need to clone the DateTime object
|
||||
*/
|
||||
public function __clone() {
|
||||
$this->_date_time = clone $this->_date_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return formatted date in desired timezone.
|
||||
*
|
||||
* NOTICE: consider optimizing by storing multiple copies of `DateTime` for
|
||||
* each requested timezone, or some of them, as of now timezone is changed
|
||||
* back and forth every time when formatting is called for.
|
||||
*
|
||||
* @param string $format Desired format as accepted by {@see date}.
|
||||
* @param string $timezone Valid timezone identifier. Defaults to current.
|
||||
*
|
||||
* @return string Formatted date time.
|
||||
*
|
||||
* @throws Ai1ec_Date_Timezone_Exception If timezone is not recognized.
|
||||
*/
|
||||
public function format( $format = 'U', $timezone = null ) {
|
||||
if ( $this->_is_empty ) {
|
||||
return null;
|
||||
}
|
||||
if ( 'U' === $format ) { // performance cut
|
||||
return $this->_date_time->format( 'U' );
|
||||
}
|
||||
$timezone = $this->get_default_format_timezone( $timezone );
|
||||
$last_tz = $this->get_timezone();
|
||||
$this->set_timezone( $timezone );
|
||||
$formatted = $this->_date_time->format( $format );
|
||||
$this->set_timezone( $last_tz );
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format date time to i18n representation.
|
||||
*
|
||||
* @param string $format Target I18n format.
|
||||
* @param string $timezone Valid timezone identifier. Defaults to current.
|
||||
*
|
||||
* @return string Formatted time.
|
||||
*/
|
||||
public function format_i18n( $format, $timezone = null ) {
|
||||
$parser = $this->_registry->get( 'parser.date' );
|
||||
$parsed = $parser->get_format( $format );
|
||||
$inflected = $this->format( $parsed, $timezone );
|
||||
$formatted = $parser->squeeze( $inflected );
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commodity method to format to UTC.
|
||||
*
|
||||
* @param string $format Target format, defaults to UNIX timestamp.
|
||||
*
|
||||
* @return string Formatted datetime string.
|
||||
*/
|
||||
public function format_to_gmt( $format = 'U' ) {
|
||||
return $this->format( $format, 'UTC' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create JavaScript ready date/time information string.
|
||||
*
|
||||
* @param bool $event_timezone Set to true to format in event timezone.
|
||||
*
|
||||
* @return string JavaScript date/time string.
|
||||
*/
|
||||
public function format_to_javascript( $event_timezone = false ) {
|
||||
$event_timezone = ( $event_timezone )
|
||||
? $this->get_timezone()
|
||||
: null;
|
||||
return $this->format( 'Y-m-d\TH:i:s', $event_timezone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone to use when format doesn't have one.
|
||||
*
|
||||
* Precedence:
|
||||
* 1. Timezone supplied for formatting;
|
||||
* 2. Objects preferred timezone;
|
||||
* 3. Default systems timezone.
|
||||
*
|
||||
* @var string $timezone Requested formatting timezone.
|
||||
*
|
||||
* @return string Olsen timezone name to use.
|
||||
*/
|
||||
public function get_default_format_timezone( $timezone = null ) {
|
||||
if ( null !== $timezone ) {
|
||||
return $timezone;
|
||||
}
|
||||
if ( null !== $this->_preferred_timezone ) {
|
||||
return $this->_preferred_timezone;
|
||||
}
|
||||
return $this->_registry->get( 'date.timezone' )
|
||||
->get_default_timezone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset from GMT in minutes.
|
||||
*
|
||||
* @return int Signed integer - offset.
|
||||
*/
|
||||
public function get_gmt_offset() {
|
||||
return $this->_date_time->getOffset() / 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns timezone offset as human readable GMT string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_gmt_offset_as_text() {
|
||||
$offset = $this->_date_time->getOffset();
|
||||
$offsetHours = $offset / 3600;
|
||||
$offset = $offset % 3600;
|
||||
$offsetMinutes = abs( $offset ) / 60;
|
||||
return sprintf( '(GMT%+03d:%02d)', $offsetHours, $offsetMinutes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set preferred timezone to use when format is called without any.
|
||||
*
|
||||
* @param DateTimeZone $timezone Preferred timezone instance.
|
||||
*
|
||||
* @return Ai1ec_Date_Time Instance of self for chaining.
|
||||
*/
|
||||
public function set_preferred_timezone( $timezone ) {
|
||||
if ( $timezone instanceof DateTimeZone ) {
|
||||
$timezone = $timezone->getName();
|
||||
}
|
||||
$this->_preferred_timezone = (string)$timezone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change timezone of stored entity.
|
||||
*
|
||||
* @param string $timezone Valid timezone identifier.
|
||||
*
|
||||
* @return Ai1ec_Date Instance of self for chaining.
|
||||
*
|
||||
* @throws Ai1ec_Date_Timezone_Exception If timezone is not recognized.
|
||||
*/
|
||||
public function set_timezone( $timezone = 'UTC' ) {
|
||||
$date_time_tz = ( $timezone instanceof DateTimeZone )
|
||||
? $timezone
|
||||
: $this->_registry->get( 'date.timezone' )->get( $timezone );
|
||||
$this->_date_time->setTimezone( $date_time_tz );
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone associated with current object.
|
||||
*
|
||||
* @return string|null Valid PHP timezone string or null on error.
|
||||
*/
|
||||
public function get_timezone() {
|
||||
$timezone = $this->_date_time->getTimezone();
|
||||
if ( false === $timezone ) {
|
||||
return null;
|
||||
}
|
||||
return $timezone->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get difference in seconds between to dates.
|
||||
*
|
||||
* In PHP versions post 5.3.0 the {@see DateTimeImmutable::diff()} is
|
||||
* used. In earlier versions the difference between two timestamps is
|
||||
* being checked.
|
||||
*
|
||||
* @param Ai1ec_Date_Time $comparable Other date time entity.
|
||||
*
|
||||
* @return int Number of seconds between two dates.
|
||||
*/
|
||||
public function diff_sec( Ai1ec_Date_Time $comparable, $timezone = null ) {
|
||||
// NOTICE: `$this->_is_empty` is not touched here intentionally
|
||||
// because there is no meaningful difference to `empty` value.
|
||||
// It is left to be handled at upper level - you are not likely to
|
||||
// reach situation where you compare something against empty value.
|
||||
if ( version_compare( PHP_VERSION, '5.3.0' ) < 0 ) {
|
||||
$difference = $this->_date_time->format( 'U' ) -
|
||||
$comparable->_date_time->format( 'U' );
|
||||
if ( $difference < 0 ) {
|
||||
$difference *= -1;
|
||||
}
|
||||
return $difference;
|
||||
}
|
||||
$difference = $this->_date_time->diff( $comparable->_date_time, true );
|
||||
return (
|
||||
$difference->days * 86400 +
|
||||
$difference->h * 3600 +
|
||||
$difference->i * 60 +
|
||||
$difference->s
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust only date fragment of entity.
|
||||
*
|
||||
* @param int $year Year of the date.
|
||||
* @param int $month Month of the date.
|
||||
* @param int $day Day of the date.
|
||||
*
|
||||
* @return Ai1ec_Date_Time Instance of self for chaining.
|
||||
*/
|
||||
public function set_date( $year, $month, $day ) {
|
||||
$this->_date_time->setDate( $year, $month, $day );
|
||||
$this->_is_empty = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust only time fragment of entity.
|
||||
*
|
||||
* @param int $hour Hour of the time.
|
||||
* @param int $minute Minute of the time.
|
||||
* @param int $second Second of the time.
|
||||
*
|
||||
* @return Ai1ec_Date_Time Instance of self for chaining.
|
||||
*/
|
||||
public function set_time( $hour, $minute = 0, $second = 0 ) {
|
||||
$this->_date_time->setTime( $hour, $minute, $second );
|
||||
$this->_is_empty = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust day part of date time entity.
|
||||
*
|
||||
* @param int $quantifier Day adjustment quantifier.
|
||||
*
|
||||
* @return Ai1ec_Date_Time Instance of self for chaining.
|
||||
*/
|
||||
public function adjust_day( $quantifier ) {
|
||||
// NOTICE: `$this->_is_empty` is not touched here, because if you
|
||||
// start adjusting value it's likely not empty by then.
|
||||
$this->adjust( $quantifier, 'day' );
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust day part of date time entity.
|
||||
*
|
||||
* @param int $quantifier Day adjustment quantifier.
|
||||
*
|
||||
* @return Ai1ec_Date_Time Instance of self for chaining.
|
||||
*/
|
||||
public function adjust_month( $quantifier ) {
|
||||
$this->adjust( $quantifier, 'month' );
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change/initiate stored date time entity.
|
||||
*
|
||||
* NOTICE: time specifiers falling in range 0..2048 will be treated
|
||||
* as a UNIX timestamp, to full format specification, thus ignoring
|
||||
* any value passed for timezone.
|
||||
*
|
||||
* @param string $time Valid (PHP-parseable) date/time identifier.
|
||||
* @param string $timezone Valid timezone identifier.
|
||||
*
|
||||
* @return Ai1ec_Date Instance of self for chaining.
|
||||
*/
|
||||
public function set_date_time( $time = 'now', $timezone = 'UTC' ) {
|
||||
if ( $time instanceof self ) {
|
||||
$this->_is_empty = $time->_is_empty;
|
||||
$this->_date_time = clone $time->_date_time;
|
||||
$this->_preferred_timezone = $time->_preferred_timezone;
|
||||
if ( 'UTC' !== $timezone && $timezone ) {
|
||||
$this->set_timezone( $timezone );
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
$this->assert_utc_timezone();
|
||||
$date_time_tz = $this->_registry->get( 'date.timezone' )
|
||||
->get( $timezone );
|
||||
$reset_tz = false;
|
||||
$this->_is_empty = false;
|
||||
if ( null === $time ) {
|
||||
$this->_is_empty = true;
|
||||
$time = '@' . ~PHP_INT_MAX;
|
||||
$reset_tz = true;
|
||||
} else if ( $this->is_timestamp( $time ) ) {
|
||||
$time = '@' . $time; // treat as UNIX timestamp
|
||||
$reset_tz = true; // store intended TZ
|
||||
}
|
||||
// PHP <= 5.3.5 compatible
|
||||
$this->_date_time = new DateTime( $time, $date_time_tz );
|
||||
if ( $reset_tz ) {
|
||||
$this->set_timezone( $date_time_tz );
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if value should be treated as a UNIX timestamp.
|
||||
*
|
||||
* @param string $time Provided time value.
|
||||
*
|
||||
* @return bool True if seems like UNIX timestamp.
|
||||
*/
|
||||
public function is_timestamp( $time ) {
|
||||
// '20001231T001559Z'
|
||||
if ( isset( $time{8} ) && 'T' === $time{8} ) {
|
||||
return false;
|
||||
}
|
||||
if ( (string)(int)$time !== (string)$time ) {
|
||||
return false;
|
||||
}
|
||||
// 1000..2459 are treated as hours, 2460..9999 - as years
|
||||
if ( $time > 999 && $time < 2460 ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that current timezone is UTC.
|
||||
*
|
||||
* @return bool Success.
|
||||
*/
|
||||
public function assert_utc_timezone() {
|
||||
$default = (string)date_default_timezone_get();
|
||||
$success = true;
|
||||
if ( 'UTC' !== $default ) {
|
||||
// issue admin notice
|
||||
$success = date_default_timezone_set( 'UTC' );
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method for compatibility.
|
||||
*
|
||||
* @return string ISO-8601 formatted date-time.
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->format( 'c' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the DateTime object
|
||||
*
|
||||
* @param int $quantifieruantifier
|
||||
* @param string $longname
|
||||
*/
|
||||
public function adjust( $quantifier, $longname ) {
|
||||
$quantifier = (int)$quantifier;
|
||||
if ( $quantifier > 0 && '+' !== $quantifier{0} ) {
|
||||
$quantifier = '+' . $quantifier;
|
||||
}
|
||||
$modifier = $quantifier . ' ' . $longname;
|
||||
$this->_date_time->modify( $modifier );
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly check if value (date) is empty.
|
||||
*
|
||||
* @return bool Emptiness
|
||||
*/
|
||||
public function is_empty() {
|
||||
return $this->_is_empty;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,617 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Timezones manipulation object.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date
|
||||
*/
|
||||
class Ai1ec_Date_Timezone extends Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Cache_Interface In-memory storage for timezone objects.
|
||||
*/
|
||||
protected $_cache = null;
|
||||
|
||||
/**
|
||||
* @var array Map of timezone names and their Olson TZ counterparts.
|
||||
*/
|
||||
protected $_zones = array(
|
||||
'+00:00' => 'UTC',
|
||||
'Z' => 'UTC',
|
||||
'AUS Central Standard Time' => 'Australia/Darwin',
|
||||
'AUS Eastern Standard Time' => 'Australia/Sydney',
|
||||
'Acre' => 'America/Rio_Branco',
|
||||
'Afghanistan' => 'Asia/Kabul',
|
||||
'Afghanistan Standard Time' => 'Asia/Kabul',
|
||||
'Africa_Central' => 'Africa/Maputo',
|
||||
'Africa_Eastern' => 'Africa/Nairobi',
|
||||
'Africa_FarWestern' => 'Africa/El_Aaiun',
|
||||
'Africa_Southern' => 'Africa/Johannesburg',
|
||||
'Africa_Western' => 'Africa/Lagos',
|
||||
'Aktyubinsk' => 'Asia/Aqtobe',
|
||||
'Alaska' => 'America/Juneau',
|
||||
'Alaska_Hawaii' => 'America/Anchorage',
|
||||
'Alaskan Standard Time' => 'America/Anchorage',
|
||||
'Almaty' => 'Asia/Almaty',
|
||||
'Amazon' => 'America/Manaus',
|
||||
'America_Central' => 'America/Chicago',
|
||||
'America_Eastern' => 'America/New_York',
|
||||
'America_Mountain' => 'America/Denver',
|
||||
'America_Pacific' => 'America/Los_Angeles',
|
||||
'Anadyr' => 'Asia/Anadyr',
|
||||
'Aqtau' => 'Asia/Aqtau',
|
||||
'Aqtobe' => 'Asia/Aqtobe',
|
||||
'Arab Standard Time' => 'Asia/Riyadh',
|
||||
'Arabian' => 'Asia/Riyadh',
|
||||
'Arabian Standard Time' => 'Asia/Dubai',
|
||||
'Arabic Standard Time' => 'Asia/Baghdad',
|
||||
'Argentina' => 'America/Buenos_Aires',
|
||||
'Argentina Standard Time' => 'America/Buenos_Aires',
|
||||
'Argentina_Western' => 'America/Mendoza',
|
||||
'Armenia' => 'Asia/Yerevan',
|
||||
'Armenian Standard Time' => 'Asia/Yerevan',
|
||||
'Ashkhabad' => 'Asia/Ashgabat',
|
||||
'Atlantic' => 'America/Halifax',
|
||||
'Atlantic Standard Time' => 'America/Halifax',
|
||||
'Australia_Central' => 'Australia/Adelaide',
|
||||
'Australia_CentralWestern' => 'Australia/Eucla',
|
||||
'Australia_Eastern' => 'Australia/Sydney',
|
||||
'Australia_Western' => 'Australia/Perth',
|
||||
'Azerbaijan' => 'Asia/Baku',
|
||||
'Azerbaijan Standard Time' => 'Asia/Baku',
|
||||
'Azores' => 'Atlantic/Azores',
|
||||
'Azores Standard Time' => 'Atlantic/Azores',
|
||||
'Baku' => 'Asia/Baku',
|
||||
'Bangladesh' => 'Asia/Dhaka',
|
||||
'Bering' => 'America/Adak',
|
||||
'Bhutan' => 'Asia/Thimphu',
|
||||
'Bolivia' => 'America/La_Paz',
|
||||
'Borneo' => 'Asia/Kuching',
|
||||
'Brasilia' => 'America/Sao_Paulo',
|
||||
'British' => 'Europe/London',
|
||||
'Brunei' => 'Asia/Brunei',
|
||||
'Canada Central Standard Time' => 'America/Regina',
|
||||
'Cape Verde Standard Time' => 'Atlantic/Cape_Verde',
|
||||
'Cape_Verde' => 'Atlantic/Cape_Verde',
|
||||
'Caucasus Standard Time' => 'Asia/Yerevan',
|
||||
'Cen. Australia Standard Time' => 'Australia/Adelaide',
|
||||
'Central America Standard Time' => 'America/Guatemala',
|
||||
'Central Asia Standard Time' => 'Asia/Dhaka',
|
||||
'Central Brazilian Standard Time' => 'America/Manaus',
|
||||
'Central Europe Standard Time' => 'Europe/Budapest',
|
||||
'Central European Standard Time' => 'Europe/Warsaw',
|
||||
'Central Pacific Standard Time' => 'Pacific/Guadalcanal',
|
||||
'Central Standard Time' => 'America/Chicago',
|
||||
'Central Standard Time (Mexico)' => 'America/Mexico_City',
|
||||
'Chamorro' => 'Pacific/Saipan',
|
||||
'Changbai' => 'Asia/Harbin',
|
||||
'Chatham' => 'Pacific/Chatham',
|
||||
'Chile' => 'America/Santiago',
|
||||
'China' => 'Asia/Shanghai',
|
||||
'China Standard Time' => 'Asia/Shanghai',
|
||||
'Choibalsan' => 'Asia/Choibalsan',
|
||||
'Christmas' => 'Indian/Christmas',
|
||||
'Cocos' => 'Indian/Cocos',
|
||||
'Colombia' => 'America/Bogota',
|
||||
'Cook' => 'Pacific/Rarotonga',
|
||||
'Cuba' => 'America/Havana',
|
||||
'Dacca' => 'Asia/Dhaka',
|
||||
'Dateline Standard Time' => 'Etc/GMT+12',
|
||||
'Davis' => 'Antarctica/Davis',
|
||||
'Dominican' => 'America/Santo_Domingo',
|
||||
'DumontDUrville' => 'Antarctica/DumontDUrville',
|
||||
'Dushanbe' => 'Asia/Dushanbe',
|
||||
'Dutch_Guiana' => 'America/Paramaribo',
|
||||
'E. Africa Standard Time' => 'Africa/Nairobi',
|
||||
'E. Australia Standard Time' => 'Australia/Brisbane',
|
||||
'E. Europe Standard Time' => 'Europe/Minsk',
|
||||
'E. South America Standard Time' => 'America/Sao_Paulo',
|
||||
'East_Timor' => 'Asia/Dili',
|
||||
'Easter' => 'Pacific/Easter',
|
||||
'Eastern Standard Time' => 'America/New_York',
|
||||
'Ecuador' => 'America/Guayaquil',
|
||||
'Egypt Standard Time' => 'Africa/Cairo',
|
||||
'Ekaterinburg Standard Time' => 'Asia/Yekaterinburg',
|
||||
'Europe_Central' => 'Europe/Paris',
|
||||
'Europe_Eastern' => 'Europe/Bucharest',
|
||||
'Europe_Western' => 'Atlantic/Canary',
|
||||
'FLE Standard Time' => 'Europe/Kiev',
|
||||
'Falkland' => 'Atlantic/Stanley',
|
||||
'Fiji' => 'Pacific/Fiji',
|
||||
'Fiji Standard Time' => 'Pacific/Fiji',
|
||||
'French_Guiana' => 'America/Cayenne',
|
||||
'French_Southern' => 'Indian/Kerguelen',
|
||||
'Frunze' => 'Asia/Bishkek',
|
||||
'GMT' => 'UTC', // seems better than 'Atlantic/Reykjavik'
|
||||
'GMT Standard Time' => 'Europe/London',
|
||||
'GTB Standard Time' => 'Europe/Istanbul',
|
||||
'Galapagos' => 'Pacific/Galapagos',
|
||||
'Gambier' => 'Pacific/Gambier',
|
||||
'Georgia' => 'Asia/Tbilisi',
|
||||
'Georgian Standard Time' => 'Etc/GMT-3',
|
||||
'Gilbert_Islands' => 'Pacific/Tarawa',
|
||||
'Goose_Bay' => 'America/Goose_Bay',
|
||||
'Greenland Standard Time' => 'America/Godthab',
|
||||
'Greenland_Central' => 'America/Scoresbysund',
|
||||
'Greenland_Eastern' => 'America/Scoresbysund',
|
||||
'Greenland_Western' => 'America/Godthab',
|
||||
'Greenwich Standard Time' => 'Atlantic/Reykjavik',
|
||||
'Guam' => 'Pacific/Guam',
|
||||
'Gulf' => 'Asia/Dubai',
|
||||
'Guyana' => 'America/Guyana',
|
||||
'Hawaii_Aleutian' => 'Pacific/Honolulu',
|
||||
'Hawaiian Standard Time' => 'Pacific/Honolulu',
|
||||
'Hong_Kong' => 'Asia/Hong_Kong',
|
||||
'Hovd' => 'Asia/Hovd',
|
||||
'India' => 'Asia/Calcutta',
|
||||
'India Standard Time' => 'Asia/Calcutta',
|
||||
'Indian_Ocean' => 'Indian/Chagos',
|
||||
'Indochina' => 'Asia/Saigon',
|
||||
'Indonesia_Central' => 'Asia/Makassar',
|
||||
'Indonesia_Eastern' => 'Asia/Jayapura',
|
||||
'Indonesia_Western' => 'Asia/Jakarta',
|
||||
'Iran' => 'Asia/Tehran',
|
||||
'Iran Standard Time' => 'Asia/Tehran',
|
||||
'Irish' => 'Europe/Dublin',
|
||||
'Irkutsk' => 'Asia/Irkutsk',
|
||||
'Israel' => 'Asia/Jerusalem',
|
||||
'Israel Standard Time' => 'Asia/Jerusalem',
|
||||
'Japan' => 'Asia/Tokyo',
|
||||
'Jordan Standard Time' => 'Asia/Amman',
|
||||
'Kamchatka' => 'Asia/Kamchatka',
|
||||
'Karachi' => 'Asia/Karachi',
|
||||
'Kashgar' => 'Asia/Kashgar',
|
||||
'Kazakhstan_Eastern' => 'Asia/Almaty',
|
||||
'Kazakhstan_Western' => 'Asia/Aqtobe',
|
||||
'Kizilorda' => 'Asia/Qyzylorda',
|
||||
'Korea' => 'Asia/Seoul',
|
||||
'Korea Standard Time' => 'Asia/Seoul',
|
||||
'Kosrae' => 'Pacific/Kosrae',
|
||||
'Krasnoyarsk' => 'Asia/Krasnoyarsk',
|
||||
'Kuybyshev' => 'Europe/Samara',
|
||||
'Kwajalein' => 'Pacific/Kwajalein',
|
||||
'Kyrgystan' => 'Asia/Bishkek',
|
||||
'Lanka' => 'Asia/Colombo',
|
||||
'Liberia' => 'Africa/Monrovia',
|
||||
'Line_Islands' => 'Pacific/Kiritimati',
|
||||
'Long_Shu' => 'Asia/Chongqing',
|
||||
'Lord_Howe' => 'Australia/Lord_Howe',
|
||||
'Macau' => 'Asia/Macau',
|
||||
'Magadan' => 'Asia/Magadan',
|
||||
'Malaya' => 'Asia/Kuala_Lumpur',
|
||||
'Malaysia' => 'Asia/Kuching',
|
||||
'Maldives' => 'Indian/Maldives',
|
||||
'Marquesas' => 'Pacific/Marquesas',
|
||||
'Marshall_Islands' => 'Pacific/Majuro',
|
||||
'Mauritius' => 'Indian/Mauritius',
|
||||
'Mauritius Standard Time' => 'Indian/Mauritius',
|
||||
'Mawson' => 'Antarctica/Mawson',
|
||||
'Mexico Standard Time' => 'America/Mexico_City',
|
||||
'Mexico Standard Time 2' => 'America/Chihuahua',
|
||||
'Mid-Atlantic Standard Time' => 'Atlantic/South_Georgia',
|
||||
'Middle East Standard Time' => 'Asia/Beirut',
|
||||
'Mongolia' => 'Asia/Ulaanbaatar',
|
||||
'Montevideo Standard Time' => 'America/Montevideo',
|
||||
'Morocco Standard Time' => 'Africa/Casablanca',
|
||||
'Moscow' => 'Europe/Moscow',
|
||||
'Mountain Standard Time' => 'America/Denver',
|
||||
'Mountain Standard Time (Mexico)' => 'America/Chihuahua',
|
||||
'Myanmar' => 'Asia/Rangoon',
|
||||
'Myanmar Standard Time' => 'Asia/Rangoon',
|
||||
'N. Central Asia Standard Time' => 'Asia/Novosibirsk',
|
||||
'Namibia Standard Time' => 'Africa/Windhoek',
|
||||
'Nauru' => 'Pacific/Nauru',
|
||||
'Nepal' => 'Asia/Katmandu',
|
||||
'Nepal Standard Time' => 'Asia/Katmandu',
|
||||
'New Zealand Standard Time' => 'Pacific/Auckland',
|
||||
'New_Caledonia' => 'Pacific/Noumea',
|
||||
'New_Zealand' => 'Pacific/Auckland',
|
||||
'Newfoundland' => 'America/St_Johns',
|
||||
'Newfoundland Standard Time' => 'America/St_Johns',
|
||||
'Niue' => 'Pacific/Niue',
|
||||
'Norfolk' => 'Pacific/Norfolk',
|
||||
'Noronha' => 'America/Noronha',
|
||||
'North Asia East Standard Time' => 'Asia/Irkutsk',
|
||||
'North Asia Standard Time' => 'Asia/Krasnoyarsk',
|
||||
'North_Mariana' => 'Pacific/Saipan',
|
||||
'Novosibirsk' => 'Asia/Novosibirsk',
|
||||
'Omsk' => 'Asia/Omsk',
|
||||
'Oral' => 'Asia/Oral',
|
||||
'Pacific SA Standard Time' => 'America/Santiago',
|
||||
'Pacific Standard Time' => 'America/Los_Angeles',
|
||||
'Pacific Standard Time (Mexico)' => 'America/Tijuana',
|
||||
'Pakistan' => 'Asia/Karachi',
|
||||
'Pakistan Standard Time' => 'Asia/Karachi',
|
||||
'Palau' => 'Pacific/Palau',
|
||||
'Papua_New_Guinea' => 'Pacific/Port_Moresby',
|
||||
'Paraguay' => 'America/Asuncion',
|
||||
'Peru' => 'America/Lima',
|
||||
'Philippines' => 'Asia/Manila',
|
||||
'Phoenix_Islands' => 'Pacific/Enderbury',
|
||||
'Pierre_Miquelon' => 'America/Miquelon',
|
||||
'Pitcairn' => 'Pacific/Pitcairn',
|
||||
'Ponape' => 'Pacific/Ponape',
|
||||
'Qyzylorda' => 'Asia/Qyzylorda',
|
||||
'Reunion' => 'Indian/Reunion',
|
||||
'Romance Standard Time' => 'Europe/Paris',
|
||||
'Rothera' => 'Antarctica/Rothera',
|
||||
'Russian Standard Time' => 'Europe/Moscow',
|
||||
'SA Eastern Standard Time' => 'Etc/GMT+3',
|
||||
'SA Pacific Standard Time' => 'America/Bogota',
|
||||
'SA Western Standard Time' => 'America/La_Paz',
|
||||
'SE Asia Standard Time' => 'Asia/Bangkok',
|
||||
'Sakhalin' => 'Asia/Sakhalin',
|
||||
'Samara' => 'Europe/Samara',
|
||||
'Samarkand' => 'Asia/Samarkand',
|
||||
'Samoa' => 'Pacific/Apia',
|
||||
'Samoa Standard Time' => 'Pacific/Apia',
|
||||
'Seychelles' => 'Indian/Mahe',
|
||||
'Shevchenko' => 'Asia/Aqtau',
|
||||
'Singapore' => 'Asia/Singapore',
|
||||
'Singapore Standard Time' => 'Asia/Singapore',
|
||||
'Solomon' => 'Pacific/Guadalcanal',
|
||||
'South Africa Standard Time' => 'Africa/Johannesburg',
|
||||
'South_Georgia' => 'Atlantic/South_Georgia',
|
||||
'Sri Lanka Standard Time' => 'Asia/Colombo',
|
||||
'Suriname' => 'America/Paramaribo',
|
||||
'Sverdlovsk' => 'Asia/Yekaterinburg',
|
||||
'Syowa' => 'Antarctica/Syowa',
|
||||
'Tahiti' => 'Pacific/Tahiti',
|
||||
'Taipei' => 'Asia/Taipei',
|
||||
'Taipei Standard Time' => 'Asia/Taipei',
|
||||
'Tajikistan' => 'Asia/Dushanbe',
|
||||
'Tashkent' => 'Asia/Tashkent',
|
||||
'Tasmania Standard Time' => 'Australia/Hobart',
|
||||
'Tbilisi' => 'Asia/Tbilisi',
|
||||
'Tokelau' => 'Pacific/Fakaofo',
|
||||
'Tokyo Standard Time' => 'Asia/Tokyo',
|
||||
'Tonga' => 'Pacific/Tongatapu',
|
||||
'Tonga Standard Time' => 'Pacific/Tongatapu',
|
||||
'Truk' => 'Pacific/Truk',
|
||||
'Turkey' => 'Europe/Istanbul',
|
||||
'Turkmenistan' => 'Asia/Ashgabat',
|
||||
'Tuvalu' => 'Pacific/Funafuti',
|
||||
'US/Eastern' => 'America/New_York',
|
||||
'US Eastern Standard Time' => 'Etc/GMT+5',
|
||||
'US Mountain Standard Time' => 'America/Phoenix',
|
||||
'Uralsk' => 'Asia/Oral',
|
||||
'Uruguay' => 'America/Montevideo',
|
||||
'Urumqi' => 'Asia/Urumqi',
|
||||
'Uzbekistan' => 'Asia/Tashkent',
|
||||
'Vanuatu' => 'Pacific/Efate',
|
||||
'Venezuela' => 'America/Caracas',
|
||||
'Venezuela Standard Time' => 'America/Caracas',
|
||||
'Vladivostok' => 'Asia/Vladivostok',
|
||||
'Vladivostok Standard Time' => 'Asia/Vladivostok',
|
||||
'Volgograd' => 'Europe/Volgograd',
|
||||
'Vostok' => 'Antarctica/Vostok',
|
||||
'W. Australia Standard Time' => 'Australia/Perth',
|
||||
'W. Central Africa Standard Time' => 'Africa/Lagos',
|
||||
'W. Europe Standard Time' => 'Europe/Berlin',
|
||||
'Wake' => 'Pacific/Wake',
|
||||
'Wallis' => 'Pacific/Wallis',
|
||||
'West Asia Standard Time' => 'Asia/Tashkent',
|
||||
'West Pacific Standard Time' => 'Pacific/Port_Moresby',
|
||||
'Yakutsk' => 'Asia/Yakutsk',
|
||||
'Yakutsk Standard Time' => 'Asia/Yakutsk',
|
||||
'Yekaterinburg' => 'Asia/Yekaterinburg',
|
||||
'Yerevan' => 'Asia/Yerevan',
|
||||
'Yukon' => 'America/Yakutat',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array Map of timezones acceptable by DateTimeZone but not strtotime.
|
||||
*/
|
||||
protected $_invalid_legacy = array(
|
||||
'US/Eastern' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array|bool List of system identifiers or false if none available.
|
||||
*/
|
||||
protected $_identifiers = false;
|
||||
|
||||
/**
|
||||
* Initialize local cache and identifiers.
|
||||
*
|
||||
* @param Ai1ec_Registry_Object $registry Registry to use.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( Ai1ec_Registry_Object $registry ) {
|
||||
parent::__construct( $registry );
|
||||
$this->_cache = $this->_registry->get( 'cache.memory' );
|
||||
$this->_init_identifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default timezone to use in input/output.
|
||||
*
|
||||
* Approach is as follows:
|
||||
* - check user profile for timezone preference;
|
||||
* - if user has no preference - check site for timezone selection;
|
||||
* - if site has no selection - raise notice and use 'UTC'.
|
||||
*
|
||||
* @return string Olson timezone string identifier.
|
||||
*/
|
||||
public function get_default_timezone() {
|
||||
static $default_timezone = null;
|
||||
if ( null === $default_timezone ) {
|
||||
$candidates = array();
|
||||
$candidates[] = (string)$this->_registry->get( 'model.meta-user' )
|
||||
->get_current( 'ai1ec_timezone' );
|
||||
$candidates[] = (string)$this->_registry->get( 'model.option' )
|
||||
->get( 'timezone_string' );
|
||||
$candidates[] = (string)$this->_registry->get( 'model.option' )
|
||||
->get( 'gmt_offset' );
|
||||
$candidates = array_filter( $candidates, 'strlen' );
|
||||
foreach ( $candidates as $timezone ) {
|
||||
$timezone = $this->get_name( $timezone );
|
||||
if ( false !== $timezone ) {
|
||||
$default_timezone = $timezone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( null === $default_timezone ) {
|
||||
$default_timezone = 'UTC';
|
||||
$this->_registry->get( 'notification.admin' )->store(
|
||||
sprintf(
|
||||
Ai1ec_I18n::__(
|
||||
'Please select site timezone in %s <em>Timezone</em> dropdown menu.'
|
||||
),
|
||||
'<a href="' . ai1ec_admin_url( 'options-general.php' ) .
|
||||
'">' . Ai1ec_I18n::__( 'Settings' ) . '</a>'
|
||||
),
|
||||
'error'
|
||||
);
|
||||
}
|
||||
}
|
||||
return $default_timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to decode GMT offset to some Olson timezone.
|
||||
*
|
||||
* @param float $zone GMT offset.
|
||||
*
|
||||
* @return string Valid Olson timezone name (UTC is last resort).
|
||||
*/
|
||||
public function decode_gmt_timezone( $zone ) {
|
||||
$auto_zone = timezone_name_from_abbr( null, $zone * 3600, true );
|
||||
if ( false !== $auto_zone ) {
|
||||
return $auto_zone;
|
||||
}
|
||||
$auto_zone = timezone_name_from_abbr(
|
||||
null,
|
||||
( (int) $zone ) * 3600,
|
||||
true
|
||||
);
|
||||
if ( false !== $auto_zone ) {
|
||||
return $auto_zone;
|
||||
}
|
||||
$this->_registry->get( 'notification.admin' )->store(
|
||||
sprintf(
|
||||
Ai1ec_I18n::__(
|
||||
'Timezone "UTC%+d" is not recognized. Please %suse valid%s timezone name, until then events will be created in UTC timezone.'
|
||||
),
|
||||
$zone,
|
||||
'<a href="' . ai1ec_admin_url( 'options-general.php' ) . '">',
|
||||
'</a>'
|
||||
),
|
||||
'error'
|
||||
);
|
||||
return 'UTC';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get valid timezone name from input.
|
||||
*
|
||||
* @param string $zone Name to check/parse.
|
||||
*
|
||||
* @return string Timezone name to use
|
||||
*/
|
||||
public function get_name( $zone ) {
|
||||
if ( is_numeric( $zone ) ) {
|
||||
$decoded_zone = $this->decode_gmt_timezone( $zone );
|
||||
if ( 'UTC' !== $decoded_zone ) {
|
||||
$message = sprintf(
|
||||
Ai1ec_I18n::__(
|
||||
'Selected timezone "UTC%+d" will be treated as %s.'
|
||||
),
|
||||
$zone,
|
||||
$decoded_zone
|
||||
);
|
||||
$this->_registry->get( 'notification.admin' )
|
||||
->store( $message );
|
||||
}
|
||||
$zone = $decoded_zone;
|
||||
}
|
||||
if ( false === $this->_identifiers ) {
|
||||
return $zone; // anything should do, as zones are not supported
|
||||
}
|
||||
if ( ! isset( $this->_identifiers[$zone] ) ) {
|
||||
$zone = $this->_olson_lookup( $zone );
|
||||
$valid_legacy = false;
|
||||
try {
|
||||
new DateTimeZone( $zone ); // throw away instantly
|
||||
$valid_legacy = true;
|
||||
} catch ( Exception $excpt ) {
|
||||
$valid_legacy = false;
|
||||
}
|
||||
if ( ! $valid_legacy || isset( $this->_invalid_legacy[$zone] ) ) {
|
||||
return $this->guess_zone( $zone );
|
||||
}
|
||||
$this->_identifiers[$zone] = $zone;
|
||||
unset( $valid_legacy );
|
||||
}
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick map look-up to discard zones that have limited recognition.
|
||||
*
|
||||
* @param string $zone Name of timezone to lookup.
|
||||
*
|
||||
* @return string Timezone name to use. Might be the same as $zone.
|
||||
*/
|
||||
protected function _olson_lookup( $zone ) {
|
||||
if ( isset( $this->_zones[$zone] ) ) {
|
||||
return $this->_zones[$zone];
|
||||
}
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if timezone is set in wp_option
|
||||
*
|
||||
*/
|
||||
public function is_timezone_not_set() {
|
||||
$timezone = $this->_registry->get( 'model.option' )
|
||||
->get( 'timezone_string' );
|
||||
return empty( $timezone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render options for select in settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_timezones( $only_zones = false ) {
|
||||
$zones = DateTimeZone::listIdentifiers();
|
||||
if (
|
||||
empty( $zones )
|
||||
) {
|
||||
return array();
|
||||
}
|
||||
if ( ! $only_zones ) {
|
||||
$manual = __( 'Manual Offset', AI1EC_PLUGIN_NAME );
|
||||
$options = array();
|
||||
$options[$manual][] = array(
|
||||
'text' => __( 'Choose your timezone', AI1EC_PLUGIN_NAME ),
|
||||
'value' => '',
|
||||
'args' => array(
|
||||
'selected' => 'selected'
|
||||
)
|
||||
);
|
||||
}
|
||||
foreach ( $zones as $zone ) {
|
||||
$exploded_zone = explode( '/', $zone );
|
||||
if ( ! isset( $exploded_zone[1] ) && ! $only_zones ) {
|
||||
$exploded_zone[1] = $exploded_zone[0];
|
||||
$exploded_zone[0] = $manual;
|
||||
}
|
||||
$optgroup = $exploded_zone[0];
|
||||
unset( $exploded_zone[0] );
|
||||
$options[$optgroup][] = array(
|
||||
'text' => implode( '/', $exploded_zone ),
|
||||
'value' => $zone,
|
||||
);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess valid timezone identifier from arbitrary input.
|
||||
*
|
||||
* @param string $meta_name Arbitrary input.
|
||||
*
|
||||
* @return string|bool Parsed timezone name or false if none found.
|
||||
*/
|
||||
public function guess_zone( $meta_name ) {
|
||||
if ( isset( $this->_zones[$meta_name] ) ) {
|
||||
return $this->_zones[$meta_name];
|
||||
}
|
||||
$name_variants = array(
|
||||
strtr( $meta_name, ' ', '_' ),
|
||||
strtr( $meta_name, '_', ' ' ),
|
||||
);
|
||||
if ( false !== ( $parenthesis_pos = strpos( $meta_name, '(' ) ) ) {
|
||||
foreach ( $name_variants as $name ) {
|
||||
$name_variants[] = substr( $name, 0, $parenthesis_pos - 1 );
|
||||
}
|
||||
}
|
||||
foreach ( $name_variants as $name ) {
|
||||
if ( isset( $this->_zones[$name] ) ) {
|
||||
// cache to avoid future lookups and return
|
||||
$this->_zones[$meta_name] = $this->_zones[$name];
|
||||
return $this->_zones[$name];
|
||||
}
|
||||
}
|
||||
if (
|
||||
isset( $meta_name{0} ) &&
|
||||
'(' === $meta_name{0} &&
|
||||
$closing_pos = strpos( $meta_name, ')' )
|
||||
) {
|
||||
$meta_name = trim( substr( $meta_name, $closing_pos + 1 ) );
|
||||
return $this->guess_zone( $meta_name );
|
||||
}
|
||||
if (
|
||||
false === strpos( $meta_name, ' Standard ' ) &&
|
||||
false !== ( $time_pos = strpos( $meta_name, ' Time' ) )
|
||||
) {
|
||||
$meta_name = substr( $meta_name, 0, $time_pos ) .
|
||||
' Standard' . substr( $meta_name, $time_pos );
|
||||
return $this->guess_zone( $meta_name );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone object instance.
|
||||
*
|
||||
* @param string $timezone Name of timezone to get instance for.
|
||||
*
|
||||
* @return DateTimeZone Instance of timezone object.
|
||||
*
|
||||
* @throws Ai1ec_Date_Timezone_Exception If an error occurs.
|
||||
*/
|
||||
public function get( $timezone ) {
|
||||
if ( 'sys.default' === $timezone ) {
|
||||
$timezone = $this->get_default_timezone();
|
||||
}
|
||||
$name = $this->get_name( $timezone );
|
||||
if ( ! $name ) {
|
||||
$name = $this->get_name( $this->get_default_timezone() );
|
||||
}
|
||||
$zone = $this->_cache->get( $name, null );
|
||||
if ( null === $zone ) {
|
||||
$exception = null;
|
||||
try {
|
||||
$zone = new DateTimeZone( $name );
|
||||
} catch ( Exception $invalid_tz ) {
|
||||
$exception = $invalid_tz;
|
||||
}
|
||||
if ( null !== $exception ) {
|
||||
throw new Ai1ec_Date_Timezone_Exception( $exception->getMessage() );
|
||||
}
|
||||
$this->_cache->set( $name, $zone );
|
||||
}
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add system identifiers to object registry.
|
||||
*
|
||||
* @return bool Success
|
||||
*/
|
||||
protected function _init_identifiers() {
|
||||
$identifiers = DateTimeZone::listIdentifiers();
|
||||
if ( ! $identifiers ) {
|
||||
return false;
|
||||
}
|
||||
$mapped = array();
|
||||
foreach ( $identifiers as $zone ) {
|
||||
$zone = (string)$zone;
|
||||
$mapped[$zone] = true;
|
||||
$this->_zones[$zone] = $zone;
|
||||
}
|
||||
unset( $identifiers, $zone );
|
||||
$this->_identifiers = $mapped;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validation utility library
|
||||
*
|
||||
* @author Timely Network Inc
|
||||
* @since 2012.08.21
|
||||
*
|
||||
* @package AllInOneCalendar
|
||||
* @subpackage AllInOneCalendar.Lib.Utility
|
||||
*/
|
||||
class Ai1ec_Validation_Utility {
|
||||
|
||||
/**
|
||||
* Check if the date supplied is valid. It validates $date in the format given
|
||||
* by $pattern, which matches one of the supported date patterns.
|
||||
*
|
||||
* @param string $date Date string to validate
|
||||
* @param string $pattern Key of date pattern (@see
|
||||
* self::get_date_patterns()) to
|
||||
* match date string against
|
||||
* @return boolean
|
||||
*/
|
||||
static public function validate_date( $date, $pattern = 'def' ) {
|
||||
$result = self::validate_date_and_return_parsed_date( $date, $pattern );
|
||||
if( $result === false ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the date supplied is valid. It validates date in the format given
|
||||
* by $pattern, which matches one of the supported date patterns.
|
||||
*
|
||||
* @param string $date Date string to parse
|
||||
* @param string $pattern Key of date pattern (@see
|
||||
* self::get_date_patterns()) to
|
||||
* match date string against
|
||||
* @return array|boolean An array with the parsed date or false if the date
|
||||
* is not valid.
|
||||
*/
|
||||
static public function validate_date_and_return_parsed_date(
|
||||
$date, $pattern = 'def'
|
||||
) {
|
||||
$pattern = self::_get_pattern_regexp( $pattern );
|
||||
if ( preg_match( $pattern, $date, $matches ) ) {
|
||||
if ( checkdate( $matches['m'], $matches['d'], $matches['y'] ) ) {
|
||||
return array(
|
||||
'month' => $matches['m'],
|
||||
'day' => $matches['d'],
|
||||
'year' => $matches['y'],
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert input into a valid ISO date.
|
||||
*
|
||||
* @param string $date Date to convert to ISO.
|
||||
* @param string $pattern Format used to store it.
|
||||
*
|
||||
* @return string|bool Re-formatted date or false on failure.
|
||||
*/
|
||||
static public function format_as_iso( $date, $pattern = 'def' ) {
|
||||
$regexp = self::_get_pattern_regexp( $pattern );
|
||||
if ( ! preg_match( $regexp, $date, $matches ) ) {
|
||||
return false;
|
||||
}
|
||||
return sprintf(
|
||||
'%04d-%02d-%02d',
|
||||
$matches['y'],
|
||||
$matches['m'],
|
||||
$matches['d']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create regexp with named groups to match positional elements.
|
||||
*
|
||||
* @param string $pattern Pattern to convert.
|
||||
*
|
||||
* @return string Regular expression pattern.
|
||||
*/
|
||||
static protected function _get_pattern_regexp( $pattern ) {
|
||||
$pattern = self::get_date_pattern_by_key( $pattern );
|
||||
$pattern = preg_quote( $pattern, '/' );
|
||||
$pattern = str_replace(
|
||||
array( 'dd', 'd', 'mm', 'm', 'yyyy', 'yy' ),
|
||||
array( '(?P<d>\d{2})', '(?P<d>\d{1,2})', '(?P<m>\d{2})', '(?P<m>\d{1,2})', '(?P<y>\d{4})', '(?P<y>\d{2})' ),
|
||||
$pattern
|
||||
);
|
||||
// Accept hyphens and dots in place of forward slashes (for URLs).
|
||||
$pattern = str_replace( '\/', '[\/\-\.]', $pattern );
|
||||
return '#^' . $pattern . '$#';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the string or integer is a valid timestamp.
|
||||
*
|
||||
* @see http://stackoverflow.com/questions/2524680/check-whether-the-string-is-a-unix-timestamp
|
||||
* @param string|int $timestamp
|
||||
* @return boolean
|
||||
*/
|
||||
static public function is_valid_time_stamp( $timestamp ) {
|
||||
return
|
||||
(
|
||||
is_int( $timestamp ) ||
|
||||
( (string)(int)$timestamp ) === (string)$timestamp
|
||||
)
|
||||
&& ( $timestamp <= PHP_INT_MAX )
|
||||
&& ( $timestamp >= 0 /*~ PHP_INT_MAX*/ );
|
||||
// do not allow negative timestamps until this is widely accepted
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the associative array of date patterns supported by the plugin,
|
||||
* currently:
|
||||
* array(
|
||||
* 'def' => 'd/m/yyyy',
|
||||
* 'us' => 'm/d/yyyy',
|
||||
* 'iso' => 'yyyy-m-d',
|
||||
* 'dot' => 'm.d.yyyy',
|
||||
* );
|
||||
*
|
||||
* 'd' or 'dd' represent the day, 'm' or 'mm' represent the month, and 'yy'
|
||||
* or 'yyyy' represent the year.
|
||||
*
|
||||
* @return array Supported date patterns
|
||||
*/
|
||||
static public function get_date_patterns() {
|
||||
return array(
|
||||
'def' => 'd/m/yyyy',
|
||||
'us' => 'm/d/yyyy',
|
||||
'iso' => 'yyyy-m-d',
|
||||
'dot' => 'm.d.yyyy',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date pattern (in the form 'd-m-yyyy', for example) associated
|
||||
* with the provided key, used by plugin settings. Simply a static map as
|
||||
* follows:
|
||||
*
|
||||
* @param string $key Key for the date format
|
||||
* @return string Associated date format pattern
|
||||
*/
|
||||
static public function get_date_pattern_by_key( $key = 'def' ) {
|
||||
$patterns = self::get_date_patterns();
|
||||
return $patterns[$key];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user