Я развиваюсь на php 5.3.
Однако наш производственный сервер – 5.2.6.
Я использую
$schedule = '31/03/2011 01:22 pm'; // example input if (empty($schedule)) $schedule = date('Ymd H:i:s'); else { $schedule = dateTime::createFromFormat('d/m/Y h:i a', $schedule); $schedule = $schedule->format('Ymd H:i:s'); } echo $schedule;
Однако эта функция недоступна в 5.2
Каков самый простой способ обойти это (нет шансов на обновление php).
просто включите следующий код
function DEFINE_date_create_from_format() { function date_create_from_format( $dformat, $dvalue ) { $schedule = $dvalue; $schedule_format = str_replace(array('Y','m','d', 'H', 'i','a'),array('%Y','%m','%d', '%I', '%M', '%p' ) ,$dformat); // %Y, %m and %d correspond to date()'s Y m and d. // %I corresponds to H, %M to i and %p to a $ugly = strptime($schedule, $schedule_format); $ymd = sprintf( // This is a format string that takes six total decimal // arguments, then left-pads them with zeros to either // 4 or 2 characters, as needed '%04d-%02d-%02d %02d:%02d:%02d', $ugly['tm_year'] + 1900, // This will be "111", so we need to add 1900. $ugly['tm_mon'] + 1, // This will be the month minus one, so we add one. $ugly['tm_mday'], $ugly['tm_hour'], $ugly['tm_min'], $ugly['tm_sec'] ); $new_schedule = new DateTime($ymd); return $new_schedule; } } if( !function_exists("date_create_from_format") ) DEFINE_date_create_from_format();
Поскольку strtotime
делает плохо, когда сталкиваются с D / M / Y и date_create_from_format
недоступно, strptime
может быть вашей единственной надеждой здесь. Он делает некоторые довольно старые школьные вещи, например, справляется с годами, как если бы они были числом лет с 1900 года и занимались месяцами, как будто месяц месяца был месяц. Вот какой ужасный примерный код, который использует sprintf
для повторной сборки даты во что-то, что понимает DateTime:
$schedule = '31/03/2011 01:22 pm'; // %Y, %m and %d correspond to date()'s Y m and d. // %I corresponds to H, %M to i and %p to a $ugly = strptime($schedule, '%d/%m/%Y %I:%M %p'); $ymd = sprintf( // This is a format string that takes six total decimal // arguments, then left-pads them with zeros to either // 4 or 2 characters, as needed '%04d-%02d-%02d %02d:%02d:%02d', $ugly['tm_year'] + 1900, // This will be "111", so we need to add 1900. $ugly['tm_mon'] + 1, // This will be the month minus one, so we add one. $ugly['tm_mday'], $ugly['tm_hour'], $ugly['tm_min'], $ugly['tm_sec'] ); echo $ymd; $new_schedule = new DateTime($ymd); echo $new_schedule->format('Ymd H:i:s');
Если он работает, вы должны увидеть то же самое, правильную дату и время, напечатанную дважды.
Я думаю, что гораздо createFromFormat()
расширить класс DateTime и реализовать createFromFormat()
так:
class MyDateTime extends DateTime { public static function createFromFormat($format, $time, $timezone = null) { if(!$timezone) $timezone = new DateTimeZone(date_default_timezone_get()); $version = explode('.', phpversion()); if(((int)$version[0] >= 5 && (int)$version[1] >= 2 && (int)$version[2] > 17)){ return parent::createFromFormat($format, $time, $timezone); } return new DateTime(date($format, strtotime($time)), $timezone); } } $dateTime = MyDateTime::createFromFormat('Ym-d', '2013-6-13'); var_dump($dateTime); var_dump($dateTime->format('Ym-d'));
Это будет работать во всех версиях PHP> = 5.2.0.
См. Здесь демо-версию http://3v4l.org/djucq
Так как на самом деле это не показывает, как конвертировать YYYY: DDD: HH: MM: SS время в unix секунд, используя опцию «z», вы должны создать свои собственные функции для преобразования DOY в месяц и день месяца. Это то, что я сделал:
function _IsLeapYear ($Year) { $LeapYear = 0; # Leap years are divisible by 4, but not by 100, unless by 400 if ( ( $Year % 4 == 0 ) || ( $Year % 100 == 0 ) || ( $Year % 400 == 0 ) ) { $LeapYear = 1; } return $LeapYear; } function _DaysInMonth ($Year, $Month) { $DaysInMonth = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); return ((_IsLeapYear($Year) && $Month == 2) ? 29 : $DaysInMonth[$Month - 1]); } function yydddhhssmmToTime($Year, $DOY, $Hour, $Min, $Sec) { $Day = $DOY; for ($Month = 1; $Day > _DaysInMonth($Year, $Month); $Month++) { $Day -= _DaysInMonth($Year, $Month); } $DayOfMonth = $Day; return mktime($Hour, $Min, $Sec, $Month, $DayOfMonth, $Year); } $timeSec = yydddhhssmmToTime(2016, 365, 23, 23, 23); $str = date("m/d/YH:i:s", $timeSec); echo "unix seconds: " . $timeis . " " . $str ."<br>";
Выход на странице показывает его работу, так как я могу преобразовать обратно секунды в исходные значения ввода. unix секунд: 1483140203 12/30/2016 23:23:23
$your_datetime_object=new DateTime($date); $date_format_modified=date_format($your_datetime_object,'DM d Y');//Change the format of date time
У меня была аналогичная проблема с производственным сервером в 5.2, поэтому я использовал указанное выше datetime для создания объекта, а затем изменил формат по своему вкусу, как указано выше.
Только дата и время
$dateTime = DateTime::createFromFormat('Ymd\TH:i:s', '2015-04-20T18:56:42');
ISO8601 нет двоеточий
$dateTime = DateTime::createFromFormat('Ymd\TH:i:sO', '2015-04-20T18:56:42+0000');
ISO8601 с двоеточиями
$date = $dateTime->format('c');
Формат Salesforce ISO8601
DateTime::createFromFormat('Ymd\TH:i:s.uO', '2015-04-20T18:56:42.000+0000');
Надеюсь, это экономит время!