【问题标题】:php dateTime::createFromFormat in 5.2?5.2 中的 php dateTime::createFromFormat?
【发布时间】:2011-07-20 22:08:10
【问题描述】:

我一直在 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)。

【问题讨论】:

    标签: php datetime php-5.2


    【解决方案1】:

    由于这并没有真正展示如何使用“z”选项将 YYYY:DDD:HH:MM:SS 时间转换为 unix 秒,因此您必须创建自己的函数来将 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 12/30/2016 23:23:23

    【讨论】:

      【解决方案2】:

      仅限日期和时间

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

      希望这可以节省一些时间!

      【讨论】:

      • 刚刚阅读了这个问题,请原谅我,本打算发布适用的问题,但很高兴终于解决了这个问题,不知道如何删除这个问题,我的错。
      【解决方案3】:
      $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 的生产服务器上遇到了类似的问题,所以我使用上面的 datetime 创建一个对象,然后按照我的喜好更改格式。

      【讨论】:

        【解决方案4】:

        我认为扩展 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。

        查看这里的演示http://3v4l.org/djucq

        【讨论】:

        • 这在 5.2.x 中无法使用通常的非英语格式,如 'd/m/Y',但如果将 '/' 替换为 '-' 则可以。
        • 随着 5.2.x 近 6 年前达到EOL,我并不太担心它。谢谢你让我知道。
        【解决方案5】:

        只需包含下一个代码

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

        【讨论】:

        • 这是一个很好的答案。真的应该得到更多的支持!谢谢
        • 支持 DateTime 'M':$schedule_format = str_replace(array('M', 'Y', 'm', 'd', 'H', 'i', 'a'),array('%b', '%Y', '%m', '%d', '%I', '%M', '%p'), $dformat);
        • 有一个小错误,因为 '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);
        • 在 Windows 上不起作用!,strptime 未实现
        【解决方案6】:

        因为strtotime 在面对 D/M/Y 时表现不佳,而date_create_from_format 不可用,strptime 可能是您在这里唯一的希望。它做了一些非常老派的事情,比如将年份视为自 1900 年以来的年数,将月份视为 1 月为零月。这是一些可怕的示例代码,它使用 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');
        

        如果有效,您应该会看到两次打印的相同、正确的日期和时间。

        【讨论】:

        • 出于好奇,你的代码和else { $schedule = str_replace('/', '-', $schedule); $schedule = date('Y-m-d H:i:s', strtotime($schedule)); }有什么区别
        • 这可能是最好的解决方案,除非您可以更好地控制输入并确保您使用的是Supported Date and Time Formats
        • strtotime 不理解 D/M/Y。它只能处理 Y/M/D 和 M/D/Y。如果您尝试将 D/M/Y 传递给它,它将失败。 strtotime('20/02/2003') 返回 false。您必须传递 '20.03.2003'(注意点!)才能识别该格式,这不是您期望的日期格式。
        • 我知道 strtotime 不喜欢/,但如果你将/ 转换为-,那么它会完美运行。我发现很难阅读上面的代码,介意评论一下以解释每个函数的作用吗?
        • 似乎支持 D-M-Y,但您的示例日期仅包含斜线。此外,虽然支持 D-M-Y,但 M-D-Y 不支持 - 替换 M/D/Y 上的斜杠会导致无法解析的日期。稍后我将使用更多 cmets 编辑我的代码。
        猜你喜欢
        • 1970-01-01
        • 2017-11-01
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-09
        • 2014-08-07
        • 1970-01-01
        相关资源
        最近更新 更多