Convert one date format into another in PHP
Asked Answered
R

18

386

Is there a simple way to convert one date format into another date format in PHP?

I have this:

$old_date = date('y-m-d-h-i-s');            // works

$middle = strtotime($old_date);             // returns bool(false)

$new_date = date('Y-m-d H:i:s', $middle);   // returns 1970-01-01 00:00:00

But I'd of course like it to return a current date rather than the crack 'o dawn. What am I doing wrong?

Romine answered 30/1, 2010 at 12:58 Comment(3)
tech-blog.maddyzone.com/php/type-date-convert-php very nice articleJoacimah
#2168416Ogee
This question's sample input string format and desired output format is "lossy" because the h is an/pm-ignorant. h will never be higher than 12, so there is no possibility of the H in the output being greater than 12. There simply isn't good data coming in, so good data cannot come out.Kuehnel
R
328

The second parameter to date() needs to be a proper timestamp (seconds since January 1, 1970). You are passing a string, which date() can't recognize.

You can use strtotime() to convert a date string into a timestamp. However, even strtotime() doesn't recognize the y-m-d-h-i-s format.

PHP 5.3 and up

Use DateTime::createFromFormat. It allows you to specify an exact mask - using the date() syntax - to parse incoming string dates with.

PHP 5.2 and lower

You will have to parse the elements (year, month, day, hour, minute, second) manually using substr() and hand the results to mktime() that will build you a timestamp.

But that's a lot of work! I recommend using a different format that strftime() can understand. strftime() understands any date input short of the next time joe will slip on the ice. for example, this works:

$old_date = date('l, F d y h:i:s');              // returns Saturday, January 30 10 02:06:34
$old_date_timestamp = strtotime($old_date);
$new_date = date('Y-m-d H:i:s', $old_date_timestamp);   
Radioactivate answered 30/1, 2010 at 13:1 Comment(1)
Note: According to php.net DateTime exists since PHP 5.2 in PHP core and experimential support for DateTime can be enabled for PHP 5.1 at compilation. secure.php.net/manual/en/datetime.installation.phpLuxembourg
K
132

The easiest way to do this is

$myDateTime = DateTime::createFromFormat('Y-m-d', $dateString);
$newDateString = $myDateTime->format('m/d/Y');

You are first giving it the format $dateString is in. Then you are telling it the format you want $newDateString to be in.

This also avoids the use of strtotime, which can be hard to work with at times.

If you are not transforming from one date format to another, but just want the current date (or datetime) in a specific format then it's even easier:

$now = new DateTime();
$timestring = $now->format('Y-m-d h:i:s');

This other question also refers to the same topic: Convert date format yyyy-mm-dd => dd-mm-yyyy.

Kidnap answered 11/7, 2012 at 14:58 Comment(4)
I've edited the response. I just wanted to point out that these two questions should be linked somehow.Kidnap
$timestring = $now->format('Y-m-d h:i:s'); surely? m for months, i for minutesWhiles
@madlopt ~ static methods: secure.php.net/manual/en/language.oop5.static.phpKidnap
You are right. But it can't create an object if a date is bad.Famished
R
65

The Basics

The simplist way to convert one date format into another is to use strtotime() with date(). strtotime() will convert the date into a Unix Timestamp. That Unix Timestamp can then be passed to date() to convert it to the new format.

$timestamp = strtotime('2008-07-01T22:35:17.02');
$new_date_format = date('Y-m-d H:i:s', $timestamp);

Or as a one-liner:

$new_date_format = date('Y-m-d H:i:s', strtotime('2008-07-01T22:35:17.02'));

Keep in mind that strtotime() requires the date to be in a valid format. Failure to provide a valid format will result in strtotime() returning false which will cause your date to be 1969-12-31.

Using DateTime()

As of PHP 5.2, PHP offered the DateTime() class which offers us more powerful tools for working with dates (and time). We can rewrite the above code using DateTime() as so:

$date = new DateTime('2008-07-01T22:35:17.02');
$new_date_format = $date->format('Y-m-d H:i:s');

Working with Unix timestamps

date() takes a Unix timeatamp as its second parameter and returns a formatted date for you:

$new_date_format = date('Y-m-d H:i:s', '1234567890');

