public function format(string $format, $timeZone = null) : string
{
// Prepares the right result time zone if needed
if ($timeZone) {
$this->setTemporaryTimeZone($timeZone);
}
// Translation required?
if (preg_match('~(?:^|[^\\\\])[lDFM]~', $format)) {
static $days = [];
if (empty($days)) {
$days = [_('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday'), _('Sunday')];
}
static $daysShort = [];
if (empty($daysShort)) {
$daysShort = [_('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat'), _('Sun')];
}
static $months = [];
if (empty($months)) {
$months = [_('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'), _('September'), _('October'), _('November'), _('December')];
}
static $monthsGen = [];
if (empty($monthsGen)) {
$monthsGen = [_('January#~Genitive'), _('February#~Genitive'), _('March#~Genitive'), _('April#~Genitive'), _('May#~Genitive'), _('June#~Genitive'), _('July#~Genitive'), _('August#~Genitive'), _('September#~Genitive'), _('October#~Genitive'), _('November#~Genitive'), _('December#~Genitive')];
}
static $monthsShort = [];
if (empty($monthsShort)) {
$monthsShort = [_('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May#~Shortcut'), _('Jun'), _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')];
}
// Replace certain identifiers with fake ones
$search = ['~(^|[^\\\\])l~', '~(^|[^\\\\])D~', '~(^|[^\\\\])F~', '~(^|[^\\\\])M~'];
$replace = ['$1<===>', '$1<___>', '$1<--->', '$1<...>'];
$format = preg_replace($search, $replace, $format);
// Format the rest of the date
$date = $this->dateTime->format($format);
// Calculate day and month
$day = $this->dateTime->format('N') - 1;
$month = $this->dateTime->format('n') - 1;
// If the month is not at the beginning, the genitive case and lowercase will be used
$monthName = 0 !== strpos($format, '<--->') ? mb_strtolower($monthsGen[$month], 'utf-8') : $months[$month];
// Add translated days and months into the result
$result = strtr($date, ['<===>' => $days[$day], '<___>' => $daysShort[$day], '<--->' => $monthName, '<...>' => $monthsShort[$month]]);
} else {
// No need to translate
$result = $this->dateTime->format($format);
}
// If a custom result timezone was specified, revert the original one
if ($timeZone) {
$this->revertOriginalTimeZone();
}
return $result;
}