PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
← All changes | app/Services/DateTime/DateTime.php +23 -7 1.3.19 → 1.6.5 View file →
@@ -45,9 +45,9 @@
45 45 $dt = clone $datetime;
46 46
47 47 // If fromTz is specified and the datetime doesn't have timezone info, set it
48 48 if ($fromTz && $dt->getTimezone()->getName() === 'UTC' && $fromTz !== 'UTC') {
49 - $dt = $dt->setTimezone(new \DateTimeZone($fromTz));
49 + $dt = $dt->setTimezone(static::resolveTimezone($fromTz));
50 50 }
51 51
52 52 return $dt->setTimezone(new \DateTimeZone('UTC'));
53 53 }
@@ -64,9 +64,9 @@
64 64
65 65 // If fromTz is provided and the parsed string doesn't contain timezone info
66 66 if ($fromTz && !preg_match('/[+-]\d{2}:?\d{2}$|Z$|[A-Z]{3,4}$/i', trim($datetime))) {
67 67 // Create a new datetime in the specified timezone
68 - $dt = static::createFromFormat('Y-m-d H:i:s', $dt->format('Y-m-d H:i:s'), new \DateTimeZone($fromTz));
68 + $dt = static::createFromFormat('Y-m-d H:i:s', $dt->format('Y-m-d H:i:s'), static::resolveTimezone($fromTz));
69 69 }
70 70
71 71 return $dt->setTimezone(new \DateTimeZone('UTC'));
72 72 }
@@ -88,13 +88,10 @@
88 88 * @return static
89 89 */
90 90 public static function gmtToTimezone($datetime = null, $timezone = null): DateTime
91 91 {
92 - // If not a string or DateTimeZone, fallback to wp_timezone()
93 92 if (!$timezone instanceof \DateTimeZone) {
94 - $timezone = is_string($timezone)
95 - ? new \DateTimeZone($timezone)
96 - : wp_timezone(); // returns a DateTimeZone object
93 + $timezone = static::resolveTimezone($timezone);
97 94 }
98 95
99 96
100 97 if (is_null($datetime)) {
@@ -118,8 +115,27 @@
118 115
119 116 }
120 117
121 118
119 + /**
120 + * Safely resolve a timezone string to a DateTimeZone object.
121 + *
122 + * PHP 8.4 throws on deprecated aliases like Asia/Saigon, so we validate
123 + * with timezone_open() before constructing. Old orders may carry such aliases
124 + * from the browser-captured user_tz stored in order config at checkout time.
125 + * Falls back to the supplied $fallback, or wp_timezone() if none given.
126 + */
127 + private static function resolveTimezone($timezone, $fallback = null): \DateTimeZone
128 + {
129 + if ($timezone instanceof \DateTimeZone) {
130 + return $timezone;
131 + }
132 + if (is_string($timezone) && $timezone !== '' && @timezone_open($timezone) !== false) {
133 + return new \DateTimeZone($timezone);
134 + }
135 + return ($fallback instanceof \DateTimeZone) ? $fallback : wp_timezone();
136 + }
137 +
122 138 public function getDefaultTimezone()
123 139 {
124 140 return new DateTimeZone('UTC');
125 141 }
@@ -135,9 +151,9 @@
135 151 $dt = new \DateTimeImmutable($datetimeString);
136 152 } else {
137 153 $tz = $timezone instanceof \DateTimeZone
138 154 ? $timezone
139 - : ($timezone ? new \DateTimeZone($timezone) : new DateTimeZone('UTC'));
155 + : ($timezone ? static::resolveTimezone($timezone, new \DateTimeZone('UTC')) : new DateTimeZone('UTC'));
140 156
141 157 $dt = new \DateTimeImmutable($datetimeString, $tz);
142 158 }
143 159