DateTime() works with Unix timestamps by adding an @ before the timestamp:

$date = new DateTime('@1234567890');
$new_date_format = $date->format('Y-m-d H:i:s');

If the timestamp you have is in milliseconds (it may end in 000 and/or the timestamp is thirteen characters long) you will need to convert it to seconds before you can can convert it to another format. There's two ways to do this:

  • Trim the last three digits off using substr()

Trimming the last three digits can be acheived several ways, but using substr() is the easiest:

$timestamp = substr('1234567899000', -3);
  • Divide the substr by 1000

You can also convert the timestamp into seconds by dividing by 1000. Because the timestamp is too large for 32 bit systems to do math on you will need to use the BCMath library to do the math as strings:

$timestamp = bcdiv('1234567899000', '1000');

To get a Unix Timestamp you can use strtotime() which returns a Unix Timestamp:

$timestamp = strtotime('1973-04-18');

With DateTime() you can use DateTime::getTimestamp()

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->getTimestamp();

If you're running PHP 5.2 you can use the U formatting option instead:

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->format('U');

Working with non-standard and ambiguous date formats

Unfortunately not all dates that a developer has to work with are in a standard format. Fortunately PHP 5.3 provided us with a solution for that. DateTime::createFromFormat() allows us to tell PHP what format a date string is in so it can be successfully parsed into a DateTime object for further manipulation.

$date = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM');
$new_date_format = $date->format('Y-m-d H:i:s');

In PHP 5.4 we gained the ability to do class member access on instantiation has been added which allows us to turn our DateTime() code into a one-liner:

$new_date_format = (new DateTime('2008-07-01T22:35:17.02'))->format('Y-m-d H:i:s');

$new_date_format = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM')->format('Y-m-d H:i:s');
Rutledge answered 15/4, 2014 at 14:49 Comment(0)
D
29

Try this:

$old_date = date('y-m-d-h-i-s');
$new_date = date('Y-m-d H:i:s', strtotime($old_date));
Diverticulosis answered 30/1, 2010 at 13:1 Comment(4)
Won't work, strtotime() doesn't recognize the format. Just tried.Radioactivate
agreed, i just put in the format code from questioner, there should be proper format specified.Diverticulosis
This answer is missing its educational explanation.Kuehnel
This answer is provably incorrect and its existence (and positive score) is only damaging the Researcher eXperience.Kuehnel
S
16

To convert $date from dd-mm-yyyy hh:mm:ss to a proper MySQL datetime I go like this:

$date = DateTime::createFromFormat('d-m-Y H:i:s',$date)->format('Y-m-d H:i:s');
Singer answered 4/3, 2013 at 12:45 Comment(2)
You shouldn't chain these methods unless you are 110% sure $date is a valid date and fits the format. With that being said, an invalid date that doesn't exactly match the format will return: Fatal error: Call to a member function format() on a non-object. Just a heads up!Monafo
True, a better solution is to do it in 3 steps with a null check as the middle step.Singer
D
15

The following is an easy method to convert dates to different formats.

// Create a new DateTime object
$date = DateTime::createFromFormat('Y-m-d', '2016-03-25');

// Output the date in different formats
echo $date->format('Y-m-d')."\n";
echo $date->format('d-m-Y')."\n";
echo $date->format('m-d-Y')."\n";
Drexler answered 25/3, 2016 at 9:11 Comment(0)
B
11
$old_date = date('y-m-d-h-i-s');       // works

you are doing wrong here, this should be

$old_date = date('y-m-d h:i:s');       // works

separator of time is ':'


I think this will help...

$old_date = date('y-m-d-h-i-s');              // works

preg_match_all('/(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)/', $old_date, $out, PREG_SET_ORDER);
$out = $out[0];
$time = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]);

$new_date = date('Y-m-d H:i:s', $time); 

OR


$old_date = date('y-m-d-h-i-s');              // works

$out = explode('-', $old_date);
$time = mktime($out[3], $out[4], $out[5], $out[1], $out[2], $out[0]);

$new_date = date('Y-m-d H:i:s', $time); 
Bobsledding answered 30/1, 2010 at 13:8 Comment(2)
Yes, sure thanks, it's a GUID filename that I want to convert back into a proper date format.Romine
preg_match_all() seems a bit silly if you are not looping its return value. Why call _all when you only want one?Kuehnel
D
11

