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 (or more precisely, a subset of humans known as “Americans” that are also prone to, on occasion, take for granted that their cultural habits are common to all humans… as pointed out by John in the comments below) 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") );

output: 1735344000

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")) );

output: 12/28/2024

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")) );

output: 1:30 pm

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")) );

output: 13:30:00

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")) );

output: 1:30 pm

30 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!!

  15. John

    # August 22, 2010 - 1:58 pm

    Thank you for confirming that Europeans are not humans ;)

  16. Jim Mayes

    # August 22, 2010 - 2:03 pm

    Glad I could do my part. Please spread the word ;)

  17. steph jimenez

    # August 30, 2010 - 10:48 pm

    hi i hope you could help me with my problem..i have a form for time(an have an option value from 1:00,1:30,2:00,2:30,3:00,3:30,…12:30)and also have a select box for choosing am or pm..if i choose for example 1:00(for the time value) and i want to choose “pm”…i dont have problems with “am”,but i encounter problems when i choose “pm”already..

    this is the code that we have done:

    //for timeDeparture:
    if($_REQUEST['ampm'] == “am”){
    $time = $_REQUEST['timed'];
    }else{
    $convertTime = date(“H:I”,$convertTime);
    $time = $convertTime;
    }

    *hope you could help me with this one..thanks

  18. Johan L. Cerezo

    # December 5, 2010 - 1:48 am

    Thanks Jim! I used php for a long time but this info is a great help for me.

  19. Rakesh

    # March 6, 2011 - 10:12 pm

    Thanks dude….

  20. Jeremy

    # March 17, 2011 - 1:36 am

    OMG. thank you. I’ve been stumbling around in the dark for half an hour at least.

  21. NateW

    # April 30, 2011 - 12:16 pm

    Thanks for the tips but it would have been much more useful if you also included what would print at execution of the code…

  22. Amy

    # September 30, 2011 - 10:38 am

    just what I needed! thank you!

  23. Will Fastie

    # November 27, 2011 - 9:23 am

    Thanks! The “over engineering” crack helped clear my head.

  24. willowdan

    # January 15, 2012 - 5:04 am

    Wow, the very thing I needed … Many thanks

  25. restroika

    # February 18, 2012 - 6:10 am

    This is awesome… destroy my fu**ing stuck! Thank

  26. Martin

    # March 9, 2012 - 9:37 am

    HOOO YES! thanks guy.

  27. Tony Gray

    # May 26, 2012 - 11:29 am

    I use date and strtotime for dates but the light bulb hadn’t clicked to just apply the same combo to time. I’ve spent hours trying to make sense of php.net’s various time functions. Thank you so much for sharing (and, you’re right, there is a lot of convoluted code out there for duplicating what those two functions do).

  28. Yosh

    # June 18, 2012 - 12:54 pm

    If you can believe it, phpfox 3.0, which is a great social networking platform, actually forces you to enter events in military time! This makes the software kind of unusable for normal people. Who thinks in military time? Anyway, here is my fix:

    First you have to change the “Add Event” template (Edit templates -> event -> add.html.php) to show 12 hour format and AM/PM instead of the military time. Just view the html source for the event page and copy and paste the select tags for start_hour and start_minute. Then be sure to remove the 13-24 from the start_hour dropdown AND then create an AM/PM drop down called “start_ampm”

    Then do the same for the end_minute, end_hour, and end_ampm. (You have to delete the custom smarty generated dropdowns, changing the attributes won’t override the defaults. It’s not a big deal.)

    And finally you have to edit the actual file: module/event/include/service/process.class.php — add these lines:

    //12 Hour to Military Time Hack — start hour/minute
    $startTimeHack = $aVals['start_hour'] . “:” . $aVals['start_minute'] . ” ” . $aVals['start_ampm'];
    $aVals['start_hour'] = DATE(“H”, STRTOTIME($startTimeHack));

    //This line is left unchanged from the original code
    //as a reference point for you
    $iStartTime = Phpfox::getLib(‘date’)->mktime($aVals['start_hour'], $aVals['start_minute'], 0, $aVals['start_month'], $aVals['start_day'], $aVals['start_year']);

    //12 hour to military time hack — end hour/minute
    $endTimeHack = $aVals['end_hour'] . “:” . $aVals['end_minute'] . ” ” . $aVals['end_ampm'];
    $aVals['end_hour'] = DATE(“H”, STRTOTIME($endTimeHack));

    //This line is left unchanged from the original code
    //as a reference point for you.
    $iEndTime = Phpfox::getLib(‘date’)->mktime($aVals['end_hour'], $aVals['end_minute'], 0, $aVals['end_month'], $aVals['end_day'], $aVals['end_year']);

  29. tushersuvro

    # June 27, 2012 - 11:25 pm

    Thanks dude. I was looking for it for about an hour and your solution made my problem solved in just about 1 minute. Thank you very much. Cheers.

    Mahfuz

Leave a Reply