سؤال

هل هناك طريقة بسيطة لتحويل تنسيق تاريخ واحد إلى تنسيق تاريخ آخر في PHP؟

لدي هذا:

$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

لكنني بالطبع أود أن أعيد تاريخًا حاليًا بدلاً من الفجر. ما الخطأ الذي افعله؟

هل كانت مفيدة؟

المحلول

المعلمة الثانية date() يحتاج إلى أن يكون الطابع الزمني المناسب (ثواني منذ 1 يناير 1970). أنت تمرر سلسلة ، والتي لا يمكن التعرف عليها.

يمكنك استخدام strtotime () لتحويل سلسلة تاريخ إلى طابع زمني. ومع ذلك ، حتى strtotime () لا يتعرف على y-m-d-h-i-s صيغة.

PHP 5.3 وما فوق

يستخدم DateTime::createFromFormat. يسمح لك بتحديد قناع دقيق - باستخدام date() بناء الجملة - لتحليل التواريخ الواردة الواردة مع.

PHP 5.2 و Lower

سيتعين عليك تحليل العناصر (سنة ، شهر ، يوم ، ساعة ، دقيقة ، ثاني). substr() وتسليم النتائج إلى mktime () من شأنه أن يبني لك طابعًا زمنيًا.

لكن هذا كثير من العمل! أوصي باستخدام تنسيق مختلف يمكن أن يفهمه strftime (). strftime () يفهم أي مدخلات التاريخ أقل من the next time joe will slip on the ice. على سبيل المثال ، هذا يعمل:

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

نصائح أخرى

أسهل طريقة للقيام بذلك

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

أنت تعطيه أولاً التنسيق $ datestring. ثم تخبره بالتنسيق الذي تريد أن يكون فيه $ newDatestring.

هذا يتجنب أيضًا استخدام StrTotime ، والذي قد يكون من الصعب العمل معه في بعض الأحيان.

إذا لم تكن تتحول من تنسيق تاريخ إلى آخر ، ولكنك تريد فقط التاريخ الحالي (أو DateTime) بتنسيق محدد ، فسيكون الأمر أسهل:

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

يشير هذا السؤال الآخر أيضًا إلى نفس الموضوع: تحويل تنسيق تاريخ yyyy-mm-dd => dd-mm-yyyy.

أساسيات

طريقة التبسيط لتحويل تنسيق تاريخ إلى آخر هي الاستخدام strtotime() مع date(). strtotime() سيتم تحويل التاريخ إلى أ UNIX TIMESTAMP. يمكن بعد ذلك تمرير طابع الطابع الزمني لـ UNIX date() لتحويله إلى التنسيق الجديد.

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

أو كأحلى:

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

لا تنسى strtotime() يتطلب التاريخ ليكون في تنسيق صالح. سيؤدي عدم تقديم تنسيق صالح إلى strtotime() العودة الخاطئة والتي ستؤدي إلى أن يكون تاريخك 1969-12-31.

استخدام DateTime()

اعتبارا من PHP 5.2 ، عرضت PHP DateTime() الفصل الذي يوفر لنا أدوات أكثر قوة للعمل مع التواريخ (والوقت). يمكننا إعادة كتابة الكود أعلاه باستخدام DateTime() مثل:

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

العمل مع الطوابع الزمنية UNIX

date() يأخذ unix timeatamp كمعلمة ثانية ويعيد تاريخًا منسقًا لك:

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

يعمل DateTime () مع طوابع الزمنية UNIX عن طريق إضافة ملف @ قبل الطابع الزمني:

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

إذا كان الطابع الزمني الذي لديك في مللي ثانية (قد ينتهي في 000 و/أو الطابع الزمني يبلغ طوله ثلاثة عشر حرفًا) ستحتاج إلى تحويله إلى ثوان قبل أن تتمكن من تحويله إلى تنسيق آخر. هناك طريقتان للقيام بذلك:

  • تقليم الأرقام الثلاثة الأخيرة باستخدام substr()

يمكن تحقيق قطع الأرقام الثلاثة الأخيرة بعدة طرق ، ولكن باستخدام substr() هو الأسهل:

$timestamp = substr('1234567899000', -3);
  • قسّم Sentstr على 1000

يمكنك أيضًا تحويل الطابع الزمني إلى ثوانٍ بالقسمة على 1000 bcmath مكتبة للقيام بالرياضيات كقواسل:

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

للحصول على طابع زمني UNIX يمكنك استخدامه strtotime() الذي يعيد طابع زمني UNIX:

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

مع DateTime () يمكنك استخدامه DateTime::getTimestamp()

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