This native way will help to convert any inputted format to the desired format.

$formatInput = 'd-m-Y'; //Give any format here, this would be converted into your format
$dateInput = '01-02-2018'; //date in above format

$formatOut = 'Y-m-d'; // Your format
$dateOut = DateTime::createFromFormat($formatInput, $dateInput)->format($formatOut);
Dimenhydrinate answered 7/2, 2018 at 8:38 Comment(1)
I don't see how this answer adds any new value to the page. There are several answers that gave this technique YEARS earlier.Kuehnel
J
9

strtotime will work that out. the dates are just not the same and all in us-format.

<?php
$e1 = strtotime("2013-07-22T12:00:03Z");
echo date('y.m.d H:i', $e1);
echo "2013-07-22T12:00:03Z";

$e2 = strtotime("2013-07-23T18:18:15Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-23T18:18:15Z";

$e1 = strtotime("2013-07-21T23:57:04Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-21T23:57:04Z";
?>
Jehial answered 23/7, 2013 at 21:10 Comment(0)
P
8

You need to convert the $old_date back into a timestamp, as the date function requires a timestamp as its second argument.

Psychedelic answered 30/1, 2010 at 13:1 Comment(0)
S
7

Easiest and simplest way to change date format in php

In PHP any date can be converted into the required date format using different scenarios for example to change any date format into Day, Date Month Year

$newdate = date("D, d M Y", strtotime($date));

It will show date in the following very well format

Mon, 16 Nov 2020

And if you have time as well in your existing date format for example if you have datetime format of SQL 2020-11-11 22:00:00 you can convert this into the required date format using the following

$newdateformat = date("D, d M Y H:i:s", strtotime($oldateformat));

It will show date in following well looking format

Sun, 15 Nov 2020 16:26:00

Sedimentation answered 19/11, 2020 at 7:3 Comment(0)
C
6

This solved for me,

$old = '18-04-2018';
$new = date('Y-m-d', strtotime($old));
echo $new;

Output : 2018-04-18

Confidential answered 4/4, 2018 at 18:34 Comment(1)
This unexplained answer completely ignores the OP's question. At best, this is the correct answer to a different question. This answer should not be on this page -- it is only bloating an already bloated page and damaging the researcher experience.Kuehnel
U
5

Try this:

$tempDate = explode('-','03-23-15');
$date = '20'.$tempDate[2].'-'.$tempDate[0].'-'.$tempDate[1];
Univalent answered 31/3, 2015 at 13:6 Comment(1)
This unexplained answer completely ignores the OP's question. At best, this is the correct answer to a different question. This answer should not be on this page -- it is only bloating an already bloated page and damaging the researcher experience.Kuehnel
N
2

This is the other way you can convert date format

<?php
$pastDate = "Tuesday 11th October, 2016";
$pastDate = str_replace(",","",$pastDate);

$date = new DateTime($pastDate);
$new_date_format = $date->format('Y-m-d');

echo $new_date_format.' 23:59:59'; ?>
Nancinancie answered 6/6, 2017 at 7:22 Comment(1)
This is not the OP's input. You are answering a different question.Kuehnel
H
2

I know this is old, but, in running into a vendor that inconsistently uses 5 different date formats in their APIs (and test servers with a variety of PHP versions from the 5's through the latest 7's), I decided to write a universal converter that works with a myriad of PHP versions.

This converter will take virtually any input, including any standard datetime format (including with or without milliseconds) and any Epoch Time representation (including with or without milliseconds) and convert it to virtually any other format.

To call it:

$TheDateTimeIWant=convertAnyDateTome_toMyDateTime([thedateIhave],[theformatIwant]);

Sending null for the format will make the function return the datetime in Epoch/Unix Time. Otherwise, send any format string that date() supports, as well as with ".u" for milliseconds (I handle milliseconds as well, even though date() returns zeros).

Here's the code:

<?php   
function convertAnyDateTime_toMyDateTime($dttm,$dtFormat)
{
    if (!isset($dttm))
    {
        return "";
    }
    $timepieces = array();
    if (is_numeric($dttm))
    {
        $rettime=$dttm;
    }
    else
    {
        $rettime=strtotime($dttm);
        if (strpos($dttm,".")>0 and strpos($dttm,"-",strpos($dttm,"."))>0)
        {
            $rettime=$rettime.substr($dttm,strpos($dttm,"."),strpos($dttm,"-",strpos($dttm,"."))-strpos($dttm,"."));
            $timepieces[1]="";
        }
        else if (strpos($dttm,".")>0 and strpos($dttm,"-",strpos($dttm,"."))==0)
        {               
            preg_match('/([0-9]+)([^0-9]+)/',substr($dttm,strpos($dttm,"."))." ",$timepieces);
            $rettime=$rettime.".".$timepieces[1];
        }
    }
    
    if (isset($dtFormat))
    {
        // RETURN as ANY date format sent
        if (strpos($dtFormat,".u")>0)       // Deal with milliseconds
        {
            $rettime=date($dtFormat,$rettime);              
            $rettime=substr($rettime,0,strripos($rettime,".")+1).$timepieces[1];                
        }
        else                                // NO milliseconds wanted
        {
            $rettime=date($dtFormat,$rettime);
        }
    }
    else
    {
        // RETURN Epoch Time (do nothing, we already built Epoch Time)          
    }
    return $rettime;    
}
?>

Here's some sample calls - you will note it also handles any time zone data (though as noted above, any non GMT time is returned in your time zone).

$utctime1="2018-10-30T06:10:11.2185007-07:00";
$utctime2="2018-10-30T06:10:11.2185007";
$utctime3="2018-10-30T06:10:11.2185007 PDT";
$utctime4="2018-10-30T13:10:11.2185007Z";
$utctime5="2018-10-30T13:10:11Z";
$dttm="10/30/2018 09:10:11 AM EST";

echo "<pre>";
echo "<b>Epoch Time to a standard format</b><br>";
echo "<br>Epoch Tm: 1540905011    to STD DateTime     ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011","Y-m-d H:i:s")."<hr>";
echo "<br>Epoch Tm: 1540905011          to UTC        ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011","c");
echo "<br>Epoch Tm: 1540905011.2185007  to UTC        ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011.2185007","c")."<hr>";
echo "<b>Returned as Epoch Time (the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC), minus leap seconds.)";
echo "</b><br>";
echo "<br>UTCTime1: ".$utctime1." ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime1,null);
echo "<br>UTCTime2: ".$utctime2."       ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime2,null);
echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,null);
echo "<br>UTCTime4: ".$utctime4."      ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime4,null);
echo "<br>UTCTime5: ".$utctime5."              ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime5,null);
echo "<br>NO MILIS: ".$dttm."        ----RESULT: ".convertAnyDateTime_toMyDateTime($dttm,null);
echo "<hr>";
echo "<hr>";
echo "<b>Returned as whatever datetime format one desires</b>";
echo "<br>UTCTime1: ".$utctime1." ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime1,"Y-m-d H:i:s")."              Y-m-d H:i:s";
echo "<br>UTCTime2: ".$utctime2."       ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime2,"Y-m-d H:i:s.u")."      Y-m-d H:i:s.u";
echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,"Y-m-d H:i:s.u")."      Y-m-d H:i:s.u";
echo "<p><b>Returned as ISO8601</b>";
echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,"c")."        ISO8601";
echo "</pre>";

