diff --git a/include/Page/Rename.php b/include/Page/Rename.php
index 8eb6d12..7f84d28 100644
--- a/include/Page/Rename.php
+++ b/include/Page/Rename.php
@@ -31,6 +31,7 @@ namespace gp\Page{
'keywords' => '',
'description' => '',
'rel' => '',
+ 'category' => '',
);
if( empty($_REQUEST['new_title']) ){
@@ -69,7 +70,6 @@ namespace gp\Page{
//slug (title)
$attr = '';
$class = 'new_title';
-
if( $title == \gp\admin\Tools::LabelToSlug($label) ){
//$attr = 'disabled="disabled" ';
$attr = 'readonly="readonly"" ';
@@ -80,8 +80,7 @@ namespace gp\Page{
self::ToggleSync($attr);
echo '';
-
-
+
//browser title defaults to label
$attr = '';
$class = 'browser_title';
@@ -99,6 +98,13 @@ namespace gp\Page{
echo '';
+ //category : wird in data site config.php definiert und in pages.php eingetragen / admin/configuration.php 36 -- include install tools 242
+ $category = $title_info['category'];
+ self::FormLabel('category',$title_info['category']);
+ echo '';
+ echo '';
+
+
//meta keywords
self::FormLabel('keywords',$title_info['keywords']);
echo '';
@@ -246,6 +252,7 @@ namespace gp\Page{
self::SetInfo($title_info, 'browser_title');
self::SetInfo($title_info, 'keywords');
self::SetInfo($title_info, 'description');
+ self::SetInfo($title_info, 'category');
self::SetRobots($title_info);
diff --git a/include/admin/Configuration.php b/include/admin/Configuration.php
index 5f80bdf..f1ea4c8 100644
--- a/include/admin/Configuration.php
+++ b/include/admin/Configuration.php
@@ -33,6 +33,7 @@ class Configuration extends \gp\special\Base{
/* General Settings */
'general_settings' => false,
'title' => '',
+ 'category' => '',
'keywords' => '',
'desc' => 'textarea',
diff --git a/include/common.php b/include/common.php
index 89e1a83..4f90810 100644
--- a/include/common.php
+++ b/include/common.php
@@ -1,7 +1,6 @@
- * https://github.com/alphp/strftime MIT
- */
- function strftime (string $format, $timestamp = null, ?string $locale = null) : string {
- if (!($timestamp instanceof DateTimeInterface)) {
- $timestamp = is_int($timestamp) ? '@' . $timestamp : (string) $timestamp;
-
- try {
- $timestamp = new DateTime($timestamp);
- } catch (Exception $e) {
- throw new InvalidArgumentException('$timestamp argument is neither a valid UNIX timestamp, a valid date-time string or a DateTime object.', 0, $e);
- }
- }
-
- $timestamp->setTimezone(new DateTimeZone(date_default_timezone_get()));
-
- if (empty($locale)) {
- // get current locale
- $locale = setlocale(LC_TIME, '0');
- }
- // remove trailing part not supported by ext-intl locale
- $locale = preg_replace('/[^\w-].*$/', '', $locale);
-
- $intl_formats = [
- '%a' => 'EEE', // An abbreviated textual representation of the day Sun through Sat
- '%A' => 'EEEE', // A full textual representation of the day Sunday through Saturday
- '%b' => 'MMM', // Abbreviated month name, based on the locale Jan through Dec
- '%B' => 'MMMM', // Full month name, based on the locale January through December
- '%h' => 'MMM', // Abbreviated month name, based on the locale (an alias of %b) Jan through Dec
- ];
-
- $intl_formatter = function (DateTimeInterface $timestamp, string $format) use ($intl_formats, $locale) {
- $tz = $timestamp->getTimezone();
- $date_type = IntlDateFormatter::FULL;
- $time_type = IntlDateFormatter::FULL;
- $pattern = '';
-
- switch ($format) {
- // %c = Preferred date and time stamp based on locale
- // Example: Tue Feb 5 00:45:10 2009 for February 5, 2009 at 12:45:10 AM
- case '%c':
- $date_type = IntlDateFormatter::LONG;
- $time_type = IntlDateFormatter::SHORT;
- break;
-
- // %x = Preferred date representation based on locale, without the time
- // Example: 02/05/09 for February 5, 2009
- case '%x':
- $date_type = IntlDateFormatter::SHORT;
- $time_type = IntlDateFormatter::NONE;
- break;
-
- // Localized time format
- case '%X':
- $date_type = IntlDateFormatter::NONE;
- $time_type = IntlDateFormatter::MEDIUM;
- break;
-
- default:
- $pattern = $intl_formats[$format];
- }
-
- // In October 1582, the Gregorian calendar replaced the Julian in much of Europe, and
- // the 4th October was followed by the 15th October.
- // ICU (including IntlDateFormattter) interprets and formats dates based on this cutover.
- // Posix (including strftime) and timelib (including DateTimeImmutable) instead use
- // a "proleptic Gregorian calendar" - they pretend the Gregorian calendar has existed forever.
- // This leads to the same instants in time, as expressed in Unix time, having different representations
- // in formatted strings.
- // To adjust for this, a custom calendar can be supplied with a cutover date arbitrarily far in the past.
- $calendar = IntlGregorianCalendar::createInstance();
- $calendar->setGregorianChange(PHP_INT_MIN);
-
- return (new IntlDateFormatter($locale, $date_type, $time_type, $tz, $calendar, $pattern))->format($timestamp);
- };
-
- // Same order as https://www.php.net/manual/en/function.strftime.php
- $translation_table = [
- // Day
- '%a' => $intl_formatter,
- '%A' => $intl_formatter,
- '%d' => 'd',
- '%e' => function ($timestamp) {
- return sprintf('% 2u', $timestamp->format('j'));
- },
- '%j' => function ($timestamp) {
- // Day number in year, 001 to 366
- return sprintf('%03d', $timestamp->format('z')+1);
- },
- '%u' => 'N',
- '%w' => 'w',
-
- // Week
- '%U' => function ($timestamp) {
- // Number of weeks between date and first Sunday of year
- $day = new DateTime(sprintf('%d-01 Sunday', $timestamp->format('Y')));
- return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
- },
- '%V' => 'W',
- '%W' => function ($timestamp) {
- // Number of weeks between date and first Monday of year
- $day = new DateTime(sprintf('%d-01 Monday', $timestamp->format('Y')));
- return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
- },
-
- // Month
- '%b' => $intl_formatter,
- '%B' => $intl_formatter,
- '%h' => $intl_formatter,
- '%m' => 'm',
-
- // Year
- '%C' => function ($timestamp) {
- // Century (-1): 19 for 20th century
- return floor($timestamp->format('Y') / 100);
- },
- '%g' => function ($timestamp) {
- return substr($timestamp->format('o'), -2);
- },
- '%G' => 'o',
- '%y' => 'y',
- '%Y' => 'Y',
-
- // Time
- '%H' => 'H',
- '%k' => function ($timestamp) {
- return sprintf('% 2u', $timestamp->format('G'));
- },
- '%I' => 'h',
- '%l' => function ($timestamp) {
- return sprintf('% 2u', $timestamp->format('g'));
- },
- '%M' => 'i',
- '%p' => 'A', // AM PM (this is reversed on purpose!)
- '%P' => 'a', // am pm
- '%r' => 'h:i:s A', // %I:%M:%S %p
- '%R' => 'H:i', // %H:%M
- '%S' => 's',
- '%T' => 'H:i:s', // %H:%M:%S
- '%X' => $intl_formatter, // Preferred time representation based on locale, without the date
-
- // Timezone
- '%z' => 'O',
- '%Z' => 'T',
-
- // Time and Date Stamps
- '%c' => $intl_formatter,
- '%D' => 'm/d/Y',
- '%F' => 'Y-m-d',
- '%s' => 'U',
- '%x' => $intl_formatter,
- ];
-
- $out = preg_replace_callback('/(?format($replace);
- }
- else {
- $result = $replace($timestamp, $pattern);
- }
-
- switch ($prefix) {
- case '_':
- // replace leading zeros with spaces but keep last char if also zero
- return preg_replace('/\G0(?=.)/', ' ', $result);
- case '#':
- case '-':
- // remove leading zeros but keep last char if also zero
- return preg_replace('/^0+(?=.)/', '', $result);
- }
-
- return $result;
- }, $format);
-
- $out = str_replace('%%', '%', $out);
- return $out;
- }
diff --git a/include/thirdparty/time/strftime-bo-mod.php b/include/thirdparty/time/strftime-bo-mod.php
new file mode 100644
index 0000000..a952444
--- /dev/null
+++ b/include/thirdparty/time/strftime-bo-mod.php
@@ -0,0 +1,190 @@
+
+ */
+function strftime(string $format, $timestamp = null, ?string $locale = null): string
+{
+ if (null === $timestamp) {
+ $timestamp = new \DateTime;
+ }
+ elseif (is_numeric($timestamp)) {
+ $timestamp = date_create('@' . $timestamp);
+
+ if ($timestamp) {
+ $timestamp->setTimezone(new \DateTimezone(date_default_timezone_get()));
+ }
+ }
+ elseif (is_string($timestamp)) {
+ $timestamp = date_create($timestamp);
+ }
+
+ if (!($timestamp instanceof \DateTimeInterface)) {
+ throw new \InvalidArgumentException('$timestamp argument is neither a valid UNIX timestamp, a valid date-time string or a DateTime object.');
+ }
+
+ $locale = substr((string) $locale, 0, 5);
+
+ $intl_formats = [
+ '%a' => 'EEE', // An abbreviated textual representation of the day Sun through Sat
+ '%A' => 'EEEE', // A full textual representation of the day Sunday through Saturday
+ '%b' => 'MMM', // Abbreviated month name, based on the locale Jan through Dec
+ '%B' => 'MMMM', // Full month name, based on the locale January through December
+ '%h' => 'MMM', // Abbreviated month name, based on the locale (an alias of %b) Jan through Dec
+ ];
+
+ $intl_formatter = function (\DateTimeInterface $timestamp, string $format) use ($intl_formats, $locale) {
+ $tz = $timestamp->getTimezone();
+ $date_type = \IntlDateFormatter::FULL;
+ $time_type = \IntlDateFormatter::FULL;
+ $pattern = '';
+
+ // %c = Preferred date and time stamp based on locale
+ // Example: Tue Feb 5 00:45:10 2009 for February 5, 2009 at 12:45:10 AM
+ if ($format == '%c') {
+ $date_type = \IntlDateFormatter::LONG;
+ $time_type = \IntlDateFormatter::SHORT;
+ }
+ // %x = Preferred date representation based on locale, without the time
+ // Example: 02/05/09 for February 5, 2009
+ elseif ($format == '%x') {
+ $date_type = \IntlDateFormatter::SHORT;
+ $time_type = \IntlDateFormatter::NONE;
+ }
+ // Localized time format
+ elseif ($format == '%X') {
+ $date_type = \IntlDateFormatter::NONE;
+ $time_type = \IntlDateFormatter::MEDIUM;
+ }
+ else {
+ $pattern = $intl_formats[$format];
+ }
+
+ return (new \IntlDateFormatter($locale, $date_type, $time_type, $tz, null, $pattern))->format($timestamp);
+ };
+
+ // Same order as https://www.php.net/manual/en/function.strftime.php
+ $translation_table = [
+ // Day
+ '%a' => $intl_formatter,
+ '%A' => $intl_formatter,
+ '%d' => 'd',
+ '%e' => function ($timestamp) {
+ return sprintf('% 2u', $timestamp->format('j'));
+ },
+ '%j' => function ($timestamp) {
+ // Day number in year, 001 to 366
+ return sprintf('%03d', $timestamp->format('z')+1);
+ },
+ '%u' => 'N',
+ '%w' => 'w',
+
+ // Week
+ '%U' => function ($timestamp) {
+ // Number of weeks between date and first Sunday of year
+ $day = new \DateTime(sprintf('%d-01 Sunday', $timestamp->format('Y')));
+ return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
+ },
+ '%V' => 'W',
+ '%W' => function ($timestamp) {
+ // Number of weeks between date and first Monday of year
+ $day = new \DateTime(sprintf('%d-01 Monday', $timestamp->format('Y')));
+ return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
+ },
+
+ // Month
+ '%b' => $intl_formatter,
+ '%B' => $intl_formatter,
+ '%h' => $intl_formatter,
+ '%m' => 'm',
+
+ // Year
+ '%C' => function ($timestamp) {
+ // Century (-1): 19 for 20th century
+ return floor($timestamp->format('Y') / 100);
+ },
+ '%g' => function ($timestamp) {
+ return substr($timestamp->format('o'), -2);
+ },
+ '%G' => 'o',
+ '%y' => 'y',
+ '%Y' => 'Y',
+
+ // Time
+ '%H' => 'H',
+ '%k' => function ($timestamp) {
+ return sprintf('% 2u', $timestamp->format('G'));
+ },
+ '%I' => 'h',
+ '%l' => function ($timestamp) {
+ return sprintf('% 2u', $timestamp->format('g'));
+ },
+ '%M' => 'i',
+ '%p' => 'A', // AM PM (this is reversed on purpose!)
+ '%P' => 'a', // am pm
+ '%r' => 'h:i:s A', // %I:%M:%S %p
+ '%R' => 'H:i', // %H:%M
+ '%S' => 's',
+ '%T' => 'H:i:s', // %H:%M:%S
+ '%X' => $intl_formatter, // Preferred time representation based on locale, without the date
+
+ // Timezone
+ '%z' => 'O',
+ '%Z' => 'T',
+
+ // Time and Date Stamps
+ '%c' => $intl_formatter,
+ '%D' => 'm/d/Y',
+ '%F' => 'Y-m-d',
+ '%s' => 'U',
+ '%x' => $intl_formatter,
+ ];
+
+ $out = preg_replace_callback('/(?format($replace);
+ }
+ else {
+ return $replace($timestamp, $match[1]);
+ }
+ }, $format);
+
+ $out = str_replace('%%', '%', $out);
+ return $out;
+}
diff --git a/include/thirdparty/time/strftime.php b/include/thirdparty/time/strftime.php
index a952444..921158c 100644
--- a/include/thirdparty/time/strftime.php
+++ b/include/thirdparty/time/strftime.php
@@ -1,190 +1,201 @@
+ * @param string $format The format string. See https://www.php.net/manual/en/function.strftime.php for details.
+ * @param int|string|DateTimeInterface|null $timestamp (Optional) The timestamp to format. If null, uses the current time.
+ * @param string|null $locale (Optional) The locale to use. If null, uses the default locale.
+ * @param string|null $timezone (Optional) The timezone to use. If null, uses the default timezone.
+ * @return string|false The formatted string, or false on failure.
+ * @throws InvalidArgumentException
*/
-function strftime(string $format, $timestamp = null, ?string $locale = null): string
+function strftime(string $format, int|string|DateTimeInterface|null $timestamp = null, ?string $locale = null, ?string $timezone = null): string|false
{
- if (null === $timestamp) {
- $timestamp = new \DateTime;
- }
- elseif (is_numeric($timestamp)) {
- $timestamp = date_create('@' . $timestamp);
+ if (!extension_loaded('intl')) {
+ trigger_error('The intl extension is not loaded.', E_USER_WARNING);
+ return false;
+ }
- if ($timestamp) {
- $timestamp->setTimezone(new \DateTimezone(date_default_timezone_get()));
- }
- }
- elseif (is_string($timestamp)) {
- $timestamp = date_create($timestamp);
- }
+ // Handle Timestamp Input and Create DateTime Object
+ try {
+ if ($timestamp === null) {
+ $dateTime = new DateTime();
+ } elseif (is_numeric($timestamp)) {
+ $dateTime = new DateTime('@' . $timestamp);
+ $dateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ } elseif (is_string($timestamp)) {
+ $dateTime = new DateTime($timestamp);
+ } elseif ($timestamp instanceof DateTimeInterface) {
+ $dateTime = $timestamp;
+ } else {
+ throw new InvalidArgumentException('$timestamp argument is not a valid date-time string nor a DateTime object nor a valid UNIX timestamp.');
+ }
+ } catch (\Exception $e) {
+ throw new InvalidArgumentException('Invalid timestamp format', 0, $e);
+ }
- if (!($timestamp instanceof \DateTimeInterface)) {
- throw new \InvalidArgumentException('$timestamp argument is neither a valid UNIX timestamp, a valid date-time string or a DateTime object.');
- }
+ // Set Locale and Timezone (use defaults if not provided)
+ $locale = $locale ?? \Locale::getDefault();
+ $timezone = $timezone ?? date_default_timezone_get();
+ $timeZoneObject = new DateTimeZone($timezone);
+ $dateTime->setTimezone($timeZoneObject);
- $locale = substr((string) $locale, 0, 5);
+ // Format Map: strftime to ICU
+ $formatMap = [
+ '%a' => 'EEE', // Abbreviated weekday name
+ '%A' => 'EEEE', // Full weekday name
+ '%b' => 'MMM', // Abbreviated month name
+ '%B' => 'MMMM', // Full month name
+ '%c' => 'EEE MMM dd HH:mm:ss yyyy', // Preferred date and time representation (locale-dependent)
+ '%C' => null, // Century number (year/100, truncated to integer)
+ '%d' => 'dd', // Day of the month as a decimal number (01-31)
+ '%D' => 'MM/dd/yy', // Short MM/DD/YY date
+ '%e' => 'd', // Day of the month as a decimal number (1-31); a single digit is preceded by a space
+ '%F' => 'yyyy-MM-dd', // ISO 8601 date format (YYYY-MM-DD)
+ '%g' => 'yy', // The ISO 8601 week-based year without the century (00-99) (approximation)
+ '%G' => 'yyyy', // The ISO 8601 week-based year with century
+ '%h' => 'MMM', // Same as %b
+ '%H' => 'HH', // Hour as a decimal number (00-23)
+ '%I' => 'hh', // Hour as a decimal number (01-12)
+ '%j' => null, // Day of the year as a decimal number (001-366)
+ '%m' => 'MM', // Month as a decimal number (01-12)
+ '%M' => 'mm', // Minute as a decimal number (00-59)
+ '%n' => "\n", // A newline character
+ '%p' => 'a', // AM or PM
+ '%P' => null, // am or pm (lowercase)
+ '%r' => 'hh:mm:ss a', // AM/PM time format
+ '%R' => 'HH:mm', // 24-hour HH:MM time format
+ '%s' => null, // Number of seconds since the Epoch
+ '%S' => 'ss', // Second as a decimal number (00-60)
+ '%t' => "\t", // A tab character
+ '%T' => 'HH:mm:ss', // 24-hour time format
+ '%u' => null, // ISO 8601 weekday as number with Monday as 1
+ '%U' => null, // Week number of the current year (Sunday as first day)
+ '%V' => null, // ISO 8601 week number
+ '%w' => null, // Weekday as a decimal number (0-6), with Sunday as 0
+ '%W' => null, // Week number of the current year, starting with the first Monday as the first week
+ '%x' => 'MM/dd/yyyy', // Preferred date representation (locale-dependent)
+ '%X' => 'HH:mm:ss', // Preferred time representation (locale-dependent)
+ '%y' => 'yy', // Year without century (00-99)
+ '%Y' => 'yyyy', // Year with century
+ '%z' => 'ZZZZ', // Numeric timezone offset. E.g., -0800
+ '%Z' => 'z', // Timezone abbreviation
+ '%%' => '%', // A literal '%' character
+ '%k' => null, // Hour in 24-hour format, space-padded
+ '%l' => null, // Hour in 12-hour format, space-padded
+ ];
- $intl_formats = [
- '%a' => 'EEE', // An abbreviated textual representation of the day Sun through Sat
- '%A' => 'EEEE', // A full textual representation of the day Sunday through Saturday
- '%b' => 'MMM', // Abbreviated month name, based on the locale Jan through Dec
- '%B' => 'MMMM', // Full month name, based on the locale January through December
- '%h' => 'MMM', // Abbreviated month name, based on the locale (an alias of %b) Jan through Dec
- ];
+ // Build ICU Format String
+ $icuFormat = '';
+ $len = strlen($format);
- $intl_formatter = function (\DateTimeInterface $timestamp, string $format) use ($intl_formats, $locale) {
- $tz = $timestamp->getTimezone();
- $date_type = \IntlDateFormatter::FULL;
- $time_type = \IntlDateFormatter::FULL;
- $pattern = '';
+ for ($i = 0; $i < $len; $i++) {
+ if ($format[$i] == '%') {
+ $i++;
+ if (!isset($format[$i])) {
+ return false; // Invalid format. Trailing %.
+ }
- // %c = Preferred date and time stamp based on locale
- // Example: Tue Feb 5 00:45:10 2009 for February 5, 2009 at 12:45:10 AM
- if ($format == '%c') {
- $date_type = \IntlDateFormatter::LONG;
- $time_type = \IntlDateFormatter::SHORT;
- }
- // %x = Preferred date representation based on locale, without the time
- // Example: 02/05/09 for February 5, 2009
- elseif ($format == '%x') {
- $date_type = \IntlDateFormatter::SHORT;
- $time_type = \IntlDateFormatter::NONE;
- }
- // Localized time format
- elseif ($format == '%X') {
- $date_type = \IntlDateFormatter::NONE;
- $time_type = \IntlDateFormatter::MEDIUM;
- }
- else {
- $pattern = $intl_formats[$format];
- }
+ $key = '%' . $format[$i];
+ if (isset($formatMap[$key])) {
+ if ($formatMap[$key] === null) {
+ // Handle cases where a direct mapping isn't possible
+ switch ($key) {
+ case '%C':
+ $icuFormat .= floor($dateTime->format('Y') / 100);
+ break;
+ case '%j':
+ $icuFormat .= sprintf('%03d', (int)$dateTime->format('z') + 1);
+ break;
+ case '%s':
+ $icuFormat .= $dateTime->getTimestamp();
+ break;
+ case '%k':
+ $icuFormat .= sprintf('% 2u', $dateTime->format('G')); // Hour in 24-hour format, space-padded
+ break;
+ case '%l':
+ $icuFormat .= sprintf('% 2u', $dateTime->format('g')); // Hour in 12-hour format, space-padded
+ break;
+ case '%u': // ISO 8601 weekday as number with Monday as 1
+ $dayOfWeek = (int)$dateTime->format('N');
+ $icuFormat .= $dayOfWeek;
+ break;
+ case '%w': // Weekday as a decimal number (0-6), with Sunday as 0
+ $icuFormat .= $dateTime->format('w');
+ break;
+ case '%U': // Week number of the current year as a decimal number, starting with the first Sunday as the first week
+ case '%W': // Week number of the current year as a decimal number, starting with the first Monday as the first week
+ case '%V': // The ISO 8601 week number (01-53)
+ $calendar = IntlCalendar::createInstance($timeZoneObject, $locale);
+ $calendar->setTime($dateTime->getTimestamp() * 1000); // IntlCalendar uses milliseconds
- return (new \IntlDateFormatter($locale, $date_type, $time_type, $tz, null, $pattern))->format($timestamp);
- };
+ if ($key == '%U') {
+ $icuFormat .= $calendar->get(IntlCalendar::FIELD_WEEK_OF_YEAR);
+ } elseif ($key == '%W') {
+ $calendar->setMinimalDaysInFirstWeek(4); // ISO 8601
+ $calendar->setFirstDayOfWeek(IntlCalendar::MONDAY); // ISO 8601
+ $icuFormat .= $calendar->get(IntlCalendar::FIELD_WEEK_OF_YEAR);
- // Same order as https://www.php.net/manual/en/function.strftime.php
- $translation_table = [
- // Day
- '%a' => $intl_formatter,
- '%A' => $intl_formatter,
- '%d' => 'd',
- '%e' => function ($timestamp) {
- return sprintf('% 2u', $timestamp->format('j'));
- },
- '%j' => function ($timestamp) {
- // Day number in year, 001 to 366
- return sprintf('%03d', $timestamp->format('z')+1);
- },
- '%u' => 'N',
- '%w' => 'w',
+ } else { // %V
+ $calendar->setMinimalDaysInFirstWeek(4); // ISO 8601
+ $calendar->setFirstDayOfWeek(IntlCalendar::MONDAY); // ISO 8601
+ $icuFormat .= sprintf("%02d", $calendar->get(IntlCalendar::FIELD_WEEK_OF_YEAR)); //format to 2 digits
+ }
+ break;
+ case '%P':
+ $amPm = $dateTime->format('a');
+ $icuFormat .= strtolower($amPm);
+ break;
+ default:
+ return false; // Indicate unsupported format
+ }
+ } else {
+ $icuFormat .= $formatMap[$key];
+ }
+ } else {
+ return false; // Unknown format code.
+ }
+ } else {
+ $icuFormat .= $format[$i];
+ }
+ }
- // Week
- '%U' => function ($timestamp) {
- // Number of weeks between date and first Sunday of year
- $day = new \DateTime(sprintf('%d-01 Sunday', $timestamp->format('Y')));
- return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
- },
- '%V' => 'W',
- '%W' => function ($timestamp) {
- // Number of weeks between date and first Monday of year
- $day = new \DateTime(sprintf('%d-01 Monday', $timestamp->format('Y')));
- return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
- },
+ try {
+ $formatter = new IntlDateFormatter(
+ $locale,
+ IntlDateFormatter::FULL,
+ IntlDateFormatter::FULL,
+ $timeZoneObject,
+ IntlDateFormatter::GREGORIAN,
+ $icuFormat
+ );
- // Month
- '%b' => $intl_formatter,
- '%B' => $intl_formatter,
- '%h' => $intl_formatter,
- '%m' => 'm',
-
- // Year
- '%C' => function ($timestamp) {
- // Century (-1): 19 for 20th century
- return floor($timestamp->format('Y') / 100);
- },
- '%g' => function ($timestamp) {
- return substr($timestamp->format('o'), -2);
- },
- '%G' => 'o',
- '%y' => 'y',
- '%Y' => 'Y',
-
- // Time
- '%H' => 'H',
- '%k' => function ($timestamp) {
- return sprintf('% 2u', $timestamp->format('G'));
- },
- '%I' => 'h',
- '%l' => function ($timestamp) {
- return sprintf('% 2u', $timestamp->format('g'));
- },
- '%M' => 'i',
- '%p' => 'A', // AM PM (this is reversed on purpose!)
- '%P' => 'a', // am pm
- '%r' => 'h:i:s A', // %I:%M:%S %p
- '%R' => 'H:i', // %H:%M
- '%S' => 's',
- '%T' => 'H:i:s', // %H:%M:%S
- '%X' => $intl_formatter, // Preferred time representation based on locale, without the date
-
- // Timezone
- '%z' => 'O',
- '%Z' => 'T',
-
- // Time and Date Stamps
- '%c' => $intl_formatter,
- '%D' => 'm/d/Y',
- '%F' => 'Y-m-d',
- '%s' => 'U',
- '%x' => $intl_formatter,
- ];
-
- $out = preg_replace_callback('/(?format($replace);
- }
- else {
- return $replace($timestamp, $match[1]);
- }
- }, $format);
-
- $out = str_replace('%%', '%', $out);
- return $out;
-}
+ return $formatter->format($dateTime);
+ } catch (\Exception $e) {
+ // Handle invalid locale or timezone
+ error_log("IntlDateFormatter exception: " . $e->getMessage()); // Log the error
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/include/tool.php b/include/tool.php
index a1c3045..60a0b07 100644
--- a/include/tool.php
+++ b/include/tool.php
@@ -2,7 +2,10 @@
namespace gp{
- use function \PHP81_BC\strftime;
+
+use intltime;
+use function \intltime\strftime;
+
defined('is_running') or die('Not an entry point...');
class tool{