WedX - журнал о программировании и компьютерных науках

php dateTime::createFromFormat в 5.2?

Я разрабатываю на php 5.3.

Однако наш рабочий сервер 5.2.6.

я использовал

$schedule = '31/03/2011 01:22 pm'; // example input
if (empty($schedule))
    $schedule = date('Y-m-d H:i:s');
else {
    $schedule = dateTime::createFromFormat('d/m/Y h:i a', $schedule);
    $schedule = $schedule->format('Y-m-d H:i:s');
}
echo $schedule;

Однако эта функция недоступна в версии 5.2.

Какой самый простой способ обойти это (нет шансов на обновление php).

22.03.2011

Ответы:


1

просто включите следующий код

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();
25.08.2012
  • Это БОЛЬШОЙ ответ. Должно действительно получить больше голосов! Спасибо 16.03.2013
  • Поддержка DateTime 'M': $schedule_format = str_replace(array('M', 'Y', 'm', 'd', 'H', 'i', 'a'),array('%b', '%Y', '%m', '%d', '%I', '%M', '%p'), $dformat); 09.09.2013
  • Есть небольшая ошибка, так как «H» следует заменить на %H (24-часовой формат), а не %I (12-часовой формат). Итак, вот улучшенная строка: $schedule_format = str_replace(array('M', 'Y', 'm', 'd', 'H', 'i', 'a'), array('%b', '%Y', '%m', '%d', '%H', '%M', '%p'), $dformat); 19.09.2013
  • Не работает в Windows!, strptime не реализован 07.02.2019

  • 2

    Потому что 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('Y-m-d H:i:s');
    

    Если это работает, вы должны увидеть одну и ту же правильную дату и время, напечатанные дважды.

    22.03.2011
  • из любопытства, в чем разница между вашим кодом и else { $schedule = str_replace('/', '-', $schedule); $schedule = date('Y-m-d H:i:s', strtotime($schedule)); } 23.03.2011
  • Это, вероятно, лучшее решение, если только вы не можете лучше контролировать ввод и использовать Поддерживаемые форматы даты и времени. 23.03.2011
  • strtotime не понимает Д/М/Г. Он может обрабатывать только Y/M/D и M/D/Y. Если вы попытаетесь передать ему D/M/Y, это не удастся. strtotime('20/02/2003') возвращает false. Вам нужно будет передать '20.03.2003' (обратите внимание на точки!), чтобы распознать этот формат, который не является ожидаемым форматом даты. 23.03.2011
  • Я понимаю, что strtotime не любит /, но если преобразовать / в -, то работает отлично. Мне трудно читать ваш код выше, не могли бы вы немного его прокомментировать, чтобы объяснить, что делает каждая функция? 23.03.2011
  • Похоже, D-M-Y поддерживается, но в вашем примере дата содержит только косые черты. Кроме того, в то время как D-M-Y поддерживается, M-D-Y не поддерживается - замена косых черт на M/D/Y приведет к невозможности анализа даты. Я отредактирую свой код с дополнительными комментариями через минуту. 23.03.2011
  • также, если `обращаться с годами, как если бы они были количеством лет с 1900 года`, верно, не хотели бы вы вычесть 1900 вместо добавления 1900? 23.03.2011
  • Я отредактировал свой пост, добавив несколько встроенных комментариев и ссылку на документацию sprintf. tm_year здесь получается 111, поэтому нам нужно добавить 1900, чтобы вернуться к 2011 году. Да, это действительно так. Причудливо, не так ли? Возвращает меня в мои Perl-дни... 23.03.2011
  • Ничего себе, в том году управляемость испорчена! Ваше здоровье! 23.03.2011
  • @Hailwood @Charles см. мой ответ stackoverflow.com/questions/5287224/ о форматах даты. 23.03.2011

  • 3

    Я думаю, что гораздо чище расширить класс 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('Y-m-d', '2013-6-13');
    var_dump($dateTime);
    var_dump($dateTime->format('Y-m-d'));
    

    Это будет работать во всех версиях PHP >= 5.2.0.

    Демонстрацию см. здесь: https://3v4l.org/djucq

    17.11.2013
  • Это не работает в 5.2.x с обычным неанглийским форматом, таким как 'd/m/Y', но работает, если вы замените '/' на '-'. 14.10.2016
  • Поскольку версия 5.2.x достигла EOL почти 6 лет назад, меня это не слишком беспокоит. Спасибо, что дали мне знать в любом случае. 14.10.2016

  • 4

    Поскольку на самом деле это не показывает, как преобразовать время 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/Y H:i:s", $timeSec);
    echo "unix seconds: " . $timeis . " " . $str ."<br>";
    

    Вывод на странице показывает его работу, так как я могу преобразовать секунды обратно в исходные входные значения. unix секунд: 1483140203 30.12.2016 23:23:23

    30.12.2015

    5
    $your_datetime_object=new DateTime($date);
    $date_format_modified=date_format($your_datetime_object,'D M d Y');//Change the format of date time
    

    У меня была аналогичная проблема с производственным сервером в 5.2, поэтому я использовал указанную выше дату и время для создания объекта, а затем изменил формат по своему вкусу, как указано выше.

    20.01.2014

    6

    Только дата и время

    $dateTime = DateTime::createFromFormat('Y-m-d\TH:i:s', '2015-04-20T18:56:42');
    

    ISO8601 без двоеточий

    $dateTime = DateTime::createFromFormat('Y-m-d\TH:i:sO', '2015-04-20T18:56:42+0000');
    

    ISO8601 с двоеточием

    $date = $dateTime->format('c');
    

    Формат Salesforce ISO8601

    DateTime::createFromFormat('Y-m-d\TH:i:s.uO', '2015-04-20T18:56:42.000+0000');
    

    Надеюсь, это сэкономит кому-то время!

    05.05.2015
  • Просто прочитайте вопрос, пожалуйста, простите меня, я хотел опубликовать соответствующий вопрос, но был рад, что наконец решил проблему, и понятия не имею, как это удалить, мой плохой. 05.05.2015
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]