Home > Software design >  PHP - determining midday using UTC time with timezone offset
PHP - determining midday using UTC time with timezone offset

Time:08-26

Given a time in UTC and the timezone offset, I want to establish a four hour window centred on Midday localtime.

This function has been in active use in a radio database and I now learn has been giving inconsistent results for over 15 years without anyone realizing it until now.

The problem is that it doesn't register the full four hour window when the timezone offset is between -10 and -12, or 10 and 12.

Here's my simplified PHP test code which produces the results described above:

<?php
function convertHtoHH($value) {
    // Takes hour as an integer and formats it as hh
    return
        ($value < 0 ? '-' : '')
        . substr('00', 0, 2 - strlen(abs($value)))
        . abs($value);
}

function isDaytime($hhmm, $timezone) {
    // Supposed to return 'true' if time is within two hours of noon local time
    return ($hhmm   24 >= ($timezone * -1)   34)
        && ($hhmm   24 <  ($timezone * -1)   38);
}
?>
<html>
<head>
    <title>Daytime Tester</title>
</head>
<body>
<h1>Daytime Tester</h1>
<table border='1' cellpadding='1' cellspacing='0'>
    <thead>
        <tr>
            <th rowspan='2'>&nbsp;<br>Local</th>
            <th colspan='24' style='text-align: center'>UTC</th>
        </tr>
        <tr>
<?php for ($u = 0; $u < 24; $u  ): ?>
    <th><?php echo convertHtoHH($u); ?></th>
<?php endfor; ?>
        </tr>
    </thead>
    <tbody>
<?php for ($l = -12; $l <= 12; $l  ): ?>
    <?php $local = convertHtoHH($l); ?>
        <tr>
            <th><?php echo $local; ?></th>
    <?php for ($u=0; $u<24; $u  ): ?>
        <?php $UTC = convertHtoHH($u); ?>
        <?php $DT = isDaytime($UTC, $l); ?>
            <td><?php echo ($DT ? 'Y' : ''); ?></td>
    <?php endfor; ?>
        </tr>
<?php endfor; ?>
        </tbody>
    </table>
</body>
</html>

When executed, the above code generates this test result set: Output, with missing values shown in red

Clearly the following function provides an incomplete result:

function isDaytime($hhmm, $timezone) {
    return ($hhmm   24 >= ($timezone * -1)   34)
        && ($hhmm   24 <  ($timezone * -1)   38);
}

Can anyone help me solve this conundrum?

CodePudding user response:

You can simplify isDaytime by using a modulus operator. By adding 24 and taking the modulus 24, we can guarantee that the range of $timeModulo is 0 - 24 and not negative or otherwise weird.

function isDaytime($hhmm, $timezone) {
    $timeModulo = ($hhmm   $timezone   24) % 24;
    return $timeModulo >= 10 && $timeModulo < 14;
}
  • Related