Konwertuj jeden format daty na inny w PHP

336

Czy istnieje prosty sposób na konwersję jednego formatu daty na inny format daty w PHP?

Mam to:

$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

Ale oczywiście chciałbym, żeby zwróciła aktualną datę, a nie świt. Co ja robię źle?

Tomek
źródło

Odpowiedzi:

293

Drugim parametrem date()musi być odpowiedni znacznik czasu (sekundy od 1 stycznia 1970 r.). Podajesz ciąg znaków, którego data () nie może rozpoznać.

Możesz użyć strtotime () do konwersji ciągu daty na znacznik czasu. Jednak nawet strtotime () nie rozpoznaje y-m-d-h-i-sformatu.

PHP 5.3 i nowsze

Zastosowanie DateTime::createFromFormat. Pozwala określić dokładną maskę - używając date()składni - do analizy dat ciągów przychodzących.

PHP 5.2 i niższe

Będziesz musiał ręcznie przeanalizować elementy (rok, miesiąc, dzień, godzinę, minutę, sekundę) ręcznie, używając substr()wyników i przekazując wyniki do mktime () , która zbuduje znacznik czasu.

Ale to dużo pracy! Polecam użycie innego formatu, który strftime () może zrozumieć. strftime () rozpoznaje dowolne dane wejściowe bez the next time joe will slip on the ice. na przykład to działa:

$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);   
Pekka
źródło
Dzięki, Pekka, właśnie edytowałem moje pytanie, próbowałem tego, ale wydaje się, że nie działa.
Tom
Zredagowałem odpowiedź, a ty ją zaakceptowałeś :) Dodałem jeszcze kilka przykładów i referencji.
Pekka
Gotcha, to rzeczywiście problem. Jest to stała nazwa pliku, którą muszę przekonwertować z powrotem na datę (musi być w tym formacie), więc wymyślę obejście.
Tom
Uwaga: Według php.net DateTimeistnieje od PHP 5.2 w rdzeniu PHP, a wsparcie eksperymentalne DateTimedla PHP 5.1 można włączyć podczas kompilacji. secure.php.net/manual/en/datetime.installation.php
Charlotte Dunois
108

Najłatwiej to zrobić

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

Najpierw nadajesz mu format $ dateString. Następnie mówisz, że chcesz, aby był to format $ newDateString.

Pozwala to również uniknąć używania strtotime, z którym czasami może być trudno pracować.

Jeśli nie przechodzisz z jednego formatu daty na inny, ale potrzebujesz tylko bieżącej daty (lub daty / godziny) w określonym formacie, jest to jeszcze łatwiejsze:

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

To drugie pytanie odnosi się również do tego samego tematu: Konwertuj format daty rrrr-mm-dd => dd-mm-rrrr .

ceiroa
źródło
A jak to jest duplikat, jeśli zadałem pytanie przed tym, o którym mówisz?
Tom
1
Zredagowałem odpowiedź. Chciałem tylko zaznaczyć, że te dwa pytania powinny być w jakiś sposób powiązane.
ceiroa
dostępne w php 5.3+
Zorox
$timestring = $now->format('Y-m-d h:i:s');pewno? mprzez miesiące, iprzez minuty
Mark Baker
@madlopt ~ metody statyczne: secure.php.net/manual/en/language.oop5.static.php
ceiroa
53

Podstawy

Najprostszym sposobem konwersji jednego formatu daty na inny jest użycie strtotime()go date(). strtotime()przekształci datę w uniksowy znacznik czasu . Ten uniksowy znacznik czasu można następnie przekazać w date()celu przekonwertowania go na nowy format.

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

Lub jako jedna linijka:

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

Pamiętaj, że strtotime()data musi być w prawidłowym formacie . Niedostarczenie prawidłowego formatu spowoduje strtotime()zwrócenie wartości false, co spowoduje wyświetlenie daty 1969-12-31.

Za pomocą DateTime()

Począwszy od PHP 5.2, PHP oferowało DateTime()klasę, która oferuje nam potężniejsze narzędzia do pracy z datami (i czasem). Możemy przepisać powyższy kod za pomocą DateTime():

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

Praca z uniksowymi znacznikami czasu

date() bierze uniksowy znacznik czasu jako drugi parametr i zwraca sformatowaną datę:

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

DateTime () działa z uniksowymi znacznikami czasu, dodając @przed znacznikiem czasu:

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

Jeśli posiadany znacznik czasu jest wyrażony w milisekundach (może kończyć się za 000i / lub znacznik czasu ma trzynaście znaków), musisz przekonwertować go na sekundy, zanim będzie można przekonwertować go na inny format. Można to zrobić na dwa sposoby:

  • Przytnij ostatnie trzy cyfry za pomocą substr()

Przycinanie ostatnich trzech cyfr można uzyskać na kilka sposobów, ale użycie substr()jest najłatwiejsze:

$timestamp = substr('1234567899000', -3);
  • Podziel substrat przez 1000

Możesz także przekonwertować znacznik czasu na sekundy, dzieląc przez 1000. Ponieważ znacznik czasu jest zbyt duży, aby systemy 32-bitowe mogły wykonywać matematykę, musisz użyć biblioteki BCMath, aby wykonać matematykę jako ciągi znaków:

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

Aby uzyskać uniksowy znacznik czasu, możesz użyć, strtotime()który zwraca uniksowy znacznik czasu:

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

Z DateTime () możesz korzystać DateTime::getTimestamp()

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

Jeśli korzystasz z PHP 5.2, możesz Uzamiast tego użyć opcji formatowania:

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