Here's the output:

Epoch Tm: 1540905011                        ----RESULT: 2018-10-30 09:10:11

Epoch Tm: 1540905011          to UTC        ----RESULT: 2018-10-30T09:10:11-04:00
Epoch Tm: 1540905011.2185007  to UTC        ----RESULT: 2018-10-30T09:10:11-04:00
Returned as Epoch Time (the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC), minus leap seconds.)

UTCTime1: 2018-10-30T06:10:11.2185007-07:00 ----RESULT: 1540905011.2185007
UTCTime2: 2018-10-30T06:10:11.2185007       ----RESULT: 1540894211.2185007
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 1540905011.2185007
UTCTime4: 2018-10-30T13:10:11.2185007Z      ----RESULT: 1540905011.2185007
UTCTime5: 2018-10-30T13:10:11Z              ----RESULT: 1540905011
NO MILIS: 10/30/2018 09:10:11 AM EST        ----RESULT: 1540908611
Returned as whatever datetime format one desires
UTCTime1: 2018-10-30T06:10:11.2185007-07:00 ----RESULT: 2018-10-30 09:10:11              Y-m-d H:i:s
UTCTime2: 2018-10-30T06:10:11.2185007       ----RESULT: 2018-10-30 06:10:11.2185007      Y-m-d H:i:s.u
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 2018-10-30 09:10:11.2185007      Y-m-d H:i:s.u
Returned as ISO8601
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 2018-10-30T09:10:11-04:00        ISO8601

