fn() => substr($dt->format('Y'), -2), 'y' => fn() => $dt->format('Y'), 'MM' => fn() => $dt->format('m'), 'M' => fn() => (string)(int)$dt->format('m'), // без ведущего нуля 'dd' => fn() => $dt->format('d'), 'd' => fn() => (string)(int)$dt->format('d'), 'hh' => fn() => $dt->format('h'), 'h' => fn() => (string)(int)$dt->format('h'), 'HH' => fn() => $dt->format('H'), 'H' => fn() => (string)(int)$dt->format('H'), 'mm' => fn() => $dt->format('i'), 'm' => fn() => (string)(int)$dt->format('i'), 'ss' => fn() => $dt->format('s'), 's' => fn() => (string)(int)$dt->format('s'), ]; for ($i = 0; $i < $len; $i++) { $char = $format[$i]; if ($escape) { // Текущий символ — экранированный, просто добавляем и сбрасываем флаг $result .= $char; $escape = false; continue; } if ($char === '\\') { // Следующий символ экранированный $escape = true; continue; } // Попробуем проверить двухсимвольные паттерны (yy, MM, dd, hh, HH, mm, ss) if ($i + 1 < $len) { $pair = $char . $format[$i + 1]; if (isset($formatters[$pair])) { $result .= $formatters[$pair](); $i++; // пропускаем следующий символ, т.к. он уже учтен continue; } } // Односимвольные паттерны if (isset($formatters[$char])) { $result .= $formatters[$char](); } else { // Просто символ без замены $result .= $char; } } return $result; } // Тесты $date = new DateTime('2025-06-03 15:07:09'); echo dateFormat($date, 'y-M-d H:mm:ss') . PHP_EOL; // 2025-6-3 15:07:09 echo dateFormat($date, 'yy \\yy\\y') . PHP_EOL; // 25 y2025y echo dateFormat($date, 'H\\H:mm\\m:ss hh\\:m:s') . PHP_EOL; // 15H:07m:09 03\:7:9 test('2025-6-3 15:07:09', dateFormat($date, 'y-M-d H:mm:ss')); test('15H:07m:09 03\:7:9', dateFormat($date, 'H\H:mm\m:ss hh\:m:s')); test('25 y2025y', dateFormat($date, 'yy \yy\y')); echo dateFormat($date, 'y-M-d H:mm:ss') . PHP_EOL; // 2025-6-3 15:07:09 echo dateFormat($date, 'yy \yy\y') . PHP_EOL; // 25 y2025y echo dateFormat($date, 'H\H:mm\m:ss hh\:m:s') . PHP_EOL; // 15H:07m:09 03\:7:9 function test($expected, $actual): void { try { assert($expected === $actual); } catch (\AssertionError) { echo "failed tests. Expected === actual. {$expected} === {$actual}\n"; exit(1); } echo "Ok!\n"; }