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