skip to Main Content

For example, when a country changes time, there are 2 possibilities:

1.- If it changes to an earlier time, for example, at 3 Am in Central Europe, the last Sunday in October at 3 Am becomes 2 Am, therefore, if there is a date that is 02:30 am, 2 Dates and Hours are possible, one before the Change, and one after the Change.

2.- In Central Europe the Last Sunday of March at 2 Am becomes 3 Am, therefore if someone puts a date/time like this: 03-31-2024 at 02:30 Am, that LOCAL time It is theoretically impossible, since between 2 and 3 there is no possibility of Local Time.

Is there any code that warns about this?

For example, I have this code in PHP, I pass it a time zone, and it does not warn me that this time, 02:30:00Am, is not officially possible, and I would like it to warn me about these conflicting hours:

https://timezonespro.com/php/test4.php?tzname=Europe/Madrid

<?php
$timezoneStr = $_GET["tzname"];
echo "TimeZone = " . $timezoneStr;


$datetime = "2024-03-31 02:30:00";
print '<br>';
echo "Local = " . $datetime;
$given = new DateTime($datetime, new DateTimeZone($timezoneStr));
$given->setTimezone(new DateTimeZone("UTC"));
$output = $given->format("Y-m-d H:i:s"); 
print '<br>';
echo "UTC = " . $output;

$ano = substr($output, 0, 4);
$mes = substr($output, 5, 2);
$dia = substr($output, 8, 2);
$hor = substr($output, 11, 2);
$min = substr($output, 14, 2);
$sec = substr($output, 17, 2);
print '<br>';
echo "Year = " . $ano;
print '<br>';
echo "Month = " . $mes;
print '<br>';
echo "Day = " . $dia;
print '<br>';
echo "Hours = " . $hor;
print '<br>';
echo "Minutes = " . $min;
print '<br>';
echo "Seconds = " . $sec;

$meses = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"];
$mesStr = $meses[intval($mes) - 1];

print '<br>';
echo $dia . "-" . $mesStr . "-" . $ano . " a las " . $hor . ":" . $min . ":" . $sec;

$secondsInTime = intval($hor * 3600) + intval($min * 60) + intval($sec);
$secondsInTimeDec = $secondsInTime / 86400;

$jd = GregorianToJD($mes, $dia, $ano);
$jdDec = intval($jd) + $secondsInTimeDec;
print '<br>';
echo "JulianDay = " . $jdDec;
?>

A code that warns of conflicting times in time changes in a country.

2

Answers


  1. Chosen as BEST ANSWER

    A little error in my code in the JulianDay, correction:

        <?php
    $timezoneStr = $_GET["tzname"];
    echo "TimeZone = " . $timezoneStr;
    
    
    $datetime = "2024-03-31 02:30:00";
    print '<br>';
    echo "Local = " . $datetime;
    //$given = new DateTime($datetime, new DateTimeZone("Europe/Madrid"));
    $given = new DateTime($datetime, new DateTimeZone($timezoneStr));
    $given->setTimezone(new DateTimeZone("UTC"));
    $output = $given->format("Y-m-d H:i:s"); 
    print '<br>';
    echo "UTC = " . $output;
    
    $ano = substr($output, 0, 4);
    $mes = substr($output, 5, 2);
    $dia = substr($output, 8, 2);
    $hor = substr($output, 11, 2);
    $min = substr($output, 14, 2);
    $sec = substr($output, 17, 2);
    print '<br>';
    echo "Year = " . $ano;
    print '<br>';
    echo "Month = " . $mes;
    print '<br>';
    echo "Day = " . $dia;
    print '<br>';
    echo "Hours = " . $hor;
    print '<br>';
    echo "Minutes = " . $min;
    print '<br>';
    echo "Seconds = " . $sec;
    
    $meses = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"];
    $mesStr = $meses[intval($mes) - 1];
    
    print '<br>';
    echo $dia . "-" . $mesStr . "-" . $ano . " a las " . $hor . ":" . $min . ":" . $sec;
    
    if (intval($hor) >= 12)
        $secondsInTime = intval($hor * 3600) + intval($min * 60) + intval($sec);
    else
        $secondsInTime = intval($hor * 3600) + intval(12 * 3600) + intval($min * 60) + intval($sec);
    $secondsInTimeDec = $secondsInTime / 86400;
    
    $jd = GregorianToJD($mes, $dia, $ano);
    $jdDec = intval($jd) + $secondsInTimeDec;
    print '<br>';
    echo "JulianDay = " . $jdDec;
    ?>
    

    The correction is this part:

    if (intval($hor) >= 12)
        $secondsInTime = intval($hor * 3600) + intval($min * 60) + intval($sec);
    else
        $secondsInTime = intval($hor * 3600) + intval(12 * 3600) + intval($min * 60) + intval($sec);
    

    And well, it is possible to list all the time changes, and search for the dates that have these problems, but I was looking to see if there was someone who had already done it.

    For example, with this code you can list all changes in the "Europe/Madrid" TimeZone:

    All TimeZone changes for Europe/Madrid

    Code:

    <?php
    $timezoneStr = $_GET["tzname"];
    print_r('timezone = ' . $timezoneStr . '@');
    print '<br>';
    $timezone_identifiers = DateTimeZone::listIdentifiers();
    for ($i=0; $i < 1005; $i++)
        {
        if ($timezone_identifiers[$i] == "")
            break;
        else if ($timezone_identifiers[$i] == $timezoneStr)
            {
            $timezone = new DateTimeZone($timezone_identifiers[$i]);
            $transitions = $timezone->getTransitions();
            for ($k=0; $k<500; $k++)
                {
                if ($transitions[$k] == "")
                    break;
                $UnixTimeStamp = $transitions[$k][ts];
                $julianDay = ($UnixTimeStamp / 86400) + 2440587.5;
                print_r('UnixTimeStamp = ' . $UnixTimeStamp . ' | ');
                print_r('JulianDay = ' . $julianDay . ' | ');
                print_r('DateTime (Time) = ' . $transitions[$k][time] . ' | ');
                print_r('Seconds Difference to GMT (Offset) = ' . $transitions[$k][offset] . ' | ');
                print_r('Is Dst (IsDst) = ' . $transitions[$k][isdst] . ' | ');
                print_r('TimeZone Abreviation (Abbr) = ' . $transitions[$k][abbr] . '@');
                Print '<br>';
                }
            return;
            }
        }
    return;
    

    ?>

    I'm looking to see if there was already someone who had done it. Well, it should be something that has been done for a long time, these types of problems with time changes are always there.

    And I think that php should already have it corrected, and when there are officially impossible hours, notify, and when there are possible double hours, also notify.


  2. DateTime already handles such cases:

    $dt = new DateTime('2024-03-31 02:30:00', new DateTimeZone('Europe/Madrid'));
    echo $dt->format('Y-m-d H:i:s'); // prints: 2024-03-31 03:30:00
    

    Notice how the "impossible" 02:30 became 03:30 automatically.

    There is no warning, but you can always compare the formatted Y-m-d H:i:s strings of the date with and without timezone info, if you need to check if that happened.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search