192

I really like the strtotime() function, but the user manual doesn't give a complete description of the supported date formats. strtotime('dd/mm/YYYY') doesn't work, it works only with mm/dd/YYYY format.

If I have date in dd/mm/YYYY format, how can I convert it to YYYY-mm-dd? I can do it by using explode() function, but I think there are better solutions.

sitilge
  • 3,687
  • 4
  • 30
  • 56
Simon
  • 22,637
  • 36
  • 92
  • 121
  • 8
    You don't actually need to convert it to "YYYY-mm-dd" format to parse it - you just need to change it to "dd-mm-YYYY", which can be done with `str_replace('/', '-', $date);` – Gavin Coates Feb 12 '14 at 20:53

17 Answers17

456

Here is the simplified solution:

$date = '25/05/2010';
$date = str_replace('/', '-', $date);
echo date('Y-m-d', strtotime($date));

Result:

2010-05-25

The strtotime documentation reads:

Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.

TRiG
  • 10,148
  • 7
  • 57
  • 107
  • 2
    @Web Logic i can't anderstand the default format of strtotime() function, if i write strtotimr('01-01-2010'), it understand it as dd-mm-YYYY or mm-dd-YYYY format? – Simon May 23 '10 at 13:52
  • 3
    If you test it with: `echo date('Y-m-l', strtotime('01-01-2010'));` The result is `2010-01-Friday`. So day coming at the end, depends on how you specify the date format to the `date` function. –  May 23 '10 at 13:55
  • 1
    While what you have posted here is correct and answers the users question - it is a roundabout way of solving the actual problem. In order for strtotime() to properly parse a date in the format "dd/mm/yy", you need to replace the "/" with "-". Therefore you only really need the first two lines of the answer: `$date = '25/05/2010'; $date = str_replace('/', '-', $date);` The additional line is not necessary to solve your problem. – Gavin Coates Feb 12 '14 at 20:51
  • This is only correct if the day is >12: $date='1/2/34'; //1st of Feb 2034 echo date('d M Y', strtotime($date)); //02 Jan 2034 – kurdtpage Aug 28 '18 at 04:44
  • date('Y-m-d H:i:s', strtotime('26/05/17'); gives 2026-05-17 but it's the 26th of May 2017....It works with 26.05.17 – Ponzio Pilato Jul 15 '19 at 18:46
  • Why have you used Y-m-d when the documentation you quoted says "if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed." ? – wbinky Jan 19 '23 at 10:00
78

You can parse dates from a custom format (as of PHP 5.3) with DateTime::createFromFormat

$timestamp = DateTime::createFromFormat('!d/m/Y', '23/05/2010')->getTimestamp();

(Aside: The ! is used to reset non-specified values to the Unix timestamp, ie. the time will be midnight.)


If you do not want to (or cannot) use PHP 5.3, then a full list of available date/time formats which strtotime accepts is listed on the Date Formats manual page. That page more thoroughly describes the fact that m/d/Y is inferred over d/m/Y (but you can, as mentioned in the answers here, use d-m-Y, d.m.Y or d\tm\tY).


In the past, I've also resorted to the quicky str_replace mentioned in another answer, as well as self-parsing the date string into another format like

$subject   = '23/05/2010';
$formatted = vsprintf('%3$04d/%2$02d/%1$02d', sscanf($subject,'%02d/%02d/%04d'));
$timestamp = strtotime($formatted);
Toby Allen
  • 10,997
  • 11
  • 73
  • 124
salathe
  • 51,324
  • 12
  • 104
  • 132
22

This is a good solution to many problems:

function datetotime ($date, $format = 'YYYY-MM-DD') {

    if ($format == 'YYYY-MM-DD') list($year, $month, $day) = explode('-', $date);
    if ($format == 'YYYY/MM/DD') list($year, $month, $day) = explode('/', $date);
    if ($format == 'YYYY.MM.DD') list($year, $month, $day) = explode('.', $date);

    if ($format == 'DD-MM-YYYY') list($day, $month, $year) = explode('-', $date);
    if ($format == 'DD/MM/YYYY') list($day, $month, $year) = explode('/', $date);
    if ($format == 'DD.MM.YYYY') list($day, $month, $year) = explode('.', $date);

    if ($format == 'MM-DD-YYYY') list($month, $day, $year) = explode('-', $date);
    if ($format == 'MM/DD/YYYY') list($month, $day, $year) = explode('/', $date);
    if ($format == 'MM.DD.YYYY') list($month, $day, $year) = explode('.', $date);

    return mktime(0, 0, 0, $month, $day, $year);

}
jmattheis
  • 10,494
  • 11
  • 46
  • 58
Jonathan Roy
  • 903
  • 11
  • 20
17

From the STRTOTIME writeup Note:

Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.

It is as simple as that.

L. Smit
  • 171
  • 1
  • 2
  • We can implement that as they won't give error but when I checked `$t` and `$t1` are showing different result. I checked like this. `$t=strtotime(date('d-m-Y'));` and `$t1=strtotime(date('m/d/Y'));` – vusan Oct 10 '12 at 09:03
6

$srchDate = date_format(date_create_from_format('d/m/Y', $srchDate), 'Y/m/d');

This will work for you. You convert the String into a custom date format where you can specify to PHP what the original format of the String is that had been given to it. Now that it is a date format, you can convert it to PHP's default date format, which is the same that is used by MySQL.

Fi Horan
  • 503
  • 4
  • 14
3

fastest should probably be

false!== ($date !== $date=preg_replace(';[0-2]{2}/[0-2]{2}/[0-2]{2};','$3-$2-$1',$date))

this will return false if the format does not look like the proper one, but it wont-check wether the date is valid

musefan
  • 47,875
  • 21
  • 135
  • 185
2

I tried to convert ddmmyy format to date("Y-m-d" format but was not working when I directly pass ddmmyy =date('dmy')

then realized it has to be in yyyy-mm-dd format so. used substring to organize

$strParam = '20'.substr($_GET['date'], 4, 2).'-'.substr($_GET['date'], 2, 2).'-'.substr($_GET['date'], 0, 2);  

then passed to date("Y-m-d",strtotime($strParam));

it worked!

Kampai
  • 22,848
  • 21
  • 95
  • 95
smakintel.com
  • 416
  • 4
  • 5
1

I haven't found a better solution. You can use explode(), preg_match_all(), etc.

I have a static helper function like this

class Date {

    public static function ausStrToTime($str) {
        $dateTokens = explode('/', $str);
        return strtotime($dateTokens[1] . '/' . $dateTokens[0] . '/' . $dateTokens[2]); 

    }

}

There is probably a better name for that, but I use ausStrToTime() because it works with Australian dates (which I often deal with, being an Australian). A better name would probably be the standardised name, but I'm not sure what that is.

alex
  • 479,566
  • 201
  • 878
  • 984
1

Are you getting this value from a database? If so, consider formatting it in the database (use date_format in mysql, for example). If not, exploding the value may be the best bet, since strtotime just doesn't seem to appreciate dd/mm/yyyy values.

Joe Mastey
  • 26,809
  • 13
  • 80
  • 104
1

If you know it's in dd/mm/YYYY, you can do:

    $regex = '#([/d]{1,2})/([/d]{1,2})/([/d]{2,4})#';
    $match = array();
    if (preg_match($regex, $date, $match)) {
        if (strlen($match[3]) == 2) {
            $match[3] = '20' . $match[3];
        }
        return mktime(0, 0, 0, $match[2], $match[1], $match[3]);
    }
    return strtotime($date);

It will match dates in the form d/m/YY or dd/mm/YYYY (or any combination of the two)...

If you want to support more separators than just /, you can change the regex to:

    $regex = '#([\d]{1,2})[/-]([\d]{1,2})[/-]([\d]{2,4})#';

And then add any characters you want into the [/-] bit (Note, the - character needs to be last)

ircmaxell
  • 163,128
  • 34
  • 264
  • 314
  • Surely your regex should be using `\d` for decimal digits rather than `[/d]` for *forward-slash or d character*. – salathe May 23 '10 at 14:11
1

This workaround is simpler and more elegant than explode:

$my_date = str_replace("/", ".", $my_date);
$my_date = strtotime($my_date);
$my_date = date("Y-m-d", $my_date);

You don't have to know what format you're getting the date in, but if it comes with slashes they are replaced with full stops and it is treated as European by strtotime.

user2623027
  • 91
  • 2
  • 3
1

$date_info = '20/02/2019'; echo date('Y-m-d', strtotime(str_replace('/', '-', $date_info) ));

Nazmul Haque
  • 720
  • 8
  • 13
1

Simple as this

date('Y-m-d H:i:s', strtotime( str_replace('/', '-', $from_date ) ) );
Prajwol KC
  • 398
  • 6
  • 13
0

The simplest solution is this:

$date    = '07/28/2010';
$newdate = date('Y-m-d', strtotime($date));
0

This the solution i'm using even if the leading zero are there.

<?php
 $date = '05/05/2017';
 $date = str_replace('/', '-', $date);
 $date = date('Y-m-d', strtotime($date));

 echo $date;
?>
Nandhini
  • 54
  • 7
0

If nothing worked, try this.

$date = '25/05/2010'; //dd/mm/YYYY
$dateAr = explode('/',);
$date = $dateAr[2].'-'.$dateAr[1].'-'.$dateAr[0]; //YYYY-mm-dd
Disapamok
  • 1,426
  • 2
  • 21
  • 27
0
{{ date('d F Y',strtotime($a->dates)) }}

alternative use laravel

\Carbon\Carbon::parse($a->dates)->format('d F Y') }}
DoYouOne
  • 17
  • 4