[Back] <?php
class OsTimeHelper {
private static $timezone = false;
public static function get_db_weekday_by_number( $number ) {
$weekdays = [ 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su' ];
return $weekdays[ $number - 1 ];
}
public static function is_valid_date( $date_string ) {
if(empty($date_string)) return false;
return (bool) strtotime( $date_string );
}
public static function reformat_date_string( $date_string, $from_format, $to_format ) {
$start_date_obj = OsWpDateTime::os_createFromFormat( $from_format, $date_string );
return $start_date_obj->format( $to_format );
}
public static function nice_date( $date ) {
if ( $date == OsTimeHelper::today_date( 'Y-m-d' ) ) {
$nice_date = __( 'Today', 'latepoint' );
} else {
$nice_date = self::get_nice_date_with_optional_year( $date, true );
}
return $nice_date;
}
public static function date_from_db( $date_string, $format = false, string $output_timezone_name = 'UTC' ) {
$timezone = new DateTimeZone( 'UTC' );
$date_obj = OsWpDateTime::os_createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $date_string, $timezone );
if(empty($date_obj)) $date_obj = self::now_datetime_object();
$date_obj->setTimezone( new DateTimeZone( $output_timezone_name ) );
if ( $format ) {
return $date_obj->format( $format );
}
return $date_obj;
}
public static function today_date( $date_format = 'Y-m-d' ) {
$today = new OsWpDateTime( 'today' );
return $today->format( $date_format );
}
public static function now_datetime_in_format( $date_format = LATEPOINT_DATETIME_DB_FORMAT, string $timezone = 'UTC' ) {
$now = self::now_datetime_object();
$now->setTimezone( new DateTimeZone( "UTC" ) );
return $now->format( $date_format );
}
public static function now_datetime_utc() {
$now = self::now_datetime_object();
$now->setTimezone( new DateTimeZone( "UTC" ) );
return $now;
}
public static function time_left_to_datetime( string $datetime, DateTimeZone $timezone ) {
$now_datetime = new OsWpDateTime( 'now', $timezone );
$event_datetime = OsWpDateTime::createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $datetime, $timezone );
$css_class = 'left-days';
$before = ( $now_datetime < $event_datetime ) ? __( 'in', 'latepoint' ) . ' ' : '';
$ago = ( $now_datetime > $event_datetime ) ? ' ' . __( 'ago', 'latepoint' ) : '';
$ago_class = empty( $ago ) ? '' : 'time-past';
if ( $event_datetime ) {
$diff = $now_datetime->diff( $event_datetime );
if ( $diff->d > 0 ) {
$left = $before . $diff->format( '%a ' . __( 'days', 'latepoint' ) ) . $ago;
} else {
if ( $diff->h > 0 ) {
$css_class = 'left-hours';
$left = $before . $diff->format( '%h ' . __( 'hours', 'latepoint' ) ) . $ago;
} else {
$css_class = 'left-minutes';
$left = $before . $diff->format( '%i ' . __( 'minutes', 'latepoint' ) ) . $ago;
}
}
} else {
$left = 'n/a';
}
return '<span class="time-left ' . esc_attr( $css_class ) . ' ' . esc_attr( $ago_class ) . '">' . esc_html( $left ) . '</span>';
}
public static function now_datetime_utc_in_db_format() {
return OsWpDateTime::datetime_in_utc( new OsWpDateTime( 'now' ), LATEPOINT_DATETIME_DB_FORMAT );
}
public static function custom_datetime_utc_in_db_format( string $time = 'now' ): string {
return OsWpDateTime::datetime_in_utc( new OsWpDateTime( $time ), LATEPOINT_DATETIME_DB_FORMAT );
}
public static function now_datetime_in_db_format() {
return self::now_datetime_in_format( LATEPOINT_DATETIME_DB_FORMAT );
}
public static function now_datetime_object() {
return new OsWpDateTime( 'now' );
}
public static function get_time_system() {
return OsSettingsHelper::get_time_system();
}
public static function get_time_format() {
return self::is_army_clock() ? 'H:i' : 'g:ia';
}
public static function is_army_clock() {
return ( self::get_time_system() == 24 );
}
public static function get_time_systems_list_for_select() {
return array(
array( 'value' => '12', 'label' => __( '12-hour clock', 'latepoint' ) ),
array( 'value' => '24', 'label' => __( '24-hour clock', 'latepoint' ) )
);
}
public static function get_date_formats_list_for_select() {
return array(
array( 'value' => 'm/d/Y', 'label' => __( 'MM/DD/YYYY', 'latepoint' ) ),
array( 'value' => 'm.d.Y', 'label' => __( 'MM.DD.YYYY', 'latepoint' ) ),
array( 'value' => 'd/m/Y', 'label' => __( 'DD/MM/YYYY', 'latepoint' ) ),
array( 'value' => 'd.m.Y', 'label' => __( 'DD.MM.YYYY', 'latepoint' ) ),
array( 'value' => 'Y-m-d', 'label' => __( 'YYYY-MM-DD', 'latepoint' ) )
);
}
public static function get_time_systems_list() {
return array( '12' => __( '12-hour clock', 'latepoint' ), '24' => __( '24-hour clock', 'latepoint' ) );
}
public static function format_date_with_locale( string $format, DateTime $date_obj ): string {
return OsUtilHelper::translate_months( $date_obj->format( $format ) );
}
public static function get_nice_date_with_optional_year( $date, $show_year_if_not_current = true, $short_month = false ) {
$d = OsWpDateTime::os_createFromFormat( "Y-m-d", $date );
if ( ! $d ) {
return $date;
}
if ( ! $show_year_if_not_current || ( $d->format( 'Y' ) == OsTimeHelper::today_date( 'Y' ) ) ) {
return OsUtilHelper::translate_months( $d->format( OsSettingsHelper::get_readable_date_format( true, $short_month ) ) );
} else {
return OsUtilHelper::translate_months( $d->format( OsSettingsHelper::get_readable_date_format( false, $short_month) ) );
}
}
public static function get_readable_date( DateTime $date, string $output_timezone_name = '' ): string {
if ( empty( $output_timezone_name ) ) {
$output_timezone_name = self::get_wp_timezone_name();
}
$date->setTimezone( new DateTimeZone( $output_timezone_name ) );
return self::format_date_with_locale( OsSettingsHelper::get_readable_date_format(), $date );
}
public static function get_readable_date_from_string( string $date, string $input_timezone_name = '', string $output_timezone_name = '' ): string {
if ( empty( $input_timezone_name ) ) {
$input_timezone_name = 'UTC';
}
if ( empty( $output_timezone_name ) ) {
$output_timezone_name = self::get_wp_timezone_name();
}
$date_obj = new OsWpDateTime( $date, new DateTimeZone( $input_timezone_name ) );
return self::get_readable_date( $date_obj, $output_timezone_name );
}
public static function get_wp_timezone() {
if ( self::$timezone ) {
return self::$timezone;
}
try{
$timezone_string = get_option( 'timezone_string' );
if ( ! empty( $timezone_string ) ) {
return new DateTimeZone( $timezone_string );
}
$offset = get_option( 'gmt_offset' );
$hours = (int) $offset;
$minutes = abs( ( $offset - (int) $offset ) * 60 );
$offset = sprintf( '%+03d:%02d', $hours, $minutes );
self::$timezone = new DateTimeZone( $offset );
}catch(Exception $e){
return new DateTimeZone('UTC');
}
return self::$timezone;
}
public static function get_wp_timezone_name() {
$timezone_obj = self::get_wp_timezone();
if ( $timezone_obj ) {
return $timezone_obj->getName();
} else {
return 'America/New_York';
}
}
public static function get_timezone_from_session() {
try {
$timezone = new DateTimeZone( self::get_timezone_name_from_session() );
} catch ( Exception $e ) {
$timezone = new DateTimeZone( self::get_wp_timezone_name() );
}
return $timezone;
}
public static function get_timezone_name_from_session() {
$timezone_name = self::get_wp_timezone_name();
$timezone_name = apply_filters( 'latepoint_timezone_name_from_session', $timezone_name );
return $timezone_name;
}
public static function is_timezone_saved_in_session() {
return ( isset( $_COOKIE[ LATEPOINT_SELECTED_TIMEZONE_COOKIE ] ) && ! empty( $_COOKIE[ LATEPOINT_SELECTED_TIMEZONE_COOKIE ] ) );
}
public static function set_timezone_name_in_cookie( $timezone_name ) {
OsSessionsHelper::setcookie( LATEPOINT_SELECTED_TIMEZONE_COOKIE, $timezone_name );
$_COOKIE[ LATEPOINT_SELECTED_TIMEZONE_COOKIE ] = $timezone_name;
}
public static function convert_datetime_to_minutes( DateTime $datetime ) {
return $datetime->format( 'i' ) + ( $datetime->format( 'G' ) * 60 );
}
public static function get_current_minutes( ) {
$now = new OsWpDateTime( 'now' );
return $now->format( 'i' ) + ( $now->format( 'G' ) * 60 );
}
public static function convert_time_to_minutes( $time, $ampm = false ) {
if ( strpos( $time, ':' ) === false ) {
return 0;
}
list( $hours, $minutes ) = explode( ':', $time );
if ( $hours == '12' && $ampm == 'am' ) {
// midnight
$hours = '0';
}
if ( $ampm == 'pm' && $hours < 12 ) {
// convert to 24 hour format
$hours = $hours + 12;
}
$minutes = ( $hours * 60 ) + $minutes;
return $minutes;
}
public static function am_or_pm( $minutes ) {
if ( self::is_army_clock() ) {
return '';
}
return ( $minutes < 720 ) ? 'am' : 'pm';
}
public static function minutes_to_hours( $time ) {
if ( $time ) {
$hours = floor( $time / 60 );
if ( ! self::is_army_clock() && $hours > 12 ) {
$hours = $hours - 12;
}
if ( ! self::is_army_clock() && ! $hours ) {
$hours = 12;
}
return $hours;
} else {
// if am/pm - we don't show 0, we show 12
return ( self::is_army_clock() ) ? 0 : 12;
}
}
public static function minutes_to_army_hours_and_minutes( $time_in_minutes ) {
if ( is_null( $time_in_minutes ) || $time_in_minutes === '' ) {
return __( 'n/a', 'latepoint' );
}
$hours = floor( $time_in_minutes / 60 );
$minutes = ( $time_in_minutes % 60 );
return sprintf( '%02d:%02d', $hours, $minutes );
}
public static function minutes_to_hours_and_minutes( $minutes, $format = '%02d:%02d', $add_ampm = true, $hide_if_zero_minutes = false ) {
if ( is_null( $minutes ) ) {
return 'n/a';
}
if ( ! $format ) {
$format = '%02d:%02d';
}
if ( $minutes === '' ) {
return;
}
$ampm = ( $add_ampm ) ? self::am_or_pm( $minutes ) : '';
$hours = self::minutes_to_hours( $minutes );
$minutes = ( $minutes % 60 );
if ( $hide_if_zero_minutes && ! $minutes ) {
return $hours . ' ' . $ampm;
} else {
return sprintf( $format, $hours, $minutes ) . $ampm;
}
}
public static function timezones_options_list_styled( $selected_zone, $locale = null ) {
static $mo_loaded = false, $locale_loaded = null;
$continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific' );
// Load translations for continents and cities.
if ( ! $mo_loaded || $locale !== $locale_loaded ) {
$locale_loaded = $locale ? $locale : get_locale();
$mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
unload_textdomain( 'continents-cities' );
load_textdomain( 'continents-cities', $mofile );
$mo_loaded = true;
}
$time_format = self::get_time_format();
$zonen = array();
foreach ( timezone_identifiers_list() as $zone ) {
$zone = explode( '/', $zone );
if ( ! in_array( $zone[0], $continents ) ) {
continue;
}
// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
$exists = array(
0 => ( isset( $zone[0] ) && $zone[0] ),
1 => ( isset( $zone[1] ) && $zone[1] ),
2 => ( isset( $zone[2] ) && $zone[2] ),
);
$exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );
$exists[4] = ( $exists[1] && $exists[3] );
$exists[5] = ( $exists[2] && $exists[3] );
// phpcs:disable WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
$zonen[] = array(
'continent' => ( $exists[0] ? $zone[0] : '' ),
'city' => ( $exists[1] ? $zone[1] : '' ),
'subcity' => ( $exists[2] ? $zone[2] : '' ),
't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ),
);
// phpcs:enable
}
usort( $zonen, '_wp_timezone_choice_usort_callback' );
$structure = array();
foreach ( $zonen as $key => $zone ) {
// Build value in an array to join later
$value = array( $zone['continent'] );
if ( empty( $zone['city'] ) ) {
// It's at the continent level (generally won't happen)
$display = $zone['t_continent'];
} else {
// It's inside a continent group
// Continent optgroup
if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
$label = $zone['t_continent'];
$structure[] = '<div class="os-timezone-group"><div class="os-timezone-group-header">'.esc_html( $label ).'</div>';
}
// Add the city to the value
$value[] = $zone['city'];
$display = $zone['t_city'];
if ( ! empty( $zone['subcity'] ) ) {
// Add the subcity to the value
$value[] = $zone['subcity'];
$display .= ' - ' . $zone['t_subcity'];
}
}
// Build the value
$value = join( '/', $value );
$selected = '';
if ( $value === $selected_zone ) {
$selected = 'selected';
}
try {
$local_time = new OsWpDateTime('now', new DateTimeZone($value));
$local_time_value = $local_time->format($time_format);
}catch(Exception $e){
$local_time_value = '';
}
$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>';
// Close continent optgroup
if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
$structure[] = '</div>';
}
}
// Do UTC
$structure[] = '<div class="os-timezone-group"><div class="os-timezone-group-header">'.esc_attr__( 'UTC', 'latepoint' ).'</div>';
$selected = '';
if ( 'UTC' === $selected_zone ) {
$selected = 'selected';
}
$structure[] = '<div class="os-timezone-selector-option ' . $selected . ' data-value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC', 'latepoint' ) . '</div>';
$structure[] = '</div>';
return join( "\n", $structure );
}
public static function timezones_options_list( $selected_zone, $locale = null ) {
static $mo_loaded = false, $locale_loaded = null;
$continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific' );
// Load translations for continents and cities.
if ( ! $mo_loaded || $locale !== $locale_loaded ) {
$locale_loaded = $locale ? $locale : get_locale();
$mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
unload_textdomain( 'continents-cities' );
load_textdomain( 'continents-cities', $mofile );
$mo_loaded = true;
}
$zonen = array();
foreach ( timezone_identifiers_list() as $zone ) {
$zone = explode( '/', $zone );
if ( ! in_array( $zone[0], $continents ) ) {
continue;
}
// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
$exists = array(
0 => ( isset( $zone[0] ) && $zone[0] ),
1 => ( isset( $zone[1] ) && $zone[1] ),
2 => ( isset( $zone[2] ) && $zone[2] ),
);
$exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );
$exists[4] = ( $exists[1] && $exists[3] );
$exists[5] = ( $exists[2] && $exists[3] );
// phpcs:disable WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
$zonen[] = array(
'continent' => ( $exists[0] ? $zone[0] : '' ),
'city' => ( $exists[1] ? $zone[1] : '' ),
'subcity' => ( $exists[2] ? $zone[2] : '' ),
't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ),
);
// phpcs:enable
}
usort( $zonen, '_wp_timezone_choice_usort_callback' );
$structure = array();
if ( empty( $selected_zone ) ) {
$structure[] = '<option selected="selected" value="">' . __( 'Select a city', 'latepoint' ) . '</option>';
}
foreach ( $zonen as $key => $zone ) {
// Build value in an array to join later
$value = array( $zone['continent'] );
if ( empty( $zone['city'] ) ) {
// It's at the continent level (generally won't happen)
$display = $zone['t_continent'];
} else {
// It's inside a continent group
// Continent optgroup
if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
$label = $zone['t_continent'];
$structure[] = '<optgroup label="' . esc_attr( $label ) . '">';
}
// Add the city to the value
$value[] = $zone['city'];
$display = $zone['t_city'];
if ( ! empty( $zone['subcity'] ) ) {
// Add the subcity to the value
$value[] = $zone['subcity'];
$display .= ' - ' . $zone['t_subcity'];
}
}
// Build the value
$value = join( '/', $value );
$selected = '';
if ( $value === $selected_zone ) {
$selected = 'selected="selected" ';
}
$structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $label ) . ', ' . esc_html( $display ) . '</option>';
// Close continent optgroup
if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
$structure[] = '</optgroup>';
}
}
// Do UTC
$structure[] = '<optgroup label="' . esc_attr__( 'UTC', 'latepoint' ) . '">';
$selected = '';
if ( 'UTC' === $selected_zone ) {
$selected = 'selected="selected" ';
}
$structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC', 'latepoint' ) . '</option>';
$structure[] = '</optgroup>';
return join( "\n", $structure );
}
public static function format_to_nice_time( $datetime ): string {
if ( $datetime instanceof DateTime ) {
$format = self::is_army_clock() ? 'H:i' : 'g:ia';
return $datetime->format( $format );
} else {
return 'n/a';
}
}
public static function format_to_nice_date( $datetime, $hide_year_if_current = false ): string {
if ( $datetime instanceof DateTime ) {
if ( $hide_year_if_current && ( $datetime->format( 'Y' ) == self::today_date( 'Y' ) ) ) {
$format = OsSettingsHelper::get_readable_date_format( true );
} else {
$format = OsSettingsHelper::get_readable_date_format();
}
return OsUtilHelper::translate_months( $datetime->format( $format ) );
} else {
return 'n/a';
}
}
}