PluginProbe ʕ •ᴥ•ʔ
Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress / 5.6.11
Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress v5.6.11
5.6.11 5.6.10 5.6.9 5.6.8 5.6.7 5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / helpers / time_helper.php
latepoint / lib / helpers Last commit date
activities_helper.php 5 months ago admin_nudges_helper.php 1 month ago agent_helper.php 5 months ago analytics_helper.php 1 month ago auth_helper.php 2 months ago blocks_helper.php 2 months ago booking_helper.php 1 day ago bricks_helper.php 5 months ago bundles_helper.php 2 months ago calendar_helper.php 1 month ago carts_helper.php 5 months ago connector_helper.php 5 months ago csv_helper.php 5 months ago customer_helper.php 3 months ago customer_import_helper.php 3 months ago database_helper.php 1 month ago debug_helper.php 5 months ago defaults_helper.php 5 months ago elementor_helper.php 5 months ago email_helper.php 5 months ago encrypt_helper.php 5 months ago events_helper.php 5 months ago form_helper.php 1 day ago icalendar_helper.php 5 months ago image_helper.php 5 months ago invoices_helper.php 1 month ago license_helper.php 5 months ago location_helper.php 5 months ago marketing_systems_helper.php 5 months ago meeting_systems_helper.php 5 months ago menu_helper.php 2 months ago meta_helper.php 5 months ago migrations_helper.php 5 months ago money_helper.php 5 months ago notifications_helper.php 5 months ago nps_survey_helper.php 5 months ago order_intent_helper.php 3 months ago orders_helper.php 1 month ago otp_helper.php 5 months ago pages_helper.php 1 day ago params_helper.php 5 months ago payments_helper.php 1 month ago paypal_connect_helper.php 1 month ago plugin_version_update_helper.php 4 months ago price_breakdown_helper.php 5 months ago process_jobs_helper.php 1 month ago processes_helper.php 1 day ago razorpay_connect_helper.php 1 month ago replacer_helper.php 1 day ago resource_helper.php 2 months ago roles_helper.php 1 month ago router_helper.php 5 months ago service_helper.php 5 months ago sessions_helper.php 5 months ago settings_helper.php 2 months ago short_links_systems_helper.php 5 months ago shortcodes_helper.php 2 months ago sms_helper.php 5 months ago steps_helper.php 1 day ago stripe_connect_helper.php 2 months ago styles_helper.php 5 months ago support_topics_helper.php 5 months ago time_helper.php 1 day ago timeline_helper.php 4 months ago transaction_helper.php 3 months ago transaction_intent_helper.php 5 months ago util_helper.php 1 month ago version_specific_updates_helper.php 1 month ago whatsapp_helper.php 3 months ago work_periods_helper.php 1 day ago wp_datetime.php 5 months ago wp_user_helper.php 5 months ago
time_helper.php
595 lines
1 <?php
2
3 class OsTimeHelper {
4
5 private static $timezone = false;
6
7
8 public static function get_db_weekday_by_number( $number ) {
9 $weekdays = [ 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su' ];
10
11 return $weekdays[ $number - 1 ];
12 }
13
14 public static function is_valid_date( $date_string ) {
15 if ( empty( $date_string ) ) {
16 return false;
17 }
18 return (bool) strtotime( $date_string );
19 }
20
21 public static function reformat_date_string( $date_string, $from_format, $to_format ) {
22 $start_date_obj = OsWpDateTime::os_createFromFormat( $from_format, $date_string );
23
24 return $start_date_obj->format( $to_format );
25 }
26
27 public static function nice_date( $date ) {
28 if ( $date == OsTimeHelper::today_date( 'Y-m-d' ) ) {
29 $nice_date = __( 'Today', 'latepoint' );
30 } else {
31 $nice_date = self::get_nice_date_with_optional_year( $date, true );
32 }
33
34 return $nice_date;
35 }
36
37 public static function date_from_db( $date_string, $format = false, string $output_timezone_name = 'UTC' ) {
38 $timezone = new DateTimeZone( 'UTC' );
39 $date_obj = OsWpDateTime::os_createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $date_string, $timezone );
40 if ( empty( $date_obj ) ) {
41 $date_obj = self::now_datetime_object();
42 }
43 $date_obj->setTimezone( new DateTimeZone( $output_timezone_name ) );
44 if ( $format ) {
45 return $date_obj->format( $format );
46 }
47
48 return $date_obj;
49 }
50
51 public static function today_date( $date_format = 'Y-m-d' ) {
52 $today = new OsWpDateTime( 'today' );
53
54 return $today->format( $date_format );
55 }
56
57 public static function now_datetime_in_format( $date_format = LATEPOINT_DATETIME_DB_FORMAT, string $timezone = 'UTC' ) {
58 $now = self::now_datetime_object();
59 $now->setTimezone( new DateTimeZone( 'UTC' ) );
60
61 return $now->format( $date_format );
62 }
63
64 public static function now_datetime_utc() {
65 $now = self::now_datetime_object();
66 $now->setTimezone( new DateTimeZone( 'UTC' ) );
67
68 return $now;
69 }
70
71 public static function time_left_to_datetime( string $datetime, DateTimeZone $timezone ) {
72
73 $now_datetime = new OsWpDateTime( 'now', $timezone );
74 $event_datetime = OsWpDateTime::createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $datetime, $timezone );
75 $css_class = 'left-days';
76
77 $before = ( $now_datetime < $event_datetime ) ? __( 'in', 'latepoint' ) . ' ' : '';
78 $ago = ( $now_datetime > $event_datetime ) ? ' ' . __( 'ago', 'latepoint' ) : '';
79 $ago_class = empty( $ago ) ? '' : 'time-past';
80 if ( $event_datetime ) {
81 $diff = $now_datetime->diff( $event_datetime );
82 if ( $diff->d > 0 || $diff->m > 0 || $diff->y > 0 ) {
83 $left = $before . $diff->format( '%a ' . __( 'days', 'latepoint' ) ) . $ago;
84 } else {
85 if ( $diff->h > 0 ) {
86 $css_class = 'left-hours';
87 $left = $before . $diff->format( '%h ' . __( 'hours', 'latepoint' ) ) . $ago;
88 } else {
89 $css_class = 'left-minutes';
90 $left = $before . $diff->format( '%i ' . __( 'minutes', 'latepoint' ) ) . $ago;
91 }
92 }
93 } else {
94 $left = 'n/a';
95 }
96
97 return '<span class="time-left ' . esc_attr( $css_class ) . ' ' . esc_attr( $ago_class ) . '">' . esc_html( $left ) . '</span>';
98 }
99
100 public static function now_datetime_utc_in_db_format() {
101 return OsWpDateTime::datetime_in_utc( new OsWpDateTime( 'now' ), LATEPOINT_DATETIME_DB_FORMAT );
102 }
103
104 public static function custom_datetime_utc_in_db_format( string $time = 'now' ): string {
105 return OsWpDateTime::datetime_in_utc( new OsWpDateTime( $time ), LATEPOINT_DATETIME_DB_FORMAT );
106 }
107
108 public static function now_datetime_in_db_format() {
109 return self::now_datetime_in_format( LATEPOINT_DATETIME_DB_FORMAT );
110 }
111
112 public static function now_datetime_object() {
113 return new OsWpDateTime( 'now' );
114 }
115
116 public static function get_time_system() {
117 return OsSettingsHelper::get_time_system();
118 }
119
120 public static function get_time_format() {
121 return self::is_army_clock() ? 'H:i' : 'g:ia';
122 }
123
124 public static function is_army_clock() {
125 return ( self::get_time_system() == 24 );
126 }
127
128 public static function get_time_systems_list_for_select() {
129 return array(
130 array(
131 'value' => '12',
132 'label' => __( '12-hour clock', 'latepoint' ),
133 ),
134 array(
135 'value' => '24',
136 'label' => __( '24-hour clock', 'latepoint' ),
137 ),
138 );
139 }
140
141 public static function get_date_formats_list_for_select() {
142 return array(
143 array(
144 'value' => 'm/d/Y',
145 'label' => __( 'MM/DD/YYYY', 'latepoint' ),
146 ),
147 array(
148 'value' => 'm.d.Y',
149 'label' => __( 'MM.DD.YYYY', 'latepoint' ),
150 ),
151 array(
152 'value' => 'd/m/Y',
153 'label' => __( 'DD/MM/YYYY', 'latepoint' ),
154 ),
155 array(
156 'value' => 'd.m.Y',
157 'label' => __( 'DD.MM.YYYY', 'latepoint' ),
158 ),
159 array(
160 'value' => 'Y-m-d',
161 'label' => __( 'YYYY-MM-DD', 'latepoint' ),
162 ),
163 );
164 }
165
166 public static function get_time_systems_list() {
167 return array(
168 '12' => __( '12-hour clock', 'latepoint' ),
169 '24' => __( '24-hour clock', 'latepoint' ),
170 );
171 }
172
173
174 public static function format_date_with_locale( string $format, DateTime $date_obj ): string {
175 return OsUtilHelper::translate_months( $date_obj->format( $format ) );
176 }
177
178
179 public static function get_nice_date_with_optional_year( $date, $show_year_if_not_current = true, $short_month = false ) {
180 $d = OsWpDateTime::os_createFromFormat( 'Y-m-d', $date );
181 if ( ! $d ) {
182 return $date;
183 }
184 if ( ! $show_year_if_not_current || ( $d->format( 'Y' ) == OsTimeHelper::today_date( 'Y' ) ) ) {
185 return OsUtilHelper::translate_months( $d->format( OsSettingsHelper::get_readable_date_format( true, $short_month ) ) );
186 } else {
187 return OsUtilHelper::translate_months( $d->format( OsSettingsHelper::get_readable_date_format( false, $short_month ) ) );
188 }
189 }
190
191 public static function get_readable_date( DateTime $date, string $output_timezone_name = '' ): string {
192 if ( empty( $output_timezone_name ) ) {
193 $output_timezone_name = self::get_wp_timezone_name();
194 }
195 $date->setTimezone( new DateTimeZone( $output_timezone_name ) );
196
197 return self::format_date_with_locale( OsSettingsHelper::get_readable_date_format(), $date );
198 }
199
200 public static function get_readable_date_from_string( string $date, string $input_timezone_name = '', string $output_timezone_name = '' ): string {
201 if ( empty( $input_timezone_name ) ) {
202 $input_timezone_name = 'UTC';
203 }
204 if ( empty( $output_timezone_name ) ) {
205 $output_timezone_name = self::get_wp_timezone_name();
206 }
207
208 $date_obj = new OsWpDateTime( $date, new DateTimeZone( $input_timezone_name ) );
209
210 return self::get_readable_date( $date_obj, $output_timezone_name );
211 }
212
213 public static function get_wp_timezone() {
214 if ( self::$timezone ) {
215 return self::$timezone;
216 }
217 try {
218 $timezone_string = get_option( 'timezone_string' );
219 if ( ! empty( $timezone_string ) ) {
220 return new DateTimeZone( $timezone_string );
221 }
222 $offset = get_option( 'gmt_offset' );
223 $hours = (int) $offset;
224 $minutes = abs( ( $offset - (int) $offset ) * 60 );
225 $offset = sprintf( '%+03d:%02d', $hours, $minutes );
226 self::$timezone = new DateTimeZone( $offset );
227 } catch ( Exception $e ) {
228 return new DateTimeZone( 'UTC' );
229 }
230
231 return self::$timezone;
232 }
233
234 public static function get_wp_timezone_name() {
235 $timezone_obj = self::get_wp_timezone();
236 if ( $timezone_obj ) {
237 return $timezone_obj->getName();
238 } else {
239 return 'America/New_York';
240 }
241 }
242
243 public static function get_timezone_from_session() {
244 try {
245 $timezone = new DateTimeZone( self::get_timezone_name_from_session() );
246 } catch ( Exception $e ) {
247 $timezone = new DateTimeZone( self::get_wp_timezone_name() );
248 }
249
250 return $timezone;
251 }
252
253 public static function get_timezone_name_from_session() {
254 $timezone_name = self::get_wp_timezone_name();
255 $timezone_name = apply_filters( 'latepoint_timezone_name_from_session', $timezone_name );
256
257 return $timezone_name;
258 }
259
260 public static function is_timezone_saved_in_session() {
261 return ( isset( $_COOKIE[ LATEPOINT_SELECTED_TIMEZONE_COOKIE ] ) && ! empty( $_COOKIE[ LATEPOINT_SELECTED_TIMEZONE_COOKIE ] ) );
262 }
263
264 public static function set_timezone_name_in_cookie( $timezone_name ) {
265 OsSessionsHelper::setcookie( LATEPOINT_SELECTED_TIMEZONE_COOKIE, $timezone_name );
266 $_COOKIE[ LATEPOINT_SELECTED_TIMEZONE_COOKIE ] = $timezone_name;
267 }
268
269
270 public static function convert_datetime_to_minutes( DateTime $datetime ) {
271 return $datetime->format( 'i' ) + ( $datetime->format( 'G' ) * 60 );
272 }
273
274 public static function get_current_minutes() {
275 $now = new OsWpDateTime( 'now' );
276 return $now->format( 'i' ) + ( $now->format( 'G' ) * 60 );
277 }
278
279 public static function convert_time_to_minutes( $time, $ampm = false, $as_end_of_day = false ) {
280 if ( strpos( $time, ':' ) === false ) {
281 return 0;
282 }
283
284 list( $hours, $minutes ) = explode( ':', $time );
285 if ( $hours == '12' && $ampm == 'am' ) {
286 // midnight
287 $hours = '0';
288 }
289 if ( $ampm == 'pm' && $hours < 12 ) {
290 // convert to 24 hour format
291 $hours = $hours + 12;
292 }
293 $minutes = ( $hours * 60 ) + $minutes;
294 if ( $as_end_of_day && ! $minutes ) {
295 // midnight entered as a finish time means the end of the day, not its start
296 $minutes = 24 * 60;
297 }
298
299 return $minutes;
300 }
301
302 public static function am_or_pm( $minutes ) {
303 if ( self::is_army_clock() ) {
304 return '';
305 }
306
307 // end of the day is midnight of the same day, not noon
308 return ( $minutes < 720 || $minutes == 1440 ) ? 'am' : 'pm';
309 }
310
311 public static function minutes_to_hours( $time ) {
312 if ( $time ) {
313 $hours = floor( $time / 60 );
314 if ( ! self::is_army_clock() && $hours > 12 ) {
315 $hours = $hours - 12;
316 }
317 if ( ! self::is_army_clock() && ! $hours ) {
318 $hours = 12;
319 }
320
321 return $hours;
322 } else {
323 // if am/pm - we don't show 0, we show 12
324 return ( self::is_army_clock() ) ? 0 : 12;
325 }
326 }
327
328
329 public static function minutes_to_army_hours_and_minutes( $time_in_minutes ) {
330 if ( is_null( $time_in_minutes ) || $time_in_minutes === '' ) {
331 return __( 'n/a', 'latepoint' );
332 }
333 $hours = floor( $time_in_minutes / 60 );
334 $minutes = ( $time_in_minutes % 60 );
335
336 return sprintf( '%02d:%02d', $hours, $minutes );
337 }
338
339 public static function minutes_to_hours_and_minutes( $minutes, $format = '%02d:%02d', $add_ampm = true, $hide_if_zero_minutes = false ) {
340 if ( is_null( $minutes ) ) {
341 return 'n/a';
342 }
343 if ( ! $format ) {
344 $format = '%02d:%02d';
345 }
346
347 if ( $minutes === '' ) {
348 return;
349 }
350 $ampm = ( $add_ampm ) ? self::am_or_pm( $minutes ) : '';
351 $hours = self::minutes_to_hours( $minutes );
352 $minutes = ( $minutes % 60 );
353 if ( $hide_if_zero_minutes && ! $minutes ) {
354 return $hours . ' ' . $ampm;
355 } else {
356 return sprintf( $format, $hours, $minutes ) . $ampm;
357 }
358 }
359
360
361 public static function timezones_options_list_styled( $selected_zone, $locale = null ) {
362 static $mo_loaded = false, $locale_loaded = null;
363
364 $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific' );
365
366 // Load translations for continents and cities.
367 if ( ! $mo_loaded || $locale !== $locale_loaded ) {
368 $locale_loaded = $locale ? $locale : get_locale();
369 $mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
370 unload_textdomain( 'continents-cities' );
371 load_textdomain( 'continents-cities', $mofile );
372 $mo_loaded = true;
373 }
374
375 $time_format = self::get_time_format();
376
377 $zonen = array();
378 foreach ( timezone_identifiers_list() as $zone ) {
379 $zone = explode( '/', $zone );
380 if ( ! in_array( $zone[0], $continents ) ) {
381 continue;
382 }
383
384 // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
385 $exists = array(
386 0 => ( isset( $zone[0] ) && $zone[0] ),
387 1 => ( isset( $zone[1] ) && $zone[1] ),
388 2 => ( isset( $zone[2] ) && $zone[2] ),
389 );
390 $exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );
391 $exists[4] = ( $exists[1] && $exists[3] );
392 $exists[5] = ( $exists[2] && $exists[3] );
393
394 // phpcs:disable WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
395 $zonen[] = array(
396 'continent' => ( $exists[0] ? $zone[0] : '' ),
397 'city' => ( $exists[1] ? $zone[1] : '' ),
398 'subcity' => ( $exists[2] ? $zone[2] : '' ),
399 't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
400 't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
401 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ),
402 );
403 // phpcs:enable
404 }
405 usort( $zonen, '_wp_timezone_choice_usort_callback' );
406
407 $structure = array();
408
409 foreach ( $zonen as $key => $zone ) {
410 // Build value in an array to join later
411 $value = array( $zone['continent'] );
412
413 if ( empty( $zone['city'] ) ) {
414 // It's at the continent level (generally won't happen)
415 $display = $zone['t_continent'];
416 } else {
417 // It's inside a continent group
418
419 // Continent optgroup
420 if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
421 $label = $zone['t_continent'];
422 $structure[] = '<div class="os-timezone-group"><div class="os-timezone-group-header">' . esc_html( $label ) . '</div>';
423 }
424
425 // Add the city to the value
426 $value[] = $zone['city'];
427
428 $display = $zone['t_city'];
429 if ( ! empty( $zone['subcity'] ) ) {
430 // Add the subcity to the value
431 $value[] = $zone['subcity'];
432 $display .= ' - ' . $zone['t_subcity'];
433 }
434 }
435
436 // Build the value
437 $value = join( '/', $value );
438 $selected = '';
439 if ( $value === $selected_zone ) {
440 $selected = 'selected';
441 }
442 try {
443 $local_time = new OsWpDateTime( 'now', new DateTimeZone( $value ) );
444 $local_time_value = $local_time->format( $time_format );
445 } catch ( Exception $e ) {
446 $local_time_value = '';
447 }
448 $structure[] = '<div class="os-timezone-selector-option ' . $selected . '" data-value="' . esc_attr( $value ) . '"><div>' . esc_html( $display ) . '</div><div class="os-timezone-selector-option-local-time">' . $local_time_value . '</div></div>';
449
450 // Close continent optgroup
451 if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
452 $structure[] = '</div>';
453 }
454 }
455
456 // Do UTC
457 $structure[] = '<div class="os-timezone-group"><div class="os-timezone-group-header">' . esc_attr__( 'UTC', 'latepoint' ) . '</div>';
458 $selected = '';
459 if ( 'UTC' === $selected_zone ) {
460 $selected = 'selected';
461 }
462 $structure[] = '<div class="os-timezone-selector-option ' . $selected . ' data-value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC', 'latepoint' ) . '</div>';
463 $structure[] = '</div>';
464
465 return join( "\n", $structure );
466 }
467
468 public static function timezones_options_list( $selected_zone, $locale = null ) {
469 static $mo_loaded = false, $locale_loaded = null;
470
471 $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific' );
472
473 // Load translations for continents and cities.
474 if ( ! $mo_loaded || $locale !== $locale_loaded ) {
475 $locale_loaded = $locale ? $locale : get_locale();
476 $mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
477 unload_textdomain( 'continents-cities' );
478 load_textdomain( 'continents-cities', $mofile );
479 $mo_loaded = true;
480 }
481
482 $zonen = array();
483 foreach ( timezone_identifiers_list() as $zone ) {
484 $zone = explode( '/', $zone );
485 if ( ! in_array( $zone[0], $continents ) ) {
486 continue;
487 }
488
489 // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
490 $exists = array(
491 0 => ( isset( $zone[0] ) && $zone[0] ),
492 1 => ( isset( $zone[1] ) && $zone[1] ),
493 2 => ( isset( $zone[2] ) && $zone[2] ),
494 );
495 $exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );
496 $exists[4] = ( $exists[1] && $exists[3] );
497 $exists[5] = ( $exists[2] && $exists[3] );
498
499 // phpcs:disable WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
500 $zonen[] = array(
501 'continent' => ( $exists[0] ? $zone[0] : '' ),
502 'city' => ( $exists[1] ? $zone[1] : '' ),
503 'subcity' => ( $exists[2] ? $zone[2] : '' ),
504 't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
505 't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
506 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ),
507 );
508 // phpcs:enable
509 }
510 usort( $zonen, '_wp_timezone_choice_usort_callback' );
511
512 $structure = array();
513
514 if ( empty( $selected_zone ) ) {
515 $structure[] = '<option selected="selected" value="">' . __( 'Select a city', 'latepoint' ) . '</option>';
516 }
517
518 foreach ( $zonen as $key => $zone ) {
519 // Build value in an array to join later
520 $value = array( $zone['continent'] );
521
522 if ( empty( $zone['city'] ) ) {
523 // It's at the continent level (generally won't happen)
524 $display = $zone['t_continent'];
525 } else {
526 // It's inside a continent group
527
528 // Continent optgroup
529 if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
530 $label = $zone['t_continent'];
531 $structure[] = '<optgroup label="' . esc_attr( $label ) . '">';
532 }
533
534 // Add the city to the value
535 $value[] = $zone['city'];
536
537 $display = $zone['t_city'];
538 if ( ! empty( $zone['subcity'] ) ) {
539 // Add the subcity to the value
540 $value[] = $zone['subcity'];
541 $display .= ' - ' . $zone['t_subcity'];
542 }
543 }
544
545 // Build the value
546 $value = join( '/', $value );
547 $selected = '';
548 if ( $value === $selected_zone ) {
549 $selected = 'selected="selected" ';
550 }
551 $structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $label ) . ', ' . esc_html( $display ) . '</option>';
552
553 // Close continent optgroup
554 if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
555 $structure[] = '</optgroup>';
556 }
557 }
558
559 // Do UTC
560 $structure[] = '<optgroup label="' . esc_attr__( 'UTC', 'latepoint' ) . '">';
561 $selected = '';
562 if ( 'UTC' === $selected_zone ) {
563 $selected = 'selected="selected" ';
564 }
565 $structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC', 'latepoint' ) . '</option>';
566 $structure[] = '</optgroup>';
567
568 return join( "\n", $structure );
569 }
570
571 public static function format_to_nice_time( $datetime ): string {
572 if ( $datetime instanceof DateTime ) {
573 $format = self::is_army_clock() ? 'H:i' : 'g:ia';
574
575 return $datetime->format( $format );
576 } else {
577 return 'n/a';
578 }
579 }
580
581 public static function format_to_nice_date( $datetime, $hide_year_if_current = false ): string {
582 if ( $datetime instanceof DateTime ) {
583 if ( $hide_year_if_current && ( $datetime->format( 'Y' ) == self::today_date( 'Y' ) ) ) {
584 $format = OsSettingsHelper::get_readable_date_format( true );
585 } else {
586 $format = OsSettingsHelper::get_readable_date_format();
587 }
588
589 return OsUtilHelper::translate_months( $datetime->format( $format ) );
590 } else {
591 return 'n/a';
592 }
593 }
594 }
595