PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 1.5.02
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v1.5.02
2.4.0 2.3.0 2.2.5 2.2.0 2.1.2 2.1.1 trunk 1.10.0 1.10.01 1.10.02 1.5.0 1.5.01 1.5.02 1.5.1 1.5.10 1.5.20 1.5.21 1.5.22 1.5.23 1.5.24 1.5.25 1.6.0 1.7.0 1.7.1 1.7.2 All 33 releases
fluent-booking / app / Services / DateTimeHelper.php

DateTimeHelper.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution 1.5.02, at app/Services/DateTimeHelper.php

318 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBooking\App\Services;
4
5 class DateTimeHelper
6 {
7 public static function getTimeZones($grouped = false)
8 {
9 $tz_identifiers = timezone_identifiers_list();
10
11 if (!$grouped) {
12 return $tz_identifiers;
13 }
14
15 $lists = [];
16
17 $topLevels = [];
18 foreach ($tz_identifiers as $tz) {
19 $parts = explode('/', $tz);
20 if (count($parts) > 1) {
21 $lists[$parts[0]][] = $tz;
22 } else {
23 $topLevels[$tz][] = $tz;
24 }
25 }
26
27 return array_merge($topLevels, $lists);
28 }
29
30 public static function getFlatGroupedTimeZones()
31 {
32 $tz_identifiers = timezone_identifiers_list();
33
34 $lists = [];
35 $topLevels = [];
36 foreach ($tz_identifiers as $tz) {
37 $parts = explode('/', $tz);
38 if (count($parts) > 1) {
39 $lists[] = [
40 'label' => $tz,
41 'value' => $tz,
42 'group' => $parts[0]
43 ];
44 } else {
45 $topLevels[] = [
46 'label' => $tz,
47 'value' => $tz,
48 'group' => $tz
49 ];
50 }
51 }
52
53 return $topLevels + $lists;
54 }
55
56 public static function getTimeZone()
57 {
58 $timeZone = wp_timezone_string();
59
60 if (!in_array($timeZone, \DateTimeZone::listIdentifiers())) {
61 $timeZone = 'UTC';
62 }
63
64 return $timeZone;
65 }
66
67 public static function convertToUtc($dateTime, $timezone, $format = 'Y-m-d H:i:s')
68 {
69 $dateTime = new \DateTime($dateTime, new \DateTimeZone($timezone));
70 $dateTime->setTimezone(new \DateTimeZone('UTC'));
71 return $dateTime->format($format);
72 }
73
74 public static function convertFromUtc($dateTime, $timezone, $format = 'Y-m-d H:i:s')
75 {
76 $dateTime = new \DateTime($dateTime, new \DateTimeZone('UTC'));
77
78 if ($timezone != 'UTC') {
79 $dateTime->setTimezone(new \DateTimeZone($timezone));
80 }
81
82 return $dateTime->format($format);
83 }
84
85 public static function convertToTimeZone($dateTime, $fromTimeZone, $toTimeZone, $format = 'Y-m-d H:i:s', $date = null)
86 {
87 if ($fromTimeZone == $toTimeZone) {
88 return gmdate($format, strtotime($dateTime)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
89 }
90
91 if ($date) {
92 $dateTime = gmdate('Y-m-d H:i', strtotime($date . ' ' . gmdate('H:i', strtotime($dateTime)))); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
93 }
94
95 $dateTime = new \DateTime($dateTime, new \DateTimeZone($fromTimeZone));
96 $dateTime->setTimezone(new \DateTimeZone($toTimeZone));
97 return $dateTime->format($format);
98 }
99
100 public static function getDateWithoutDST($timezone)
101 {
102 if (!self::isDaylightSavingActive('2024-01-03', $timezone)) {
103 return '2024-01-03';
104 }
105 return '2024-06-03';
106 }
107
108 public static function convertToIso($dateTime, $fromTimeZone = 'UTC')
109 {
110 $dateTime = new \DateTime($dateTime, new \DateTimeZone($fromTimeZone));
111 return $dateTime->format('Y-m-d\TH:i:s\Z');
112 }
113
114 public static function convertFromIso($dateTime, $toTimeZone = 'UTC')
115 {
116 $dateTime = new \DateTime($dateTime, new \DateTimeZone('UTC'));
117 $dateTime->setTimezone(new \DateTimeZone($toTimeZone));
118 return $dateTime->format('Y-m-d H:i:s');
119 }
120
121 public static function getTimestamp($timezone = 'UTC')
122 {
123 $dateTime = new \DateTime(gmdate('Y-m-d H:i:s'), new \DateTimeZone('UTC')); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
124 $dateTime->setTimezone(new \DateTimeZone($timezone));
125 $date = $dateTime->format('Y-m-d H:i:s');
126 return strtotime($date);
127 }
128
129 public static function formatToLocale($dateTime, $for = 'date')
130 {
131 // $for can be date | date_time | time
132 $dateFormat = get_option('date_format');
133
134 if ($for == 'date_time') {
135 $dateFormat .= ' ' . get_option('time_format');
136 } elseif ($for == 'time') {
137 $dateFormat = get_option('time_format');
138 }
139
140 return date_i18n($dateFormat, strtotime($dateTime)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
141 }
142
143 public static function getAvailableDateFormats()
144 {
145 $dateFormats = apply_filters('fluent_booking/available_date_formats', [
146 'm/d/Y' => 'm/d/Y - (Ex: 05/20/2024)', // USA
147 'd/m/Y' => 'd/m/Y - (Ex: 20/05/2024)', // Canada, UK
148 'd.m.Y' => 'd.m.Y - (Ex: 20.05.2024)', // Germany
149 'n/j/y' => 'n/j/y - (Ex: 5/20/24)',
150 'm/d/y' => 'm/d/y - (Ex: 05/20/24)',
151 'M/d/Y' => 'M/d/Y - (Ex: May/20/2024)',
152 'y/m/d' => 'y/m/d - (Ex: 24/05/20)',
153 'Y-m-d' => 'Y-m-d - (Ex: 2024-05-20)',
154 'd-M-y' => 'd-M-y - (Ex: 20-May-24)',
155 'F j, Y' => 'F j, Y - (Ex: May 20, 2024)'
156 ]);
157
158 $formatted = [];
159 foreach ($dateFormats as $format => $label) {
160 $formatted[] = [
161 'label' => $label,
162 'value' => $format,
163 ];
164 }
165 return $formatted;
166 }
167
168 public static function convertPhpDateToDayJSFormay($phpFormat)
169 {
170 // Mapping PHP date format characters to Day.js format characters
171 $replacements = [
172 // Day
173 'd' => 'DD', // Day of the month, 2 digits with leading zeros
174 'D' => 'ddd', // A textual representation of a day, three letters
175 'j' => 'D', // Day of the month without leading zeros
176 'l' => 'dddd', // A full textual representation of the day of the week
177 'N' => 'E', // ISO-8601 numeric representation of the day of the week
178 'S' => 'o', // English ordinal suffix for the day of the month, 2 characters
179 'w' => 'd', // Numeric representation of the day of the week
180 'z' => 'DDD', // The day of the year (starting from 0)
181
182 // Week
183 'W' => 'W', // ISO-8601 week number of year, weeks starting on Monday
184
185 // Month
186 'F' => 'MMMM', // A full textual representation of a month
187 'm' => 'MM', // Numeric representation of a month, with leading zeros
188 'M' => 'MMM', // A short textual representation of a month, three letters
189 'n' => 'M', // Numeric representation of a month, without leading zeros
190 't' => '', // Not supported in Day.js (Number of days in the given month)
191
192 // Year
193 'L' => '', // Not supported in Day.js (Whether it's a leap year)
194 'o' => 'GGGG', // ISO-8601 week-numbering year
195 'Y' => 'YYYY', // A full numeric representation of a year, 4 digits
196 'y' => 'YY', // A two digit representation of a year
197
198 // Time
199 'a' => 'a', // Lowercase Ante meridiem and Post meridiem
200 'A' => 'A', // Uppercase Ante meridiem and Post meridiem
201 'B' => '', // Not supported in Day.js (Swatch Internet time)
202 'g' => 'h', // 12-hour format of an hour without leading zeros
203 'G' => 'H', // 24-hour format of an hour without leading zeros
204 'h' => 'hh', // 12-hour format of an hour with leading zeros
205 'H' => 'HH', // 24-hour format of an hour with leading zeros
206 'i' => 'mm', // Minutes with leading zeros
207 's' => 'ss', // Seconds with leading zeros
208 'u' => 'SSS', // Milliseconds (Day.js uses SSS for fractional seconds)
209 'v' => 'SSS', // Milliseconds (Day.js uses SSS for fractional seconds)
210
211 // Timezone
212 'e' => '', // Not supported in Day.js (Timezone identifier)
213 'I' => '', // Not supported in Day.js (Whether or not the date is in daylight saving time)
214 'O' => 'ZZ', // Difference to Greenwich time (GMT) in hours
215 'P' => 'Z', // Difference to Greenwich time (GMT) with colon between hours and minutes
216 'T' => '', // Not supported in Day.js (Timezone abbreviation)
217 'Z' => '', // Not supported in Day.js (Timezone offset in seconds)
218
219 // Full Date/Time
220 'c' => 'YYYY-MM-DDTHH:mm:ssZ', // ISO 8601 date
221 'r' => 'ddd, DD MMM YYYY HH:mm:ss ZZ', // RFC 2822 formatted date
222 'U' => 'X', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
223 ];
224
225 // Replace each PHP date format character with Day.js equivalent
226 $dayjsFormat = "";
227
228 for ($i = 0; $i < strlen($phpFormat); $i++) {
229 $char = $phpFormat[$i];
230
231 // Check if the character is escaped
232 if ($char === "\\") {
233 // Add the next character to the result as is, without mapping
234 $i++;
235 if ($i < strlen($phpFormat)) {
236 $dayjsFormat .= "\\" . $phpFormat[$i];
237 }
238 continue;
239 }
240
241 // Add the mapped character or the character itself if not found in the mapping
242 $dayjsFormat .= $replacements[$char] ?? $char;
243 }
244
245 return $dayjsFormat;
246 }
247
248 public static function getDateFormatter($isDayJs = false)
249 {
250 $format = get_option('date_format');
251 if ($isDayJs) {
252 return self::convertPhpDateToDayJSFormay($format);
253 }
254
255 return $format;
256 }
257
258 public static function getTimeFormatter($isDayJs = false)
259 {
260 $format = get_option('time_format');
261 if ($isDayJs) {
262 return self::convertPhpDateToDayJSFormay($format);
263 }
264
265 return $format;
266 }
267
268 public static function getTodayDate($timezone = 'UTC', $format = 'Y-m-d')
269 {
270 $dateTime = new \DateTime('now', new \DateTimeZone($timezone));
271 return $dateTime->format($format);
272 }
273
274 public static function getDayDifference($dateTime, $fromTimeZone, $toTimeZone, $refDate = 'now')
275 {
276 if ($refDate != 'now') {
277 $dateTime = gmdate('Y-m-d H:i', strtotime($refDate . ' ' . gmdate('H:i', strtotime($dateTime)))); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
278 }
279
280 $currentDate = new \DateTime($refDate, new \DateTimeZone($fromTimeZone));
281
282 $originalDateTime = new \DateTime($dateTime, new \DateTimeZone($fromTimeZone));
283
284 $originalDateTime->setTimezone(new \DateTimeZone($toTimeZone));
285
286 return $originalDateTime->format('z') - $currentDate->format('z');
287 }
288
289 public static function getDaylightSavingTime($timezone)
290 {
291 $timezone = new \DateTimeZone($timezone);
292 $dateTime = new \DateTime('2024-01-01', $timezone);
293
294 $currentOffset = $timezone->getOffset($dateTime);
295
296 $sixMonthsAgo = clone $dateTime;
297 $sixMonthsAgo->modify('+6 month');
298 $offsetBefore = $timezone->getOffset($sixMonthsAgo);
299
300 $dstDifference = $currentOffset - $offsetBefore;
301
302 return abs($dstDifference) / 60;
303 }
304
305 public static function isDaylightSavingActive($dateTime, $timezone)
306 {
307 if (!$dateTime || !$timezone) {
308 return false;
309 }
310
311 $dateTimeObject = new \DateTime($dateTime, new \DateTimeZone($timezone));
312
313 $isDstActive = $dateTimeObject->format('I');
314
315 return $isDstActive;
316 }
317 }
318