2011-03-22 69 views
9

我一直在开发PHP 5.3。php dateTime :: createFromFormat在5.2中?

但是我们的生产服务器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升级的机会),最简单的方法。

回答

19

只包括下一个代码

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

这是一个很好的答案。应该真的得到更多的赞扬!感谢 – andreapier 2013-03-15 20:45:33

+0

支持日期时间 'M':'''$ schedule_format = str_replace函数(阵列( 'M', 'Y', 'M', 'd', 'H', 'I', 'A'),阵列( '%b', '%Y', '%M', '%d', '%I', '%M', '%p'),$ DFORMAT);''' – kenorb 2013-09-09 15:59:54

+0

有一个小缺陷,因为'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);''' – kenorb 2013-09-19 08:40:25

9

由于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'); 

如果一切正常,你应该看到打印两次相同的,正确的日期和时间。

+0

出于好奇,你的代码和'else {$ {schedule = str_replace('/',' - ',$ schedule)之间的区别是什么? $ schedule = date('Y-m-d H:i:s',strtotime($ schedule)); }' – Hailwood 2011-03-22 23:50:00

+0

这可能是最好的解决办法,除非你可以通过输入更多的控制权,并确保您使用[支持的日期和时间格式(http://www.php.net/manual/en/datetime.formats。 PHP)。 – Jacob 2011-03-22 23:54:06

+0

'strtotime'不了解D/M/Y。它只能处理Y/M/D和M/D/Y。如果您尝试将D/M/Y传递给它,它将会失败。 'strtotime('20/02/2003')'返回'false'。你必须通过20.03.2003''(注意点!)才能识别该格式,这不是你期望的日期格式。 – Charles 2011-03-22 23:55:44

6

我认为这是干净多了给自己延长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

+0

这个工程'FANTASTIC'谢谢! ! – degenerate 2015-06-29 19:09:23

+0

这在5.2.x中不起作用,像'd/m/Y'这样的非英语格式,但是如果用' - '替换'/',它就会起作用。 – morgar 2016-10-14 01:39:39

+0

由于近6年前5.2.x版本已经发布[EOL](http://php.net/eol.php),我并不太在意。无论如何,谢谢你让我知道。 – vascowhite 2016-10-14 06:08:32

-1
$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已经与生产服务器类似的问题,所以我就用上面的日期时间来创建一个对象,然后格式更改为我喜欢如上。

-1

仅日期和时间

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

希望这样可以节省时间的人!

+0

刚刚阅读这个问题,请原谅我,打算在适用的问题上发布,但很高兴终于解决了这个问题,并不知道如何删除这个,我的坏。 – 2015-05-05 19:01:55

0

因为这不是真正显示如何使用“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 seconds:1483140203 12/30/2016 23:23:23