Skip to content

Commit d121a9f

Browse files
committed
MC-36836: Datepicker issue on Admin GRID
1 parent 2ead5af commit d121a9f

File tree

2 files changed

+90
-25
lines changed

2 files changed

+90
-25
lines changed

lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ class Timezone implements TimezoneInterface
3030
\IntlDateFormatter::SHORT,
3131
];
3232

33+
/**
34+
* @var array
35+
*/
36+
private $dateFormatterCache = [];
37+
3338
/**
3439
* @var string
3540
*/
@@ -174,16 +179,9 @@ public function date($date = null, $locale = null, $useTimezone = true, $include
174179
case ($date instanceof \DateTimeImmutable):
175180
return new \DateTime($date->format('Y-m-d H:i:s'), $date->getTimezone());
176181
case (!is_numeric($date)):
177-
$timeType = $includeTime ? \IntlDateFormatter::SHORT : \IntlDateFormatter::NONE;
178-
$formatter = new \IntlDateFormatter(
179-
$locale,
180-
\IntlDateFormatter::MEDIUM,
181-
$timeType,
182-
new \DateTimeZone($timezone)
183-
);
184-
185182
$date = $this->appendTimeIfNeeded($date, $includeTime, $timezone, $locale);
186-
$date = $formatter->parse($date) ?: (new \DateTime($date))->getTimestamp();
183+
$date = $this->parseLocaleDate($date, $locale, $timezone, $includeTime)
184+
?: (new \DateTime($date))->getTimestamp();
187185
break;
188186
}
189187

@@ -343,33 +341,77 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s')
343341
private function appendTimeIfNeeded($date, $includeTime, $timezone, $locale)
344342
{
345343
if ($includeTime && !preg_match('/\d{1}:\d{2}/', $date)) {
346-
347-
$formatterWithoutHour = new \IntlDateFormatter(
348-
$locale,
349-
\IntlDateFormatter::MEDIUM,
350-
\IntlDateFormatter::NONE,
351-
new \DateTimeZone($timezone)
352-
);
353-
$convertedDate = $formatterWithoutHour->parse($date);
354-
344+
$convertedDate = $this->parseLocaleDate($date, $locale, $timezone, false);
355345
if (!$convertedDate) {
356346
throw new LocalizedException(
357347
new Phrase(
358348
'Could not append time to DateTime'
359349
)
360350
);
361-
362351
}
363352

364-
$formatterWithHour = new \IntlDateFormatter(
353+
$formatterWithHour = $this->getDateFormatter(
365354
$locale,
355+
$timezone,
366356
\IntlDateFormatter::MEDIUM,
367-
\IntlDateFormatter::SHORT,
368-
new \DateTimeZone($timezone)
357+
\IntlDateFormatter::SHORT
369358
);
370-
371359
$date = $formatterWithHour->format($convertedDate);
372360
}
373361
return $date;
374362
}
363+
364+
/**
365+
* Parse date by locale format through IntlDateFormatter
366+
*
367+
* @param string $date
368+
* @param string $locale
369+
* @param string $timeZone
370+
* @param bool $includeTime
371+
* @return int|null Timestamp of date
372+
*/
373+
private function parseLocaleDate(string $date, string $locale, string $timeZone, bool $includeTime): ?int
374+
{
375+
$allowedStyles = [\IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT];
376+
$timeStyle = $includeTime ? \IntlDateFormatter::SHORT : \IntlDateFormatter::NONE;
377+
378+
/**
379+
* Try to parse date with different styles
380+
*/
381+
foreach ($allowedStyles as $style) {
382+
$formatter = $this->getDateFormatter($locale, $timeZone, $style, $timeStyle);
383+
$timeStamp = $formatter->parse($date);
384+
if ($timeStamp) {
385+
return $timeStamp;
386+
}
387+
}
388+
389+
return null;
390+
}
391+
392+
/**
393+
* Get date formatter for locale
394+
*
395+
* @param string $locale
396+
* @param string $timeZone
397+
* @param int $style
398+
* @param int $timeStyle
399+
* @return \IntlDateFormatter
400+
*/
401+
private function getDateFormatter(string $locale, string $timeZone, int $style, int $timeStyle): \IntlDateFormatter
402+
{
403+
$cacheKey = "{$locale}_{$timeZone}_{$style}_{$timeStyle}";
404+
if (isset($this->dateFormatterCache[$cacheKey])) {
405+
return $this->dateFormatterCache[$cacheKey];
406+
}
407+
408+
$this->dateFormatterCache[$cacheKey] = new \IntlDateFormatter(
409+
$locale,
410+
$style,
411+
$timeStyle,
412+
new \DateTimeZone($timeZone)
413+
);
414+
415+
return $this->dateFormatterCache[$cacheKey];
416+
}
375417
}

lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,12 @@ public function testDateIncludeTime($date, $locale, $includeTime, $expectedTimes
101101

102102
/** @var \DateTime $dateTime */
103103
$dateTime = $timezone->date($date, $locale, true, $includeTime);
104-
$this->assertEquals($expectedTimestamp, $dateTime->getTimestamp());
104+
if (is_numeric($expectedTimestamp)) {
105+
$this->assertEquals($expectedTimestamp, $dateTime->getTimestamp());
106+
} else {
107+
$format = $includeTime ? DateTime::DATETIME_PHP_FORMAT : DateTime::DATE_PHP_FORMAT;
108+
$this->assertEquals($expectedTimestamp, date($format, $dateTime->getTimestamp()));
109+
}
105110
}
106111

107112
/**
@@ -151,7 +156,25 @@ public function dateIncludeTimeDataProvider(): array
151156
'el_GR', // locale
152157
false, // include time
153158
1635570000 // expected timestamp
154-
]
159+
],
160+
'Parse Saudi Arabia date without time' => [
161+
'31‏/8‏/2020 02020',
162+
'ar_SA',
163+
false,
164+
'2020-08-31'
165+
],
166+
'Parse date in short style with long year 1999' => [
167+
'9/11/1999',
168+
'en_US',
169+
false,
170+
'1999-09-11'
171+
],
172+
'Parse date in short style with long year 2099' => [
173+
'9/2/2099',
174+
'en_US',
175+
false,
176+
'2099-09-02'
177+
],
155178
];
156179
}
157180

0 commit comments

Comments
 (0)