Question
I have a DATETIME column in MySQL, which returns values such as 2025-03-08 14:05:00.
How can I format this value in PHP for display as mm/dd/yy hh:mm AM/PM, for example 03/08/25 02:05 PM?
Short Answer
You will learn how to parse the standard MySQL DATETIME string in PHP and display it in a user-friendly 12-hour date and time format. You will also learn the important difference between PHP format characters such as m, i, h, and H.
Concept
A MySQL DATETIME value is normally returned to PHP as a string in this format:
YYYY-MM-DD HH:MM:SS
For example:
2025-03-08 14:05:00
The database format is designed for reliable storage and sorting, not necessarily for display to users. PHP's DateTimeImmutable class lets you:
- Parse the database string into a date/time object.
- Format that object using a display pattern.
For a display like 03/08/25 02:05 PM, use this PHP format string:
'm/d/y h:i A'
The letters are case-sensitive. In particular, PHP uses i for minutes. m means month, so using H:M does not mean hours and minutes in PHP.
Mental Model
Think of a date/time as an appointment written in one universal office format: 2025-03-08 14:05:00. That is useful for filing and sorting, so it is how the database stores it.
DateTimeImmutable is a translator. You give it the office format, then ask it to print the same appointment in a format your visitor expects, such as 03/08/25 02:05 PM.
The format string is the translator's instruction sheet:
msays “print the month.”dsays “print the day.”ysays “print the two-digit year.”hsays “print the hour on a 12-hour clock.”isays “print the minutes.”Asays “print AM or PM.”
Syntax and Examples
Parse a MySQL DATETIME value explicitly, then call format().
<?php
$mysqlDateTime = '2025-03-08 14:05:00';
$date = DateTimeImmutable::createFromFormat(
'Y-m-d H:i:s',
$mysqlDateTime
);
if ($date === false) {
throw new RuntimeException('The date from the database is invalid.');
}
$displayDate = $date->format('m/d/y h:i A');
echo $displayDate; // 03/08/25 02:05 PM
The parsing pattern, Y-m-d H:i:s, matches the usual MySQL DATETIME value:
| Character | Meaning | Example |
|---|---|---|
Y | Four-digit year | 2025 |
m | Two-digit month | 03 |
d | Two-digit day | 08 |
H | 24-hour hour | 14 |
i | Two-digit minutes | 05 |
s | Two-digit seconds | 00 |
The output pattern, m/d/y h:i A, creates the requested display format. h converts the hour to a 12-hour representation, and A adds uppercase AM or PM.
Step by Step Execution
Consider this code:
<?php
$mysqlDateTime = '2025-03-08 14:05:00';
$date = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $mysqlDateTime);
echo $date->format('m/d/y h:i A');
Step by step:
$mysqlDateTimecontains the string retrieved from MySQL:2025-03-08 14:05:00.createFromFormat('Y-m-d H:i:s', ...)reads the string as:- year
2025 - month
03 - day
08 - 24-hour time
14:05:00
- year
- PHP creates a
DateTimeImmutableobject representing that moment. format('m/d/y h:i A')prints:m→03d→08y→25h→02because 14:00 is 2 PM on a 12-hour clocki→05A→PM
- The final output is
03/08/25 02:05 PM.
Real World Use Cases
Formatting database timestamps is common whenever technical storage values must be shown to people:
- Order history: Display an order time such as
03/08/25 02:05 PM. - Admin dashboards: Show when an account was created or a record was updated.
- Booking systems: Present appointment times in a familiar local format.
- Activity feeds: Display when a comment, upload, or status change occurred.
- Email notifications: Include readable event dates rather than raw database strings.
The storage format can remain consistent in MySQL while each part of the application chooses an appropriate display format.
Real Codebase Usage
In real PHP applications, date formatting is usually kept near the presentation layer: a template, API resource, view model, or serializer. The database continues to store a standard value, while the application formats it only when returning it to a user.
A reusable helper can centralize the display rule:
<?php
function formatDatabaseDateTime(?string $value): ?string
{
if ($value === null) {
return null;
}
$date = DateTimeImmutable::createFromFormat('!Y-m-d H:i:s', $value);
$errors = DateTimeImmutable::getLastErrors();
if ($date === false || ($errors !== false && ($errors['warning_count'] > 0 || $errors['error_count'] > 0))) {
throw new InvalidArgumentException('Expected a MySQL DATETIME value.');
}
return $date->format('m/d/y h:i A');
}
The ?string type and early null return are useful when a database column allows NULL. Explicit parsing also makes the expected input format clear and helps catch invalid data rather than silently displaying an incorrect date.
For applications serving users in multiple time zones, developers commonly store timestamps in UTC and convert to the user's selected time zone before formatting.
Common Mistakes
Using M for minutes
In PHP, uppercase M is a short month name, not minutes.
// Incorrect: M means Jan, Feb, Mar, and so on.
echo $date->format('m/d/y H:M');
Use lowercase i for minutes:
echo $date->format('m/d/y h:i A');
Using H while also displaying AM/PM
H is a 24-hour hour (00 through 23). It does not fit a 12-hour display with AM or PM.
// Confusing output: 14:05 PM
echo $date->format('m/d/y H:i A');
Use h for a zero-padded 12-hour hour:
echo $date->format('m/d/y h:i A'); // 02:05 PM
Confusing m with n
mgives03for March.ngives3for March.
Use m when the requirement says mm.
Assuming the server time zone is always correct
A MySQL DATETIME has no time-zone information. If the database value represents UTC but PHP uses another default time zone, the displayed clock time may be wrong. Set the intended time zone when parsing or convert before formatting.
Ignoring invalid input
createFromFormat() can return false. Check the result before calling format() to avoid errors and to identify bad database values.
Comparisons
| Need | Format | Example output |
|---|---|---|
| Two-digit month | m | 03 |
| Month without leading zero | n | 3 |
| Two-digit day | d | 08 |
| Four-digit year | Y | 2025 |
| Two-digit year | y | 25 |
| 24-hour hour | H | 14 |
| 12-hour hour, leading zero | h | 02 |
| 12-hour hour, no leading zero | g | 2 |
| Minutes | i | 05 |
| Seconds | s | 00 |
| Uppercase meridiem | A | PM |
| Lowercase meridiem | a | pm |
For the requested output, choose m/d/y h:i A. If a user prefers a 24-hour clock, use m/d/y H:i and omit A.
Cheat Sheet
// Standard MySQL DATETIME input
$mysqlDateTime = '2025-03-08 14:05:00';
// Parse it
$date = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $mysqlDateTime);
// Display: 03/08/25 02:05 PM
echo $date->format('m/d/y h:i A');
| Task | PHP format character |
|---|---|
Month (01–12) | m |
Day (01–31) | d |
Year (25) | y |
Year (2025) | Y |
12-hour hour (01–12) | h |
24-hour hour (00–23) | H |
| Minutes | i |
| AM/PM | A |
Rules to remember:
- PHP format characters are case-sensitive.
- Use
i, notmorM, for minutes. - Pair
horgwithA/afor a 12-hour clock. - Check that
createFromFormat()did not returnfalse. - A MySQL
DATETIMEdoes not include a time zone.
FAQ
How do I format a MySQL DATETIME in PHP?
Parse the value with DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $value) and call format('m/d/y h:i A').
What PHP format character represents minutes?
Use lowercase i. For example, h:i A produces 02:05 PM.
Why does PHP use i instead of m for minutes?
PHP reserves m for the numeric month. Its date-format characters are historical and case-sensitive, so minutes use i.
Should I use H or h with AM/PM in PHP?
Use h for a 12-hour clock with a leading zero, or g without one. Use H only for a 24-hour clock and do not add AM/PM.
Can I format a NULL DATETIME value?
Yes, but check for null before parsing. A missing date should usually remain null or be displayed as a placeholder such as Not available.
Does MySQL DATETIME store a time zone?
No. DATETIME stores a date and clock time without time-zone information. Your application must know which time zone that value represents.
Can I format the date directly in MySQL instead?
MySQL has DATE_FORMAT(), but formatting in PHP is usually better for user-facing output because the application controls locale, time zone, and display rules.
Mini Project
Description
Create a small PHP function for an order-management page. The function receives a MySQL DATETIME string and returns a readable date for the order list. It also handles an optional missing date safely.
Goal
Build a formatter that turns a valid MySQL DATETIME into mm/dd/yy hh:mm AM/PM.
Requirements
- Accept a MySQL
DATETIMEstring ornull. - Return
nullwhen no date is provided. - Display valid dates using
m/d/y h:i A. - Reject invalid date strings with a clear exception.
- Demonstrate the function with one sample order date.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.