diff --git a/libraries/src/Form/Field/CalendarField.php b/libraries/src/Form/Field/CalendarField.php index 428ca5a236f63..900ee2851c2f5 100644 --- a/libraries/src/Form/Field/CalendarField.php +++ b/libraries/src/Form/Field/CalendarField.php @@ -11,8 +11,10 @@ \defined('JPATH_PLATFORM') or die; use DateTime; +use DateTimeImmutable; use Joomla\CMS\Factory; use Joomla\CMS\Form\FormField; +use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; @@ -274,7 +276,8 @@ protected function getInput() { $tz = date_default_timezone_get(); date_default_timezone_set('UTC'); - $this->value = strftime($this->format, strtotime($this->value)); + $date = DateTimeImmutable::createFromFormat('U', strtotime($this->value)); + $this->value = $date->format(HTMLHelper::strftimeFormatToDateFormat($this->format)); date_default_timezone_set($tz); } else diff --git a/libraries/src/HTML/HTMLHelper.php b/libraries/src/HTML/HTMLHelper.php index 92893b35facb0..d2984d811a456 100644 --- a/libraries/src/HTML/HTMLHelper.php +++ b/libraries/src/HTML/HTMLHelper.php @@ -1072,7 +1072,7 @@ public static function tooltipText($title = '', $content = '', $translate = true * @param string $value The date value * @param string $name The name of the text field * @param string $id The id of the text field - * @param string $format The date format + * @param string $format The date format using the @deprecated strftime format parameters * @param mixed $attribs Additional HTML attributes * The array can have the following keys: * readonly Sets the readonly parameter for the input tag @@ -1085,6 +1085,7 @@ public static function tooltipText($title = '', $content = '', $translate = true * * @since 1.5 * + * @note This method uses deprecated strftime format parameters for backward compatibility. */ public static function calendar($value, $name, $id, $format = '%Y-%m-%d', $attribs = array()) { @@ -1131,7 +1132,8 @@ public static function calendar($value, $name, $id, $format = '%Y-%m-%d', $attri { $tz = date_default_timezone_get(); date_default_timezone_set('UTC'); - $inputvalue = strftime($format, strtotime($value)); + $date = \DateTimeImmutable::createFromFormat('U', strtotime($value)); + $inputvalue = $date->format(self::strftimeFormatToDateFormat($format)); date_default_timezone_set($tz); } else @@ -1284,4 +1286,63 @@ private static function checkFileOrder($first, $second) return ''; } + + /** + * Convert strftime format to php date format as strftime is deprecated and we have + * to be able to provide same backward compatibility with existing format strings. + * + * @param $strftimeformat string The format compatible with strftime. + * + * @return string The format compatible with PHP's Date functions. + * + * @since __DEPLOY_VERSION__ + * + * @throws \Exception + * + * @note Thanks to @relipse for https://stackoverflow.com/questions/22665959/using-php-strftime-using-date-format-string/62781773#62781773 + */ + public static function strftimeFormatToDateFormat(string $strftimeformat): string + { + $unsupported = ['%U', '%V', '%C', '%g', '%G']; + $foundunsupported = []; + + foreach ($unsupported as $unsup) + { + if (strpos($strftimeformat, $unsup) !== false) + { + $foundunsupported[] = $unsup; + } + } + + if (!empty($foundunsupported)) + { + throw new \Exception("Found these unsupported chars: " . implode(",", $foundunsupported) . ' in ' . $strftimeformat); + } + + /** + * It is important to note that some do not translate accurately + * ie. lowercase L is supposed to convert to number with a preceding space if it is under 10, + * there is no accurate conversion, so we just use 'g' + */ + $phpdateformat = str_replace( + ['%a','%A','%d','%e','%u','%w','%W','%b','%h','%B','%m','%y','%Y', '%D', '%F', '%x', '%n', '%t', '%H', '%k', '%I', '%l', '%M', '%p', '%P', + // %I:%M:%S %p + '%r', + // %H:%M + '%R', + '%S', + // %H:%M:%S + '%T', + '%X', '%z', '%Z', '%c', '%s', '%%' + ], + ['D','l', 'd', 'j', 'N', 'w', 'W', 'M', 'M', 'F', 'm', 'y', 'Y', 'm/d/y', 'Y-m-d', 'm/d/y', "\n", "\t", 'H', 'G', 'h', 'g', 'i', 'A', 'a', 'h:i:s A', 'H:i', 's', 'H:i:s', 'H:i:s', 'O', 'T', + // Tue Feb 5 00:45:10 2009 + 'D M j H:i:s Y' , + 'U', '%' + ], + $strftimeformat + ); + + return $phpdateformat; + } } diff --git a/tests/Unit/Libraries/Cms/Html/HtmlHelperTest.php b/tests/Unit/Libraries/Cms/Html/HtmlHelperTest.php new file mode 100644 index 0000000000000..2f547d7b84763 --- /dev/null +++ b/tests/Unit/Libraries/Cms/Html/HtmlHelperTest.php @@ -0,0 +1,61 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Tests\Unit\Libraries\Cms\Html; + +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\Tests\Unit\UnitTestCase; + +/** + * Test class for HtmlHelperTest. + * + * @since __DEPLOY_VERSION__ + */ +class HtmlHelperTest extends UnitTestCase +{ + /** + * @var string Base HTML Output with place holders + * + * @since __DEPLOY_VERSION__ + */ + private $template = '