1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290:
<?php
/**
* MvcCore
*
* This source file is subject to the BSD 3 License
* For the full copyright and license information, please view
* the LICENSE.md file that are distributed with this source code.
*
* @copyright Copyright (c) 2016 Tom Flidr (https://github.com/mvccore)
* @license https://mvccore.github.io/docs/mvccore/5.0.0/LICENCE.md
*/
namespace MvcCore\Ext\Views\Helpers;
/**
* Responsibility - format given date by `Intl` extension or by `strftime()` as fallback.
* - Possibility to configure `Intl` datetime formatter default arguments.
* - Possibility to configure format mask used by PHP `strftime(); for fallback`.
* - System locale settings for fallback conversion automatically configured by request language and request locale.
* - Fallback result string always returned in response encoding, in UTF-8 by default.
* @method \MvcCore\Ext\Views\Helpers\FormatDateHelper GetInstance()
*/
class FormatDateHelper extends \MvcCore\Ext\Views\Helpers\InternationalizedHelper {
/**
* MvcCore Extension - View Helper - Assets - version:
* Comparison by PHP function version_compare();
* @see http://php.net/manual/en/function.version-compare.php
*/
const VERSION = '5.0.0';
/**
* If this static property is set - helper is possible
* to configure as singleton before it's used for first time.
* Example:
* `\MvcCore\Ext\Views\Helpers\FormatDateHelper::GetInstance()`
* @var \MvcCore\Ext\Views\Helpers\FormatDateHelper
*/
protected static $instance;
/**
* Default date type to use:
* - `\IntlDateFormatter::NONE` - Do not include this element
* - `\IntlDateFormatter::SHORT` - Most abbreviated style, only essential data (12/13/52 or 3:30pm)
* - `\IntlDateFormatter::MEDIUM` - Medium style (Jan 12, 1952)
* - `\IntlDateFormatter::LONG` - Long style (January 12, 1952 or 3:30:32pm)
* - `\IntlDateFormatter::FULL` - Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
* If `NULL`, ICUʼs default date type will be used.
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
* @var int|NULL
*/
protected $intlDefaultDateFormatter = NULL;
/**
* Default time type to use:
* - `\IntlDateFormatter::NONE` - Do not include this element
* - `\IntlDateFormatter::SHORT` - Most abbreviated style, only essential data (12/13/52 or 3:30pm)
* - `\IntlDateFormatter::MEDIUM` - Medium style (Jan 12, 1952)
* - `\IntlDateFormatter::LONG` - Long style (January 12, 1952 or 3:30:32pm)
* - `\IntlDateFormatter::FULL` - Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
* If `NULL`, ICUʼs default time type will be used.
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
* @var int|NULL
*/
protected $intlDefaultTimeFormatter = NULL;
/**
* Time zone ID. The default (and the one used if `NULL` is given)
* is the one returned by `date_default_timezone_get()` or, if applicable,
* that of the `\IntlCalendar` object passed for the calendar parameter.
* This ID must be a valid identifier on ICUʼs database or an ID
* representing an explicit offset, such as GMT-05:30.
* @var string|\IntlTimeZone|\DateTimeZone|NULL
*/
protected $intlDefaultTimeZone = NULL;
/**
* Calendar to use for formatting or parsing. The default value is NULL,
* which corresponds to `\IntlDateFormatter::GREGORIAN`. This can either be
* one of the `\IntlDateFormatter` calendar constants or an `\IntlCalendar`.
* Any `\IntlCalendar` object passed will be clone; it will not be changed
* by the `\IntlDateFormatter`. This will determine the calendar type used
* (`gregorian`, `islamic`, `persian`, etc.) and, if `NULL` is given for the
* timezone parameter, also the timezone used.
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants.calendartypes
* @var int|NULL
*/
protected $intlDefaultCalendar = NULL;
/**
* System `setlocale()` category to set up system locale automatically
* in `parent::setUpSystemLocaleAndEncodings()` method.
* This property is used only for fallback if formatting is not by `Intl` extension.
* @var \int[]
*/
protected $localeCategories = [LC_TIME];
/**
* Custom format mask in used by PHP `strftime();`:
* This property is used only for fallback if formatting is not by `Intl` extension.
* @see http://php.net/strftime
* @var string
*/
protected $strftimeFormatMask = '%e. %B %G, %H:%M:%S';
/**
* Set default date type to use:
* - `\IntlDateFormatter::NONE` - Do not include this element
* - `\IntlDateFormatter::SHORT` - Most abbreviated style, only essential data (12/13/52 or 3:30pm)
* - `\IntlDateFormatter::MEDIUM` - Medium style (Jan 12, 1952)
* - `\IntlDateFormatter::LONG` - Long style (January 12, 1952 or 3:30:32pm)
* - `\IntlDateFormatter::FULL` - Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
* If `NULL`, ICUʼs default date type will be used.
* @param int|NULL $intlDefaultDateFormatter
* @return \MvcCore\Ext\Views\Helpers\FormatDateHelper
*/
public function SetIntlDefaultDateFormatter ($intlDefaultDateFormatter) {
$this->intlDefaultDateFormatter = $intlDefaultDateFormatter;
return $this;
}
/**
* Set default time type to use:
* - `\IntlDateFormatter::NONE` - Do not include this element
* - `\IntlDateFormatter::SHORT` - Most abbreviated style, only essential data (12/13/52 or 3:30pm)
* - `\IntlDateFormatter::MEDIUM` - Medium style (Jan 12, 1952)
* - `\IntlDateFormatter::LONG` - Long style (January 12, 1952 or 3:30:32pm)
* - `\IntlDateFormatter::FULL` - Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
* If `NULL`, ICUʼs default time type will be used.
* @param int|NULL $intlDefaultTimeFormatter
* @return \MvcCore\Ext\Views\Helpers\FormatDateHelper
*/
public function SetIntlDefaultTimeFormatter ($intlDefaultTimeFormatter) {
$this->intlDefaultTimeFormatter = $intlDefaultTimeFormatter;
return $this;
}
/**
* Set default time zone ID. The default (and the one used if `NULL` is given)
* is the one returned by `date_default_timezone_get()` or, if applicable,
* that of the `\IntlCalendar` object passed for the calendar parameter.
* This ID must be a valid identifier on ICUʼs database or an ID
* representing an explicit offset, such as GMT-05:30.
* @param string|\IntlTimeZone|\DateTimeZone|NULL $intlDefaultTimeZone
* @return \MvcCore\Ext\Views\Helpers\FormatDateHelper
*/
public function SetIntlDefaultTimeZone ($intlDefaultTimeZone) {
$this->intlDefaultTimeZone = $intlDefaultTimeZone;
return $this;
}
/**
* Set default calendar to use for formatting or parsing. The default value is NULL,
* which corresponds to `\IntlDateFormatter::GREGORIAN`. This can either be
* one of the `\IntlDateFormatter` calendar constants or an `\IntlCalendar`.
* Any `\IntlCalendar` object passed will be clone; it will not be changed
* by the `\IntlDateFormatter`. This will determine the calendar type used
* (`gregorian`, `islamic`, `persian`, etc.) and, if `NULL` is given for the
* timezone parameter, also the timezone used.
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants.calendartypes
* @param int|NULL $intlDefaultCalendar
* @return \MvcCore\Ext\Views\Helpers\FormatDateHelper
*/
public function SetIntlDefaultCalendar ($intlDefaultCalendar) {
$this->intlDefaultCalendar = $intlDefaultCalendar;
return $this;
}
/**
* Set custom format mask used by PHP `strftime();`.
* This method is used only for fallback if formatting is not by `Intl` extension.
* @see http://php.net/strftime
* @param string $formatMask
* @return \MvcCore\Ext\Views\Helpers\FormatDateHelper
*/
public function SetStrftimeFormatMask ($strftimeFormatMask = '%e. %B %G, %H:%M:%S') {
$this->strftimeFormatMask = $strftimeFormatMask;
return $this;
}
/**
* Format given date by `datefmt_format()` (in `Intl` extension) or by `strftime()` as fallback.
* If you don't want to specify all arguments for each helper callback, use setters
* instead to set up default values for `Intl` extension formatting r for `strftime()` formatting.
* You can use `$this->GetHelper('FormatDate')->SetAnything(...);` in view template
* or `\MvcCore\Ext\Views\Helpers\FormatDateHelper::GetInstance()->SetAnything(...);` anywhere else.
* @see http://php.net/manual/en/intldateformatter.create.php
* @see http://php.net/strftime
* @param \DateTime|\IntlCalendar|int|NULL $dateTimeOrTimestamp Value to format. This may be a `\DateTime\ object, an `\IntlCalendar\ object,
* a numeric type representing a (possibly fractional) number of seconds since
* epoch or an array in the format output by localtime().
* @param int|string|NULL $dateTypeOrFormatMask Any custom `\IntlDateFormatter` constant to specify second argument `int $datetype` for
* `datefmt_create()` function or custom `strftime()` format mask used as fallback.
* Default date types to use (if `NULL`, ICUʼs default date type will be used):
* - `\IntlDateFormatter::NONE` - Do not include this element
* - `\IntlDateFormatter::SHORT` - Most abbreviated style, only essential data (12/13/52 or 3:30pm)
* - `\IntlDateFormatter::MEDIUM` - Medium style (Jan 12, 1952)
* - `\IntlDateFormatter::LONG` - Long style (January 12, 1952 or 3:30:32pm)
* - `\IntlDateFormatter::FULL` - Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
* Fallback format mask for `strftime()` could look like `"%e. %B %G, %H:%M:%S"`.
* @param int|NULL $timeType Any custom `\IntlDateFormatter` constant to specify third argument `int $timetype` for `datefmt_create()`.
* Time types to use (if `NULL`, ICUʼs default time type will be used):
* - `\IntlDateFormatter::NONE` - Do not include this element
* - `\IntlDateFormatter::SHORT` - Most abbreviated style, only essential data (12/13/52 or 3:30pm)
* - `\IntlDateFormatter::MEDIUM` - Medium style (Jan 12, 1952)
* - `\IntlDateFormatter::LONG` - Long style (January 12, 1952 or 3:30:32pm)
* - `\IntlDateFormatter::FULL` - Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
* @param string|\IntlTimeZone|\DateTimeZone|NULL $timeZone Any custom time zone ID. The default (and the one used if `NULL` is given)
* is the one returned by `date_default_timezone_get()` or, if applicable, that
* of the `\IntlCalendar` object passed for the calendar parameter. This ID must
* be a valid identifier on ICUʼs database or an ID representing an explicit
* offset, such as GMT-05:30. If you want to specify custom timezone for whole
* application, use `date_default_timezone_set('Europe/Prague');`...
* @param int|NULL $calendar Calendar to use for formatting or parsing. The default value is `NULL`, which corresponds to
* `\IntlDateFormatter::GREGORIAN`. This can either be one of the `\IntlDateFormatter` calendar
* constants or an IntlCalendar. Any IntlCalendar object passed will be clone; it will not be
* changed by the IntlDateFormatter. This will determine the calendar type used (gregorian,
* islamic, persian, etc.) and, if NULL is given for the timezone parameter, also the timezone used.
* @return string
*/
public function FormatDate (
$dateTimeOrTimestamp = NULL,
$dateTypeOrFormatMask = NULL,
$timeType = NULL,
$timeZone = NULL,
$calendar = NULL
) {
$dateTimeToFormat = $dateTimeOrTimestamp === NULL
? time()
: $dateTimeOrTimestamp;
if ($this->intlExtensionFormatting) {
$dateType = $dateTypeOrFormatMask;
$formatter = $this->getIntlDatetimeFormatter(
$this->langAndLocale,
$dateType !== NULL
? $dateType
: $this->intlDefaultDateFormatter,
$timeType !== NULL
? $timeType
: $this->intlDefaultTimeFormatter,
$timeZone !== NULL
? $timeZone
: $this->intlDefaultTimeZone,
$calendar !== NULL
? $calendar
: $this->intlDefaultCalendar
);
return \datefmt_format($formatter, $dateTimeToFormat);
} else {
if ($this->encodingConversion === NULL)
$this->setUpSystemLocaleAndEncodings();
if ($this->systemEncoding === NULL)
$this->SetLangAndLocale('en', 'US')
->setUpSystemLocaleAndEncodings();
$result = \strftime(
$dateTypeOrFormatMask !== NULL
? $dateTypeOrFormatMask
: $this->strftimeFormatMask,
$dateTimeToFormat instanceof \DateTime
? $dateTimeToFormat->getTimestamp()
: intval($dateTimeToFormat)
);
return $this->encode($result);
}
}
/**
* Get stored `\IntlDateFormatter` instance or create new one.
* @param string|NULL $langAndLocale
* @param int|NULL $dateType
* @param int|NULL $timeType
* @param string|\IntlTimeZone|\DateTimeZone|NULL $timeZone
* @param int|NULL $calendar
* @return \IntlDateFormatter
*/
protected function getIntlDatetimeFormatter ($langAndLocale = NULL, $dateType = NULL, $timeType = NULL, $timeZone = NULL, $calendar = NULL) {
$key = implode('_', [
'datetime',
serialize(func_get_args())
]);
if (!isset($this->intlFormatters[$key])) {
$this->intlFormatters[$key] = \datefmt_create(
$this->langAndLocale, $dateType, $timeType, $timeZone, $calendar
);
}
return $this->intlFormatters[$key];
}
}