2

Just wondering how I would select the closest variable. I have a set list of military times, i.e: 0030 0100 0130 0200 etc...

All in half hour increments. How would I select the closest time to now. For example. User clicks on the button, php gets the time it is now, and selects the closest time variable. So if it's 0144, it would pick 0130. and if it's 0146, it would pick 0200.

David
  • 2,094
  • 3
  • 30
  • 47
  • 2
    What have you tried? This sounds like a simple case of rounding numbers to me! – adeneo Nov 06 '12 at 23:08
  • 1
    Could you not just round the time? http://stackoverflow.com/questions/2480637/round-minute-down-to-nearest-quarter-hour – Petah Nov 06 '12 at 23:10

4 Answers4

3

Since you always store times at 30 minutes interval, subtract the last 2 digits (minutes) from the current time from 30.

For example: If current time is 0146,

  1. strip out 46 (minutes)
  2. Take absolute difference from 30
  3. If difference > 15, take the next available time slot for 0146 (which is 0200 here)
  4. If difference <= 15, take the previous available time before 0146 (which is 0130 here)

Hope this helps.

Ibu
  • 42,752
  • 13
  • 76
  • 103
Vaibhav Desai
  • 2,618
  • 1
  • 16
  • 16
  • How about some code to back this up, as it's not really an answer, but more of a "how to round a number" guide? – adeneo Nov 06 '12 at 23:10
0

For ease, in your calculations treat them as integers, ignoring the leading zeroes as they're not useful to your calculations.

You have 144 and you want to round down to 130, or 146, up to 200. Similarly 14 (0014) would go to 0 (0000) and 15 (0015) up to 30.

Simple if/thens would suffice to complete this.

A.M. D.
  • 928
  • 6
  • 10
0

I believe this should do it:

function military_time() {
    $hour = (int) date('G');
    $minute = (int) date('i');

    $rounded_minute = round($minute / 30);

    switch ($rounded_minute) {
        case 0:
            $minute = '00';
            break;
        case 1:
            $minute = '30';
            break;
        case 2:
            $minute = '00';
            $hour = (int) $hour + 1;
            break;
    }

    // 2400 should become 0000
    if ($hour > 23) $hour = 0;

    // leading zero
    if ($hour < 10) $hour = '0' . $hour;

    return $hour . $minute;
}

echo military_time();

Could probably be improved though.

Nic Wortel
  • 11,155
  • 6
  • 60
  • 79
0

You can try

$times = array("0030","0100","0130","0200");

echo "<pre>";
echo militaryTime($times, "0020"), PHP_EOL;
echo militaryTime($times, "0050"), PHP_EOL;
echo militaryTime($times, "0144"), PHP_EOL;
echo militaryTime($times, "0146"), PHP_EOL;
echo militaryTime($times, "0220"), PHP_EOL;

Output

0030
0100
0130
0200
0200

Function Used

function militaryTime($times, $selected) {
    if (empty($times))
        trigger_error("Empty array not supported ");
    $times[] = $selected;
    sort($times);
    $position = array_search($selected, $times, true);
    $current = DateTime::createFromFormat("Hi", $times[$position]);
    $previous = isset($times[$position - 1]) ? DateTime::createFromFormat("Hi", $times[$position - 1]) : null;
    $next = isset($times[$position + 1]) ? DateTime::createFromFormat("Hi", $times[$position + 1]) : null;

    if ($previous != null && $next == null) {
        return $previous->format("Hi");
    }
    if ($previous == null && $next != null) {
        return $next->format("Hi");
    }

    $closest = ($current->diff($previous)->format("%i") - $current->diff($next)->format("%i") <= 0) ? $previous : $next;
    return $closest->format("Hi");
}
Baba
  • 94,024
  • 28
  • 166
  • 217