إذا كنت تقوم بتشغيل PHP 5.2 يمكنك استخدام U خيار التنسيق بدلاً من ذلك:

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

العمل مع تنسيقات تاريخ غير قياسي وغامضة

لسوء الحظ ، ليس كل التواريخ التي يتعين على المطور أن يعمل معها في شكل قياسي. لحسن الحظ ، قدم لنا PHP 5.3 حلاً لذلك. DateTime::createFromFormat() يتيح لنا أن نخبر PHP ما هي تنسيق سلسلة Date Sert بحيث يمكن تحليلها بنجاح في كائن DateTime لمزيد من التلاعب.

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

في PHP 5.4 ، اكتسبنا القدرة على القيام بوصول عضو في الفصل على مثيله مما يسمح لنا بتحويلنا DateTime() رمز في خط واحد:

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

جرب هذا:

$old_date = date('y-m-d-h-i-s');
$new_date = date('Y-m-d H:i:s', strtotime($old_date));

لتحويل $date من عند dd-mm-yyyy hh:mm:ss إلى DateTime MySQL المناسب أذهب مثل هذا:

$date = DateTime::createFromFormat('d-m-Y H:i:s',$date)->format('Y-m-d H:i:s');
$old_date = date('y-m-d-h-i-s');       // works

أنت مخطئ هنا ، يجب أن يكون هذا

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

فاصل الزمن هو: "


وأعتقد أن هذا سوف يساعد...

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

أو


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

فيما يلي طريقة سهلة لتحويل التواريخ إلى تنسيقات مختلفة.

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

تحتاج إلى تحويل $ Old_date إلى طابع زمني ، مثل وظيفة التاريخ يتطلب الطابع الزمني كحجة ثانية.

ستنجح Strtotime. التواريخ ليست هي نفسها وكلها في تنسيق الولايات المتحدة.

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

ستساعد هذه الطريقة الأصلية في تحويل أي تنسيق مدخل إلى التنسيق المطلوب.

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

جرب هذا:

$tempDate = explode('-','03-23-15');
$date = '20'.$tempDate[2].'-'.$tempDate[0].'-'.$tempDate[1];

هذا حل لي ،

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

الإخراج: 2018-04-18

هذه هي الطريقة الأخرى التي يمكنك من خلالها تحويل تنسيق التاريخ

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

مجرد استخدام السلاسل ، بالنسبة لي هو حل جيد ، ومشاكل أقل مع MySQL. يكتشف التنسيق الحالي ويغيره إذا لزم الأمر ، هذا الحل هو فقط للتنسيق الإسباني/الفرنسي وتنسيق اللغة الإنجليزية ، دون استخدام وظيفة DateTime PHP.

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

استعمال

dateTranslator::translate($date, 'en')

أعلم أن هذا قديم ، ولكن في مواجهة بائع يستخدم بشكل غير متسق 5 تنسيقات مختلفة في واجهات برمجة التطبيقات الخاصة بهم (واختبار خوادم مع مجموعة متنوعة من إصدارات PHP من 5 إلى آخر 7) ، قررت كتابة محول عالمي يعمل مع عدد لا يحصى من إصدارات PHP.

سيأخذ هذا المحول أي إدخال تقريبًا ، بما في ذلك أي تنسيق قياسي لوقت البيانات (بما في ذلك مع أو بدون ميلي ثانية) و أي تمثيل لوقت الحقبة (بما في ذلك مع أو بدون ميلي ثانية) وتحويله إلى أي تنسيق آخر تقريبًا.

لسماعها:

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

سيجعل إرسال Null for the Format وظيفة DateTime في وقت Epoch/Unix. خلاف ذلك ، أرسل أي سلسلة تنسيق تدعمها DATE () ، وكذلك مع ".u" لـ milliseconds (أنا أتعامل مع المللي ثانية أيضًا ، على الرغم من أن Date () يعيد الأصفار).

هذا هو الرمز:

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

إليك بعض المكالمات النموذجية - ستلاحظ أنها تتعامل أيضًا مع أي بيانات منطقة زمنية (على الرغم من أنه مذكور أعلاه ، يتم إرجاع أي وقت غير GMT في منطقتك الزمنية).

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

ها هو الإخراج:

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

الشيء الوحيد الذي لا في هذا الإصدار هو القدرة على تحديد المنطقة الزمنية التي تريد أن يكون فيها DateTime الذي تم إرجاعه. في الأصل ، كتبت هذا لتغيير أي وقت إلى وقت ، لذلك ، لم أكن بحاجة إلى دعم المنطقة الزمنية. من التافهة أن تضيف رغم ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top