DEV Community

David Carr
David Carr

Posted on • Originally published at dcblog.dev on

Extracting a time into select menus with PHP

When storing time in a database, often I'll store this in a time format such as 14:25:00 When populating this in a form I'll either use a time picker or use a plain select menu a separate menu for each element.

That begs the question how do you separate the time into seperate elements?

Making use of explode can work. Exploding where there a : so:

$parts = explode(':', '14:25:00');
Enter fullscreen mode Exit fullscreen mode

This would result in an array:

[
    "14",
    "25",
    "00",
]
Enter fullscreen mode Exit fullscreen mode

To use an element you can refer to its index for example $parts[0] would contain 14

Using them by their index is fine to do but kinda messy.

I prefer to give each element a name using the list function

list($hours, $minutes, $seconds) = explode(':', '14:25:00');
Enter fullscreen mode Exit fullscreen mode

When using list() passing an array to it will allow you to name each index of the array in the order listed.

Putting this into practice I like to define the null versions before using list to ensure the variables will exist.

$estimatedTime = 14:25:00;

$estimatedHour = null;
$estimatedMinute = null;
$estimatedSeconds = null;

list($estimatedHour, $estimatedMinute, $estimatedSeconds) = explode(':', $estimatedTime);
Enter fullscreen mode Exit fullscreen mode

Now we have the variables that can be used in select menus:

note I'm using Blade syntax here for readability.

<select name="estimatedTime_hour">
    <option value="0">Hours</option>
    @foreach(range(0,23) as $hour)
        <option value="{{ $hour }}" {{ old('estimatedTime_hour', $estimatedHour) == $hour ? 'selected=selected' : '' }}>{{ $hour }}</option>
    @endforeach
</select>

<select name="estimatedTime_minute">
    <option value="0">Minutes</option>
    @foreach(range(0,59) as $minute)
        <option value="{{ $minute }}" {{ old('estimatedTime_minute', $estimatedMinute) == $hour ? 'selected=selected' : '' }}>{{ $minute }}</option>
    @endforeach
</select>

<select name="estimatedTime_second">
    <option value="0">Seconds</option>
    @foreach(range(0,59) as $second)
        <option value="{{ $second }}" {{ old('estimatedTime_second', $estimatedSeconds) == $hour ? 'selected=selected' : '' }}>{{ $second }}</option>
    @endforeach
</select>
Enter fullscreen mode Exit fullscreen mode

For each time segment I have a separate select menu. Each selection uses a range function to generate an array of items. For example, range(0,23) will return an array containing all numbers between 0 and 23.

To ensure the time segment selects the correct array index inside the loop compare the the row against the time segment:

$estimatedSeconds == $hour
Enter fullscreen mode Exit fullscreen mode

When they match then print selected=selected to ensure the menu selects that time segment.

This is a simple but powerful pattern.

Top comments (0)