Praca z niestandardowymi i niejednoznacznymi formatami dat

Niestety nie wszystkie daty, z którymi programista musi współpracować, mają standardowy format. Na szczęście PHP 5.3 dostarczyło nam na to rozwiązanie. DateTime::createFromFormat()pozwala nam powiedzieć PHP, w jakim formacie znajduje się ciąg daty, aby można go było pomyślnie przeanalizować w obiekcie DateTime w celu dalszej manipulacji.

$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');

W PHP 5.4 uzyskaliśmy możliwość wykonywania dostępu członków klasy podczas tworzenia instancji, co pozwala nam zamienić nasz DateTime()kod w jednowierszowy:

$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');
John Conde
źródło
27

Spróbuj tego:

$old_date = date('y-m-d-h-i-s');
$new_date = date('Y-m-d H:i:s', strtotime($old_date));
Sarfraz
źródło
Nie będzie działać, strtotime () nie rozpoznaje formatu. Po prostu próbowałem.
Pekka
zgadzam się, po prostu wstawiłem kod formatu od pytającego, powinien być określony właściwy format.
Sarfraz
To zadziałało dla mnie. Mój $ old_date był mniej więcej taki 2012-05-22T19: 16: 37 + 01: 00. Dzięki przy okazji!
VishwaKumar
15

Aby przekonwertować $datez dd-mm-yyyy hh:mm:ssna odpowiednią datę / godzinę MySQL, idę w następujący sposób:

$date = DateTime::createFromFormat('d-m-Y H:i:s',$date)->format('Y-m-d H:i:s');
Jelle de Fries
źródło
4
Nie powinieneś łączyć tych metod, chyba że masz 110% pewności, że $ date jest prawidłową datą i pasuje do formatu. Z powiedział, że jest nieprawidłowa data, która nie dokładnie dopasować format powróci: Fatal error: Call to a member function format() on a non-object. Tylko głowa do góry!
Half Crazed
To prawda, że ​​lepszym rozwiązaniem jest zrobienie tego w 3 krokach z zerowym sprawdzeniem jako środkowym krokiem.
Jelle de Fries,
11

Poniżej przedstawiono łatwą metodę konwersji dat na różne formaty.

// 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";
Piotr
źródło
10
$old_date = date('y-m-d-h-i-s');       // works

robisz tu źle, tak powinno być

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

separatorem czasu jest „:”


Myślę, że to pomoże ...

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

LUB


$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); 
Rifat
źródło
Tak, jasne, dziękuję, to nazwa GUID, którą chcę przekonwertować z powrotem na odpowiedni format daty.
Tom
8

Ten natywny sposób pomoże przekonwertować dowolny wprowadzony format na żądany 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);
Nishad Up
źródło
7

Musisz przekonwertować $ old_date z powrotem na znacznik czasu, ponieważ funkcja daty wymaga znacznika czasu jako drugiego argumentu.

John Parker
źródło
7

strtotime to rozwiąże. daty nie są takie same i wszystkie są w formacie US.

<?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";
?>
de_nuit
źródło
5

Spróbuj tego:

$tempDate = explode('-','03-23-15');
$date = '20'.$tempDate[2].'-'.$tempDate[0].'-'.$tempDate[1];
winorośl
źródło
5

To rozwiązało dla mnie

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

Wyjście: 2018-04-18

Ashokkumar C
źródło
2

Jest to inny sposób konwersji formatu daty

 <?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'; ?>
Varun Malhotra
źródło
1

Używanie ciągów jest dla mnie dobrym rozwiązaniem, mniej problemów z mysql. Wykrywa bieżący format i zmienia go w razie potrzeby, to rozwiązanie jest tylko dla formatu hiszpańskiego / francuskiego i formatu angielskiego, bez użycia funkcji phetime datetime.

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;
 }

POSŁUGIWAĆ SIĘ

dateTranslator::translate($date, 'en')
Alejandro Aranda
źródło
1

Wiem, że to stare, ale wpadając na dostawcę, który niekonsekwentnie używa 5 różnych formatów dat w swoich interfejsach API (i testuje serwery z różnymi wersjami PHP od 5 do ostatnich 7), postanowiłem napisać uniwersalny konwerter, który współpracuje z niezliczoną liczbą wersji PHP.

Ten konwerter pobierze praktycznie dowolne dane wejściowe, w tym dowolny standardowy format daty i godziny (w tym z lub bez milisekund) i godziny (w tym z milisekundami dowolną reprezentację czasu epoki (w tym z milisekundami lub bez) i skonwertuje go na dowolny inny format.

Aby to nazwać:

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

Wysłanie wartości null dla formatu spowoduje, że funkcja zwróci datę / godzinę w Epoce / czasie uniksowym. W przeciwnym razie wyślij dowolny ciąg formatu obsługiwany przez date (), a także z „.u” dla milisekund (ja również obsługuję milisekundy, nawet jeśli date () zwraca zera).

Oto kod:

        <?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;    
        }
    ?>

Oto kilka przykładowych wywołań - zauważysz, że obsługuje on również dane strefy czasowej (chociaż jak wspomniano powyżej, czas inny niż GMT jest zwracany w Twojej strefie czasowej).

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

Oto wynik:

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

Jedyną rzeczą, której nie ma w tej wersji, jest możliwość wyboru strefy czasowej, w której ma być zwracana data i godzina. Początkowo napisałem to, aby zmienić dowolną datę i godzinę na Epoka, więc nie potrzebowałem obsługi strefy czasowej. Dodanie tego jest trywialne.

Robert Mauro
źródło