e107_handlers/date_handler.php
<?php
/*
* e107 website system
*
* Copyright (C) 2008-2009 e107 Inc (e107.org)
* Released under the terms and conditions of the
* GNU General Public License (http://gnu.org).
*
*/
if (!defined('e107_INIT')) { exit; }
//e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE."/lan_date.php");
e107::coreLan('date');
/**
*
*/
class e_date
{
function __construct()
{
}
/**
* Build the datetimepicker() locale, since it must match strftime() values for accurate conversion.
*/
function buildDateLocale()
{
$text = '
(function($){
$.fn.datetimepicker.dates["'.e_LAN.'"] = {';
$dates = array();
for ($i=1; $i < 8; $i++)
{
$day = eShims::strftime('%A', mktime(1, 1, 1, 1, $i, 2012));
$dates['days'][] = $day;
$dates['daysShort'][] = eShims::strftime('%a', mktime(1, 1, 1, 1, $i, 2012));
$dates['daysMin'][] = substr($day, 0, 2);
}
for ($i=1; $i < 13; $i++)
{
$dates['months'][] = eShims::strftime('%B', mktime(1, 1, 1, $i, 2, 2013));
$dates['monthsShort'][] = eShims::strftime('%h', mktime(1, 1, 1, $i, 2, 2013));
}
foreach($dates as $key=>$type)
{
$d = array();
$text .= "\n".$key.": [";
foreach($type as $val)
{
$d[] = '"'.$val.'"';
}
$text .= implode(",",$d);
$text .= "],";
}
$text .= '
meridiem: ["am", "pm"]
};
}(jQuery));';
return $text;
}
/**
* Return an array of language terms representing months
* @param $type string : month, month-short, day, day-short, day-shortest
* @return array|bool
*/
public function terms($type='month')
{
if($type == 'month' || $type == 'month-short')
{
$val = ($type == 'month-short') ? '%b' : '%B'; //eg. 'Aug' / 'August'
$marray = array();
for ($i = 1; $i < 13; $i++)
{
$marray[$i] = eShims::strftime($val, mktime(1, 1, 1, $i, 1, 2000));
}
return $marray;
}
if(strpos($type, 'day') === 0)
{
$days = array();
for ($i=2; $i < 9; $i++)
{
switch ($type)
{
case 'day-shortest': // eg. 'Tu'
$days[] = substr(eShims::strftime('%a', mktime(1, 1, 1, 6, $i, 2014)), 0, 2);
break;
case 'day-short': // eg. 'Tue'
$days[] = eShims::strftime('%a', mktime(1, 1, 1, 6, $i, 2014));
break;
default: // eg. 'Tuesday'
$days[] = eShims::strftime('%A', mktime(1, 1, 1, 6, $i, 2014));
break;
}
}
return $days;
}
return false;
}
/**
* Convert datestamp to human readable date.
* System time offset is considered.
*
* @param integer $datestamp unix stamp
* @param string $mask [optional] long|short|forum|relative or any strftime() valid string
*
* @return string parsed date
*/
function convert_date($datestamp, $mask = '')
{
$datestamp = (int) $datestamp;
if($datestamp == 0) return "";
if(empty($mask))
{
$mask = 'long';
}
switch($mask)
{
case 'long':
$mask = e107::getPref('longdate');
// $datestamp += TIMEOFFSET;
break;
case 'short':
$mask = e107::getPref('shortdate');
// $datestamp += TIMEOFFSET;
break;
case 'input':
case 'inputdate':
$mask = e107::getPref('inputdate', '%d/%m/%Y %H:%M');
// $mask .= " ".e107::getPref('inputtime', '%H:%M');
break;
case 'inputdatetime':
$mask = e107::getPref('inputdate', '%d/%m/%Y %H:%M');
$mask .= " ".e107::getPref('inputtime', '%H:%M');
break;
case 'inputtime':
$mask = e107::getPref('inputtime', '%H:%M');
break;
case 'forum': // DEPRECATED - temporary here from BC reasons only
// default:
//BC - old 'forum' call
if(strpos($mask, '%') === FALSE)
{
$mask = e107::getPref('forumdate');
}
// $datestamp += TIMEOFFSET;
break;
case 'relative':
return $this->computeLapse($datestamp, time(), false, true, 'short') ;
break;
default:
if(strpos($mask, '%') === FALSE)
{
$mask = $this->toMask($mask,true);
}
break;
}
$dateString = eShims::strftime($mask, $datestamp);
if (!e107::getParser()->isUTF8($dateString))
{
$dateString = utf8_encode($dateString);
}
return $dateString;
}
/**
* @deprecated - for internal use only.
* @see $tp->toDate() as a replacement.
* Converts between unix timestamp and human-readable date-time OR vice-versa. (auto-detected)
* @param string $string unix timestamp OR human-readable date-time.
* @param string $mask (optional) long | short | input
* @return bool|int|string
*/
function convert($string=null, $mask = 'inputdate')
{
trigger_error('<b>'.__METHOD__.' is deprecated.</b> Use $tp->toDate() instead.', E_USER_DEPRECATED); // NO LAN
if($string == null) return false;
return is_numeric($string) ? $this->convert_date($string, $mask) : $this->toTime($string, $mask);
}
/**
* Converts to new date-mask format or vice-versa when $legacy is TRUE
*
* string $mask
* string|bool $legacy false= strftime > datetimepicker, true = datetimepicker > strftime, 'DateTime' = strftime > DateTime format.
* @see https://secure.php.net/manual/en/function.strftime.php
* @see https://github.com/AuspeXeu/bootstrap-datetimepicker
* @see https://secure.php.net/manual/en/datetime.createfromformat.php
*/
function toMask($mask, $legacy = false)
{
//strftime() -> datetimepicker format.
$convert = array(
'%Y' => 'yyyy', // Year 4-digits '2013'
'%d' => 'dd', // day of the month 2-digits
'%m' => 'mm', // month number 2-digits
'%B' => 'MM', // Full month name, based on the locale
'%A' => 'DD', // A full textual representation of the day
'%y' => 'yy',
'%a' => 'D', // An abbreviated textual representation of the day
'%b' => 'M', // Abbreviated month name, based on the locale
'%h' => 'M', // Abbreviated month name, based on the locale (an alias of %b)
'%I' => 'HH', // Two digit representation of the hour in 12-hour format
'%l' => 'H', // 12 hour format - no leading zero
'%H' => 'hh', // 24 hour format - leading zero
'%M' => 'ii', // Two digit representation of the minute
'%S' => 'ss', // Two digit representation of the second
'%P' => 'p', // %P lower-case 'am' or 'pm' based on the given time
'%p' => 'P', // %p UPPER-CASE 'AM' or 'PM' based on the given time
'%T' => 'hh:mm:ss',
'%r' => "hh:mmm:ss TT" // 12 hour format
);
// strftime() > DateTime::
if($legacy === 'DateTime')
{
$convert = array(
'%Y' => 'Y', // Year 4-digits '2013'
'%d' => 'd', // Two-digit day of the month (with leading zeros) (01 through 31)
'%e' => 'j', // Day of the month, with a space preceding single digits. Not implemented on Windows with strftime.
'%m' => 'm', // Two digit representation of the month (01 throught 12)
'%B' => 'F', // Full month name, based on the locale
'%A' => 'l', // A full textual representation of the day
'%y' => 'y',
'%a' => 'D', // An abbreviated textual representation of the day
'%b' => 'M', // Abbreviated month name, based on the locale
'%h' => 'M', // Abbreviated month name, based on the locale (an alias of %b)
'%k' => 'G', // Hour in 24-hour format, with a space preceding single digits (0 through 23)
'%I' => 'h', // Two digit representation of the hour in 12-hour format ( 01 through 12)
'%l' => 'g', // 12 hour format - no leading zero (1 through 12)
'%H' => 'H', // Two digit representation of the hour in 24-hour format (00 through 23)
'%M' => 'i', // Two digit representation of the minute (00 through 59)
'%S' => 's', // Two digit representation of the second (00 through 59)
'%P' => 'a', // lower-case 'am' or 'pm' based on the given time
'%p' => 'A', // UPPER-CASE 'AM' or 'PM' based on the given time
'%Z' => 'e', // The time zone abbreviation. Not implemented as described on Windows with strftime.
// TODO Add anything that is missing.
// '%T' => 'hh:mm:ss',
// '%r' => "hh:mmm:ss TT" // 12 hour format
);
}
$s = array_keys($convert);
$r = array_values($convert);
if(strpos($mask, '%') === false && $legacy === true)
{
$ret = str_replace($r, $s,$mask);
return str_replace('%%p', '%P', $ret); // quick fix.
}
elseif(strpos($mask,'%')!==false)
{
return str_replace($s,$r, $mask);
}
return $mask;
// Keep this info here:
/*
* $options allowed keys:
*
* d - day of month (no leading zero)
dd - day of month (two digit)
o - day of the year (no leading zeros)
oo - day of the year (three digit)
D - day name short
DD - day name long
m - month of year (no leading zero)
mm - month of year (two digit)
M - month name short
MM - month name long
y - year (two digit)
yy - year (four digit)
@ - Unix timestamp (ms since 01/01/1970)
! - Windows ticks (100ns since 01/01/0001)
'...' - literal text
'' - single quote
anything else - literal text
ATOM - 'yy-mm-dd' (Same as RFC 3339/ISO 8601)
COOKIE - 'D, dd M yy'
ISO_8601 - 'yy-mm-dd'
RFC_822 - 'D, d M y' (See RFC 822)
RFC_850 - 'DD, dd-M-y' (See RFC 850)
RFC_1036 - 'D, d M y' (See RFC 1036)
RFC_1123 - 'D, d M yy' (See RFC 1123)
RFC_2822 - 'D, d M yy' (See RFC 2822)
RSS - 'D, d M y' (Same as RFC 822)
TICKS - '!'
TIMESTAMP - '@'
W3C - 'yy-mm-dd' (Same as ISO 8601)
*
* h Hour with no leading 0
* hh Hour with leading 0
* m Minute with no leading 0
* mm Minute with leading 0
* s Second with no leading 0
* ss Second with leading 0
* l Milliseconds always with leading 0
* t a or p for AM/PM
* T A or P for AM/PM
* tt am or pm for AM/PM
* TT AM or PM for AM/PM
*/
}
/**
* Convert date string back to integer (unix timestamp)
* NOTE: after some tests, strptime (compat mode) is adding +1 sec. after parsing to time, investigate!
*
* @param string $date_string
* @param string $mask [optional]
* @return integer
*/
function toTime($date_string, $mask = 'input')
{
switch($mask)
{
case 'long':
$mask = e107::getPref('longdate');
break;
case 'short':
$mask = e107::getPref('shortdate');
break;
case 'input':
case 'inputdate':
$mask = e107::getPref('inputdate', '%Y/%m/%d');
break;
case 'inputdatetime':
$mask = e107::getPref('inputdate', '%Y/%m/%d');
$mask .= " ".e107::getPref('inputtime', '%H:%M');
break;
case 'inputtime':
$mask = e107::getPref('inputtime', '%H:%M');
break;
}
// convert to PHP 5+ @see https://secure.php.net/manual/en/datetime.createfromformat.php
$newMask = $this->toMask($mask, 'DateTime');
$tdata = date_parse_from_format($newMask, $date_string);
return mktime(
$tdata['hour'],
$tdata['minute'],
$tdata['second'],
$tdata['month'] ,
$tdata['day'],
$tdata['year']
);
// also in php compat handler for plugins that might use it.
/*
$tdata = $this->strptime($date_string, $mask);
if(empty($tdata))
{
if(!empty($date_string) && ADMIN)
{
e107::getMessage()->addDebug( "PROBLEM WITH CONVERSION from ".$date_string." to unix timestamp");
}
return null;
}
if(STRPTIME_COMPAT !== TRUE) // returns months from 0 - 11 on Unix so we need to +1
{
$tdata['tm_mon'] = $tdata['tm_mon'] +1;
}
$unxTimestamp = mktime(
$tdata['tm_hour'],
$tdata['tm_min'],
$tdata['tm_sec'],
$tdata['tm_mon'] ,
$tdata['tm_mday'],
($tdata['tm_year'] + 1900)
);
return $unxTimestamp;
*/
}
// -----------------------
/**
* Tolerant date/time input routine - doesn't force use of specific delimiters, and can sometimes allow no delimiters at all
* The format string defines the critical day/month/year order.
* As examples, with suitable format specifiers all of the following will be interpreted into valid (and sensible) dates/times:
* 09122003 153045 -> 9-12-03 at 15:30:45 (requires dmy or mdy format specifier)
* 20031209 12:30:32 -> 9-12-03 at 12:30:32 (requires ymd specifier)
* 091203 1530 -> 9-12-09 at 15:30:00
* 9/12/3 12 -> 9-12-09 at 12:00:00
* 6-3/4 15-45:27 -> 6-3-04 at 15:45:27
*
* @param string $input - usually date/time string with numeric values for relevant fields, and almost any separator. e.g. dd-mm-yy hh:mm
* Date and time must be separated by one or more spaces. In times, minutes and seconds are optional, and default to zero
* One special value is allowed - 'now'
* @param string $decode - one of 'date', 'time', 'datetime', 'timedate'
* @param string $format - sets field order for dates. Valid strings are dmy, mdy, ymd. Add suffix 'z' to return UTC/GMT
* @param boolean $endDay - if TRUE, and no time entered, includes a time of 23:59:59 in the entered date
*
* @return integer time stamp. returns zero on any error
*/
public function decodeDateTime($input, $decode = 'date', $format = 'dmy', $endDay = FALSE)
{
if ($input == 'now') return time(); // Current time TODO: option to return UTC or local time here
$useLocale = TRUE;
if (substr($format,-1,1) == 'z')
{
$useLocale = FALSE;
$format = substr($format,0,-1); // Remove local disable string
}
switch ($decode)
{
case 'date' :
$timeString = '';
$dateString = $input;
break;
case 'time' :
$timeString = $input;
$dateString = '';
break;
case 'datetime' : // Date then time, separated by space
$input = str_replace(' ',' ', $input);
list($dateString, $timeString) = explode(' ',$input,2);
break;
case 'timedate' : // Time then date, separated by space
$input = str_replace(' ',' ', $input);
list($timeString, $dateString) = explode(' ',$input,2);
break;
default :
return 0;
}
$timeString = trim($timeString);
$dateString = trim($dateString);
$dateVals = array (1 => 0, 2 => 0, 3 => 0); // Preset date in case
$timeVals = array (1 => 0, 2 => 0, 3 => 0); // Preset time in case
if ($dateString)
{
if (is_numeric($dateString))
{
if (strlen($dateString) == 6)
{ // Probably fixed format numeric without separators
$dateVals = array(1 => substr($dateString,0,2), 2 => substr($dateString,2,2), 3 => substr($dateString,-2));
}
elseif (strlen($dateString) == 8)
{ // Trickier - year may be first or last!
if ($format == 'ymd')
{
$dateVals = array(1 => substr($dateString,0,4), 2 => substr($dateString,4,2), 3 => substr($dateString,-2));
}
else
{
$dateVals = array(1 => substr($dateString,0,2), 2 => substr($dateString,2,2), 3 => substr($dateString,-4));
}
}
}
else
{ // Assume standard 'nn-nn-nn', 'nnnn-nn-nn' or 'nn-nn-nnnn' type format
if (!preg_match('#(\d{1,4})\D(\d{1,2})\D(\d{1,4})#', $dateString, $dateVals))
{
return 0; // Can't decode date
}
}
}
if ($timeString)
{
if (is_numeric($timeString))
{
if (strlen($timeString) == 6)
{ // Assume hhmmss
$timeVals = array(1 => substr($timeString,0,2), 2 => substr($timeString,2,2), 3 => substr($timeString,-2));
}
elseif (strlen($timeString) == 4)
{ // Assume hhmm
$timeVals = array(1 => substr($timeString,0,2), 2 => substr($timeString,-2), 3 => 0);
}
else
{ // Hope its just hours!
if ($timeString < 24)
{
$timeVals[1] = $timeString;
}
}
}
else
{
preg_match('#(\d{1,2})(?:\D(\d{1,2}))?(?:\D(\d{1,2}))?#', $timeString, $timeVals);
}
}
elseif ($endDay)
{
$timeVals = array (1 => 23, 2 => 59, 3 => 59); // Last second of day
}
// Got all the values now - the rest is simple!
switch ($format)
{
case 'dmy' :
$month = $dateVals[2]; $day = $dateVals[1]; $year = $dateVals[3]; break;
case 'mdy' :
$month = $dateVals[1]; $day = $dateVals[2]; $year = $dateVals[3]; break;
case 'ymd' :
$month = $dateVals[2]; $day = $dateVals[3]; $year = $dateVals[1]; break;
default :
echo "Unsupported format string: {$format}<br />";
return 0;
}
if ($useLocale)
{
return mktime($timeVals[1], $timeVals[2], $timeVals[3], $month, $day, $year);
}
return gmmktime($timeVals[1], $timeVals[2], $timeVals[3], $month, $day, $year);
}
/**
* Calculate difference between two dates for display in terms of years/months/weeks....
*
* @param integer $older_date - time stamp
* @param integer|boolean $newer_date - time stamp. Defaults to current time if FALSE
* @param boolean $mode -if TRUE, return value is an array. Otherwise return value is a string
* @param boolean $show_secs
* @param string $format - controls display format. 'short' misses off year. 'long' includes everything
* @return array|string according to $mode, array or string detailing the time difference
*/
function computeLapse($older_date, $newer_date = FALSE, $mode = FALSE, $show_secs = TRUE, $format = 'long')
{
$older_date = (int) $older_date;
if($older_date == 0) return "";
if(empty($newer_date))
{
$newer_date = time();
}
if($format === 'short')
{
$sec = LANDT_09;
$secs = LANDT_09s;
$min = LANDT_08;
$mins = LANDT_08s;
}
else
{
$sec = LANDT_07;
$secs = LANDT_07s;
$min = LANDT_06;
$mins = LANDT_06s;
}
$dateString1 = date("Y-m-d H:i:s", $older_date);
$dateString2 = date("Y-m-d H:i:s", $newer_date);
$date1 = new DateTime($dateString1);
$date2 = new DateTime($dateString2);
$interval = $date1->diff($date2);
$result = array(
'years' => array($interval->y, LANDT_01,LANDT_01s),
'months' => array($interval->m, LANDT_02, LANDT_02s),
'weeks' => array(floor($interval->d/7), LANDT_03, LANDT_03s),
'days' => array($interval->d % 7,LANDT_04, LANDT_04s),
'hours' => array($interval->h, LANDT_05, LANDT_05s),
'minutes' => array($interval->i, $min, $mins),
'seconds' => array($interval->s, $sec, $secs),
);
if($show_secs !== true)
{
unset($result['seconds']);
}
$ret = array();
foreach($result as $val)
{
if($val[0] < 1)
{
continue;
}
$ret[] = ($val[0] == 1) ? $val[0]." ".$val[1] : $val[0]." ".$val[2];
if($format === 'short') { break; }
}
if(empty($ret) || strpos($ret[0],$sec) !== false)
{
$justNow = deftrue('LANDT_10',"Just now");
return $mode ? array($justNow) : $justNow;
}
if($older_date < $newer_date) // past
{
$replace = implode(", ", $ret);
$xago = e107::getParser()->lanVars(LANDT_XAGO, $replace);
return ($mode ? $ret : $xago);
}
else // future
{
$replace = implode(", ", $ret);
$inx = e107::getParser()->lanVars(LANDT_INX, $replace);
return ($mode ? $ret : $inx);
}
// print_r($ret);
/*
If we want an absolutely accurate result, main problems arise from the varying numbers of days in a month.
If we go over a month boundary, then we need to add days to end of start month, plus days in 'end' month
If start day > end day, we cross a month boundary. Calculate last day of start date. Otherwise we can just do a simple difference.
*/
/*
$newer_date = ($newer_date === FALSE ? (time()) : $newer_date);
if($older_date>$newer_date)
{ // Just in case the wrong way round
$tmp=$newer_date;
$newer_date=$older_date;
$older_date=$tmp;
}
$new_date = getdate($newer_date);
$old_date = getdate($older_date);
$result = array();
$outputArray = array();
$params = array(
6 => array('seconds',60, $sec, $secs),
5 => array('minutes',60, $min, $mins),
4 => array('hours',24, LANDT_05, LANDT_05s),
3 => array('mday', -1, LANDT_04, LANDT_04s),
2 => array('',-3, LANDT_03, LANDT_03s),
1 => array('mon',12, LANDT_02, LANDT_02s),
0 => array('year', -2, LANDT_01,LANDT_01s)
);
$cy = 0;
foreach ($params as $parkey => $parval)
{
if ($parkey == 2)
{
$result['2'] = floor($result['3']/7);
$result['3'] = fmod($result['3'],7);
}
else
{
$tmp = $new_date[$parval[0]] - $old_date[$parval[0]] - $cy;
$scy = $cy;
$cy = 0;
if ($tmp < 0)
{
switch ($parval[1])
{
case -1 : // Wrapround on months - special treatment
$tempdate = getdate(mktime(0,0,0,$old_date['mon']+1,1,$old_date['year']) - 1); // Last day of month
$tmp = $tempdate['mday'] - $old_date['mday'] + $new_date['mday'] - $scy;
$cy = 1;
break;
case -2 : // Year wraparound - shouldn't happen
case -3 : // Week processing - this shouldn't happen either
echo "Code bug!<br />";
break;
default :
$cy = 1;
$tmp += $parval[1];
}
}
$result[$parkey] = $tmp;
}
}
// Generate output array, add text
for ($i = 0; $i < ($show_secs ? 7 : 6); $i++)
{
if (($i > 4) || ($result[$i] != 0))
{ // Only show non-zero values, except always show minutes/seconds
$outputArray[] = $result[$i]." ".($result[$i] == 1 ? $params[$i][2] : $params[$i][3]) ;
}
if($format == 'short' && count($outputArray) == 1) { break; }
}
if(empty($outputArray[1]) && ($outputArray[0] == "0 ".$mins))
{
return deftrue('LANDT_10',"Just now");
}
// Check if it is 'past' or 'future'
if($older_date > $newer_date) // past
{
return ($mode ? $outputArray : implode(", ", $outputArray) . " " . LANDT_AGO);
}
else // future
{
return ($mode ? $outputArray : LANDT_IN ." ". implode(", ", $outputArray));
}
*/
}
/**
* Parse a time/date generated with strftime()
* With extra output keys for localized month
*
* @deprecated Use eShims::strptime() instead
* @see eShims::strptime()
* @param string $str date string to parse (e.g. returned from strftime()).
* @param $format
* @return array|bool Returns an array with the <code>$str</code> parsed, or <code>false</code> on error.
*/
public function strptime($str, $format)
{
trigger_error('<b>' . __METHOD__ . ' is deprecated.</b> Use eShims::strptime() instead', E_USER_DEPRECATED); // NO LAN
$vals = eShims::strptime($str, $format); // PHP5 is more accurate than below.
$vals['tm_amon'] = eShims::strftime('%b', mktime(0, 0, 0, $vals['tm_mon'] + 1));
$vals['tm_fmon'] = eShims::strftime('%B', mktime(0, 0, 0, $vals['tm_mon'] + 1));
return $vals;
}
/**
* @param $mode
* @return bool
*/
function supported($mode = FALSE)
{
$strftimeFormats = array(
'A' => 'A full textual representation of the day',
'B' => 'Full month name, based on the locale',
'C' => 'Two digit representation of the century (year divided by 100, truncated to an integer)',
'D' => 'Same as "%m/%d/%y"',
'E' => '',
'F' => 'Same as "%Y-%m-%d"',
'G' => 'The full four-digit version of %g',
'H' => 'Two digit representation of the hour in 24-hour format',
'I' => 'Two digit representation of the hour in 12-hour format',
'J' => '',
'K' => '',
'L' => '',
'M' => 'Two digit representation of the minute',
'N' => '',
'O' => '',
'P' => 'lower-case "am" or "pm" based on the given time',
'Q' => '',
'R' => 'Same as "%H:%M"',
'S' => 'Two digit representation of the second',
'T' => 'Same as "%H:%M:%S"',
'U' => 'Week number of the given year, starting with the first Sunday as the first week',
'V' => 'ISO-8601:1988 week number of the given year, starting with the first week of the year with at least 4 weekdays, with Monday being the start of the week',
'W' => 'A numeric representation of the week of the year, starting with the first Monday as the first week',
'X' => 'Preferred time representation based on locale, without the date',
'Y' => 'Four digit representation for the year',
//'Z' => 'The time zone offset/abbreviation option NOT given by %z (depends on operating system)',
'a' => 'An abbreviated textual representation of the day',
'b' => 'Abbreviated month name, based on the locale',
'c' => 'Preferred date and time stamp based on local',
'd' => 'Two-digit day of the month (with leading zeros)',
'e' => 'Day of the month, with a space preceding single digits',
'f' => '',
'g' => 'Two digit representation of the year going by ISO-8601:1988 standards (see %V)',
'h' => 'Abbreviated month name, based on the locale (an alias of %b)',
'i' => '',
'j' => 'Day of the year, 3 digits with leading zeros',
'k' => '',
'l' => 'Hour in 12-hour format, with a space preceeding single digits',
'm' => 'Two digit representation of the month',
'n' => 'A newline character ("\n")',
'o' => '',
'p' => 'UPPER-CASE "AM" or "PM" based on the given time',
'q' => '',
'r' => 'Same as "%I:%M:%S %p"',
's' => 'Unix Epoch Time timestamp',
't' => 'A Tab character ("\t")',
'u' => 'ISO-8601 numeric representation of the day of the week',
'v' => '',
'w' => 'Numeric representation of the day of the week',
'x' => 'Preferred date representation based on locale, without the time',
'y' => 'Two digit representation of the year',
//'z' => 'Either the time zone offset from UTC or the abbreviation (depends on operating system)',
'%' => 'A literal percentage character ("%")',
);
if (stripos(PHP_OS, 'WIN') === false)
{
// This formats are not avaiilable on windows and will make the script fail on use.
$strftimeFormats['Z'] = 'The time zone offset/abbreviation option NOT given by %z (depends on operating system)';
$strftimeFormats['z'] = 'Either the time zone offset from UTC or the abbreviation (depends on operating system)';
}
// Results.
$strftimeValues = array();
// Evaluate the formats whilst suppressing any errors.
foreach($strftimeFormats as $format => $description)
{
$strftimeValues[$format] = eShims::strftime("%{$format}");
}
// Find the longest value.
$maxValueLength = 2 + max(array_map('strlen', $strftimeValues));
$ret = array(
'enabled' => array(),
'disabled' => array()
);
// Report known formats.
foreach($strftimeValues as $format => $value)
{
$ret['enabled'][] = $format;
echo ($mode =='list') ? "Known format : '{$format}' = ". str_pad("'{$value}'", $maxValueLength). " ( {$strftimeFormats[$format]} )<br />" : "";
}
// Report unknown formats.
foreach(array_diff_key($strftimeFormats, $strftimeValues) as $format => $description)
{
$ret['disabled'][] = $format;
echo ($mode =='list') ? "Unknown format : '{$format}' ". str_pad(' ', $maxValueLength). ($description ? " ( {$description} )" : ''). "<br />" : "";
}
return in_array($mode,$ret['enabled']);
}
/**
* Check if TimeZone is valid
* @param $timezone
* @return bool
*/
function isValidTimezone($timezone)
{
return in_array($timezone, timezone_identifiers_list());
}
/**
* @param $datestamp
* @return array
*/
public function dateFormats($datestamp = null)
{
if(empty($datestamp))
{
$datestamp = time();
}
$formats = array(
"%A, %d %B, %Y",
"%A, %d %b, %Y",
"%a, %d %B, %Y",
"%a, %d %b, %Y",
"%A, %B %d, %Y",
"%A, %b %d, %Y",
"%A, %b %d, %y",
"%B %d, %Y",
"%b %d, %Y",
"%b %d, %y",
"%d %B, %Y",
"%d %b, %Y",
"%d %b, %y",
"%Y-%m-%d",
"%d-%m-%Y",
"%m/%d/%Y",
"%d.%m.%Y"
);
$ret = [];
foreach($formats as $f)
{
$ret[$f] = eShims::strftime($f,$datestamp);
}
return $ret;
}
/**
* @param $datestamp
* @return array
*/
function timeFormats($datestamp=null)
{
if(empty($datestamp))
{
$datestamp = time();
}
$inputtime = array();
$inputtime["%I:%M %p"] = eShims::strftime("%I:%M %p",$datestamp);
if(e107::getDate()->supported('P'))
{
$inputtime["%I:%M %P"] = eShims::strftime("%I:%M %P",$datestamp);
}
if(e107::getDate()->supported('l'))
{
$inputtime["%l:%M %p"] = eShims::strftime("%l:%M %p",$datestamp);
$inputtime["%l:%M %P"] = eShims::strftime("%l:%M %P",$datestamp);
}
$inputtime["%H:%M"] = eShims::strftime("%H:%M",$datestamp);
$inputtime["%H:%M:%S"] = eShims::strftime("%H:%M:%S",$datestamp);
return $inputtime;
}
}
/**
* BC Fix convert
*/
class convert extends e_date
{
}