Question
I want to convert a date string from yyyy-mm-dd format to dd-mm-yyyy in PHP, without doing the conversion in SQL.
I know that the date() function expects a Unix timestamp, but I am starting with a string such as:
$input = '2024-01-31';
I am not sure how to turn this string into something that PHP can format correctly.
How can I convert a date like yyyy-mm-dd into dd-mm-yyyy in PHP?
Short Answer
By the end of this page, you will understand how PHP date formatting works, how to convert a date string into another format, and when to use DateTime, strtotime(), or date() for safe and readable date handling.
Concept
In PHP, dates are often stored as strings, but formatting functions work best when PHP first understands that string as a date value.
The key idea is:
- Parse the original string into a date object or timestamp.
- Format that parsed date into the layout you want.
For example, if you have this string:
'2024-01-31'
that is just text until PHP interprets it as a date.
Why this matters
In real programs, dates often come from:
- databases
- forms
- APIs
- CSV files
- user input
These sources may provide dates in one format, while your application needs to display them in another.
In PHP, the most reliable modern approach is to use DateTime.
Two common ways to convert dates
1. Using DateTime
This is the preferred approach because it is clearer and more robust.
$date = new DateTime('2024-01-31');
echo $date->format('d-m-Y');
Output:
31-01-2024
2. Using strtotime() with date()
This is shorter, but slightly less explicit.
echo date('d-m-Y', strtotime('2024-01-31'));
Output:
31-01-2024
Why DateTime is usually better
- easier to read
- supports validation more cleanly
- works well in larger codebases
- avoids some confusion around timestamps and timezones
If you are learning PHP today, DateTime is the best habit to build.
Mental Model
Think of a date string like a sentence written on paper:
2024-01-31
At first, PHP just sees characters.
To work with it properly, PHP needs to understand the text as a real calendar date. That is the parsing step.
After that, formatting is like choosing how to print the same date on screen:
Y-m-d→2024-01-31d-m-Y→31-01-2024d/m/Y→31/01/2024
So the process is:
- input text
- parse into a date
- output in a new format
Same date, different display.
Syntax and Examples
Using DateTime
$input = '2024-01-31';
$date = new DateTime($input);
echo $date->format('d-m-Y');
Output:
31-01-2024
Explanation
new DateTime($input)parses the string into a date object.format('d-m-Y')prints the date in day-month-year format.
Using strtotime() and date()
$input = '2024-01-31';
echo date('d-m-Y', strtotime($input));
Output:
31-01-2024
Explanation
strtotime($input)converts the string into a Unix timestamp.date('d-m-Y', ...)formats that timestamp.
Best practice when the input format is known exactly
If you know the input is always Y-m-d, use DateTime::createFromFormat().
$input = '2024-01-31';
$date = DateTime::createFromFormat('Y-m-d', $input);
echo $date->format('d-m-Y');
This is helpful because it tells PHP exactly what format to expect.
Format characters
Common PHP date format characters:
Y= 4-digit yearm= 2-digit monthd= 2-digit day
So:
Y-m-dmeans2024-01-31d-m-Ymeans31-01-2024
Step by Step Execution
Consider this code:
$input = '2024-01-31';
$date = DateTime::createFromFormat('Y-m-d', $input);
echo $date->format('d-m-Y');
Here is what happens step by step:
1. Store the original string
$input = '2024-01-31';
The variable contains plain text.
2. Parse the string as a date
$date = DateTime::createFromFormat('Y-m-d', $input);
PHP reads the string using this pattern:
Y→ year =2024m→ month =01d→ day =31
Now $date is a DateTime object.
3. Output the date in a different format
echo $date->format('d-m-Y');
PHP prints the same date in this order:
d→31m→01Y→2024
Final output:
31-01-2024
Small trace example
$input = '2023-12-05';
$date = DateTime::createFromFormat('Y-m-d', $input);
echo $date->format('d-m-Y');
Trace:
- input string:
2023-12-05 - parsed year:
2023 - parsed month:
12 - parsed day:
05 - output:
05-12-2023
Real World Use Cases
Date format conversion appears in many real applications.
Common examples
Displaying database dates to users
Databases often store dates as:
2024-01-31
But users may expect:
31-01-2024
Formatting API responses
An external API may return ISO-style dates, and your app may need to display them in a local format.
Exporting reports
You might store dates in one format internally but export invoices or CSV files in another format.
Processing form input
A user may submit one format, while your backend stores a standardized format.
Logging and dashboards
Developers may prefer machine-friendly formats in storage and human-friendly formats in dashboards.
Practical rule
- Store dates in a standard format such as
Y-m-dwhen possible. - Display dates in whatever format users need.
Real Codebase Usage
In real PHP projects, developers usually avoid manually rearranging date strings like this:
// Avoid this
$parts = explode('-', $input);
echo $parts[2] . '-' . $parts[1] . '-' . $parts[0];
That works only when the input is always perfect, and it does not validate the date.
Common patterns in real code
Validation before formatting
$input = '2024-01-31';
$date = DateTime::createFromFormat('Y-m-d', $input);
if ($date === false) {
echo 'Invalid date';
} else {
echo $date->format('d-m-Y');
}
Guard clause pattern
function formatDateForDisplay(string $input): string
{
$date = DateTime::createFromFormat('Y-m-d', $input);
if ($date === false) {
return 'Invalid date';
}
return $date->format('d-m-Y');
}
This keeps the function simple and readable.
Reusable formatting helper
In larger projects, date conversion is often wrapped in a helper or service method so formatting is consistent everywhere.
function formatIsoDate(string $input): ?string
{
$date = DateTime::createFromFormat('Y-m-d', $input);
return $date ? $date->format('d-m-Y') : null;
}
Error handling for unreliable input
When dates come from forms or APIs, code often checks parsing errors before using the result.
Common Mistakes
1. Using the wrong format letters
A very common mistake is mixing up lowercase and uppercase letters.
echo date('d-m-y');
This prints a 2-digit year, not a 4-digit year.
Use this instead:
echo date('d-m-Y');
2. Assuming date() can directly reformat any string
Broken idea:
$input = '2024-01-31';
echo date('d-m-Y', $input);
Why it fails:
date()expects a timestamp as its second argument.$inputis a string, not a Unix timestamp.
Correct approach:
echo date('d-m-Y', strtotime($input));
Or better:
$date = new DateTime($input);
echo $date->format('d-m-Y');
3. Rearranging the string manually
Broken or fragile approach:
$input = '2024-01-31';
$parts = explode('-', $input);
echo $parts[2] . '-' . $parts[1] . '-' . $parts[0];
Why to avoid it:
- no validation
- breaks easily with unexpected input
- harder to maintain
4. Not checking for invalid input
$input = '2024-31-01';
$date = DateTime::createFromFormat('Y-m-d', $input);
echo $date->format('d-m-Y');
This can lead to incorrect behavior if parsing fails.
Safer version:
$input = '2024-31-01';
$date = DateTime::createFromFormat('Y-m-d', $input);
if ($date === false) {
echo 'Invalid date format';
} else {
echo $date->format('d-m-Y');
}
5. Ignoring timezones when working with full date-times
For simple date-only values this is often less noticeable, but for full timestamps it becomes important. Use DateTime carefully if time and timezone matter.
Comparisons
DateTime vs strtotime() + date()
| Approach | Example | Pros | Cons |
|---|---|---|---|
DateTime | new DateTime($input) | Clear, modern, flexible | Slightly more code |
strtotime() + date() | date('d-m-Y', strtotime($input)) | Short and convenient | Less explicit, weaker for strict parsing |
DateTime::createFromFormat() | DateTime::createFromFormat('Y-m-d', $input) | Best when input format is known exactly | Requires knowing the exact pattern |
new DateTime() vs createFromFormat()
| Method | Best for | Example |
|---|---|---|
new DateTime() | General date strings PHP can understand | new DateTime('2024-01-31') |
createFromFormat() | Strict, known input formats | DateTime::createFromFormat('Y-m-d', '2024-01-31') |
Manual string splitting vs date parsing
| Method | Recommended? | Reason |
|---|---|---|
explode() and reorder | No | Does not validate real dates |
DateTime parsing | Yes | Safer and easier to maintain |
Cheat Sheet
Quick reference
Convert Y-m-d to d-m-Y
$input = '2024-01-31';
echo (new DateTime($input))->format('d-m-Y');
Strict parsing
$input = '2024-01-31';
$date = DateTime::createFromFormat('Y-m-d', $input);
echo $date->format('d-m-Y');
Using strtotime()
$input = '2024-01-31';
echo date('d-m-Y', strtotime($input));
Common format characters
| Character | Meaning | Example |
|---|---|---|
Y | 4-digit year | 2024 |
y | 2-digit year | 24 |
m | 2-digit month | 01 |
d | 2-digit day | 31 |
Useful patterns
Y-m-d→2024-01-31d-m-Y→31-01-2024d/m/Y→31/01/2024
Safe habit
- Parse first
- Format second
- Validate input when it may be unreliable
FAQ
How do I change a date from yyyy-mm-dd to dd-mm-yyyy in PHP?
Use DateTime:
echo (new DateTime('2024-01-31'))->format('d-m-Y');
Can I use date() directly on a string?
No. date() expects a Unix timestamp as its second argument, not a raw date string.
Should I use strtotime() or DateTime?
For simple cases, both work. In most real projects, DateTime is preferred because it is clearer and more reliable.
What is the best way when I know the exact input format?
Use DateTime::createFromFormat().
$date = DateTime::createFromFormat('Y-m-d', '2024-01-31');
Why not just split the string with explode()?
Because that only rearranges text. It does not properly parse or validate whether the date is real.
What happens if the input date is invalid?
Parsing may fail or produce unexpected results. Always validate input when it comes from users or external systems.
Mini Project
Description
Build a small PHP utility that takes a list of database-style dates and converts them into a display-friendly format. This demonstrates parsing, formatting, and basic validation in a way that matches everyday backend work.
Goal
Create a PHP script that converts multiple Y-m-d date strings into d-m-Y format and reports invalid input safely.
Requirements
- Create an array of date strings in
Y-m-dformat. - Include at least one invalid date string.
- Convert each valid date to
d-m-Y. - Print a clear message for invalid dates.
- Use
DateTime::createFromFormat()instead of manually splitting strings.
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.