Convert 24 hour (military) time to 12 hour (am/pm) time in php

The need to convert time from 24 hour format to 12 hour format is a pretty common task in php applications involving a database. MySQL (and most databases for that matter) require time in 24 hour format while humans prefer to read their time in 12 hour format. I recently ran across a blog post demonstrating numerous custom functions to do the trick, all of which are overly complex. A quick google search confirmed that this is another one of those common programming problems that many PHP programmers have been over engineering a solution for when PHP’s core functions provide a simple and elegant solution. In other words, there’s a much better solution…

PHP provides two simple functions that when combined become a pretty powerful tool for manipulating dates and times. Those functions are date() which everybody seems to be familiar with and the apparently less familiar strtotime(). If you don’t know the strtotime() function, it’s time to get acquainted!

The strtotime() function takes just about any date/time description you can think of and does its best to convert that into a Unix timestamp. And when I say “does its best”, it’s best is pretty darn good. The function’s ability to decipher textual dates and times is almost sapient. For example pass it the string “tomorrow” and it will return the Unix timestamp for tomorrow’s date, no foolin!

print( strtotime("tomorrow") );

The real magic starts to happen when we remember all of the handy ways the date() function can manipulate dates and times when given a simple Unix timestamp to work with. Here’s tomorrows date again, easily made human readable.

print( date("m/d/Y", strtotime("tomorrow")) );

So how does all of this simplify converting time from 24 hour to 12 hour formats? The strtotime() function doesn’t just accept dates or abstract terms like “tomorrow”… it’s can also work with descriptions of time. And the function is full capable of deciphering MySQL time formats (which also happens to be 24 hour format).

print( date("g:i a", strtotime("13:30:30")) );

And the other way around, 12 hour time that needs to be converted to 24 hour for an insert into MySQL… just as easy.

print( date("H:i:s", strtotime("1:30 pm")) );

The only caveat, when you pass strtotime a string just representing the time, today is the assumed date used to build the complete Unix timestamp. That doesn’t affect the usage in this case but it’s something to keep in mind as you find your own applications for this technique. For example this little bonus treat… converting to the user’s local time zone (and 12 hour format) on the fly!

print( date("g:i a", strtotime("13:30:30 UTC")) );

15 Comments

  1. Bogdan

    # April 15, 2008 - 1:03 pm

    Thanks Tim, you saved my day :-)

  2. DRHgrafx

    # July 25, 2008 - 11:03 am

    Very helpful and simple!

  3. jonathan

    # July 30, 2008 - 2:03 pm

    thank you, it was very helpful

  4. jing

    # July 14, 2009 - 7:42 pm

    thank you jim, it was helpful

  5. Sujatha

    # December 27, 2009 - 10:48 am

    You are my saviors!

  6. Tom

    # January 7, 2010 - 1:38 pm

    You made my evening!!! Thanks so much!

  7. Steve

    # January 17, 2010 - 7:50 pm

    Thanks a lot, it was very very helpful to get it all assembled & ready to go, now I can finish designing my CMS !

  8. Jeff

    # April 5, 2010 - 10:49 pm

    How would this be done for a form input using variables for the time?

    For instance, if I have variables that I string together to show the date & time as:

    $event_start = $start_year.”-”.$start_month.”-”.$start_day.” “.$event_start_time_hh.”:”.$event_start_time_mm.”:00″;

    On my form I also have a field for my variable: $event_start_time_ampm with value for AM being ‘00′ and PM is ‘12′.

    I was trying to make an if else statement:

    if ($_POST['event_start_time_ampm'] == ‘12′) {
    $_POST['event_start_time_hh'] = $_POST['event_start_time_hh'] + 12;
    } else {
    $_POST['event_start_time_hh'];
    }

    But, it’s not working, it only formats the time as AM.

  9. Tom

    # April 6, 2010 - 11:32 am

    Very nice, thank you.

  10. Jim Mayes

    # April 6, 2010 - 12:01 pm

    Ok, let me see if I understand what you are describing Jeff. You have a form with fields for date and time and you have a select box giving the options of “AM” or “PM”. If that’s correct, you can avoid doing any hour math by just using strtotime().

    Change the am/pm select box to have literal values. So the selection for “AM” would provide the value “AM”. Selection for “PM” would give the value “PM”.

    Now, when the form is submitted concatenate the parts together into a string that is in US English date format

    $event_start = $start_month . '/' . $start_day . '/'. $start_year . ' ' . $event_start_time_hh . ':' . $event_start_time_mm . ' ' . $event_start_time_ampm;
    

    Then pass that string thru strtotime() and into date() to format however you need it.

    echo date('Y-m-d H:i:s', strtotime($event_start));
    

    Here’s a full example

    // assume these values are set by your form being submitted
    $start_month = '04';
    $start_day = '06';
    $start_year = '2010';
    $event_start_time_hh = '2';
    $event_start_time_mm = '30';
    $event_start_time_ampm = 'pm';
    
    // concatenate the parts into US English formatted date
    $event_start = $start_month . '/' . $start_day . '/'. $start_year . ' ' . $event_start_time_hh . ':' . $event_start_time_mm . ' ' . $event_start_time_ampm;
    
    // output full MySQL 24 hour format
    echo date('Y-m-d H:i:s', strtotime($event_start));
    
    //prints "2010-04-06 14:30:00"
    
  11. Jeff

    # April 6, 2010 - 2:09 pm

    Thanks for that explanation, I did figure out how to do it with if else, but this is much easier. I’m putting the value into my database, so instead of echoing it directly, would I just define the variable to something like this?

    $event_start = date(’Y-m-d H:i:s’, strtotime($event_start));

  12. Jim Mayes

    # April 6, 2010 - 2:17 pm

    yup, you can just as easily assign it to a variable as echo it out.

  13. rob barclay

    # April 14, 2010 - 10:07 pm

    Thanks for the interpretation of strtotime. I couldn’t make heads or tails of the description on php.net. You are the BEST

  14. siraj khan

    # June 10, 2010 - 3:47 am

    thank u so much!!

Leave a Reply