The only thing not in this version is the ability to select the time zone you want the returned datetime to be in. Originally, I wrote this to change any datetime to Epoch Time, so, I didn't need time zone support. It's trivial to add though.

Hobbledehoy answered 1/2, 2019 at 20:34 Comment(1)
try this one "2018-01-01T01:30:25.388940303Z"Quidnunc
V
1

Just using strings, for me is a good solution, less problems with mysql. Detects the current format and changes it if necessary, this solution is only for spanish/french format and english format, without use php datetime function.

class dateTranslator {

 public static function translate($date, $lang) {
      $divider = '';

      if (empty($date)){
           return null;   
      }
      if (strpos($date, '-') !== false) {
           $divider = '-';
      } else if (strpos($date, '/') !== false) {
           $divider = '/';
      }
      //spanish format DD/MM/YYYY hh:mm
      if (strcmp($lang, 'es') == 0) {

           $type = explode($divider, $date)[0];
           if (strlen($type) == 4) {
                $date = self::reverseDate($date,$divider);
           } 
           if (strcmp($divider, '-') == 0) {
                $date = str_replace("-", "/", $date);
           }
      //english format YYYY-MM-DD hh:mm
      } else {

           $type = explode($divider, $date)[0];
           if (strlen($type) == 2) {

                $date = self::reverseDate($date,$divider);
           } 
           if (strcmp($divider, '/') == 0) {
                $date = str_replace("/", "-", $date);

           }   
      }
      return $date;
 }

 public static function reverseDate($date) {
      $date2 = explode(' ', $date);
      if (count($date2) == 2) {
           $date = implode("-", array_reverse(preg_split("/\D/", $date2[0]))) . ' ' . $date2[1];
      } else {
           $date = implode("-", array_reverse(preg_split("/\D/", $date)));
      }

      return $date;
 }

USE

dateTranslator::translate($date, 'en')
Virtu answered 30/11, 2016 at 20:58 Comment(0)
M
0

For completeness I'm adding an answer using the Carbon library, which is very common and used in large projects like the Laravel framework.

The Carbon constructor can be passed a date string (anything that is recognized by strtotime()) or a DateTime object. If you're dealing with a date string that can't be parsed easily, Carbon provides the Carbon::createFromFormat() static creator method.

$carbon = new Carbon("January 3 2025 4:28 am");
// or
$date = new \DateTime("January 3 2025 4:28 am");
$carbon = new Carbon($date);
// or
$carbon = Carbon::createFromFormat("Y-d-m/H:i", "2025-03-01/04:28");

Now that you have a native Carbon object, you can use the Carbon::format() method to output it in whatever format you need:

echo $carbon->format("l jS \\of F Y h:i A");
// Friday 3rd of January 2025 04:28 AM

There are a lot of helper methods to quickly output certain formats, such as Carbon::toDateTimeString() which outputs in MySQL format.

Misguided answered 9/6, 2021 at 15:6 Comment(0)
I
0

TestDome Question for php developer:

Valid String having / and - Output will like that

Array
(
    [0] => 20201215
    [1] => 20161215
)

Solutions:

$dates = array("2020/12/15","15-12-2016","12023121");
$result = array();
foreach($dates as $date){
    $f = explode('/',$date);
    $d = explode('-',$date);
    if(count($d) == 3){
    $myDateTime = DateTime::createFromFormat('d-m-Y', $date);
      $result[] = $newDateString = $myDateTime->format('Ymd');
    
    }elseif(count($f) == 3){
        $myDateTime = DateTime::createFromFormat('Y/m/d', $date);
          $result[] = $newDateString = $myDateTime->format('Ymd');
    }
 
}
Ivon answered 15/4, 2023 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.