PHP 5.2中的PHP date_parse_from_format()替代方案

Aca*_*cio 5 php datetime backwards-compatibility php-5.2

由于date_parse_from_format()仅在PHP 5.3中可用,因此我需要编写一个模仿其在PHP 5.2中的行为的函数.

是否可以为PHP 5.2编写此函数并使其工作方式与PHP 5.3中的完全相同?

例:

对于此输入:

<?php
$date = "6.1.2009 13:00+01:00";
print_r(date_parse_from_format("j.n.Y H:iP", $date));
?>
Run Code Online (Sandbox Code Playgroud)

我需要这个输出:

Array
(
    [year] => 2009
    [month] => 1
    [day] => 6
    [hour] => 13
    [minute] => 0
    [second] => 0
    [fraction] => 
    [warning_count] => 0
    [warnings] => Array
        (
        )

    [error_count] => 0
    [errors] => Array
        (
        )

    [is_localtime] => 1
    [zone_type] => 1
    [zone] => -60
    [is_dst] => 
)
Run Code Online (Sandbox Code Playgroud)

Ujj*_*har 6

<?php
function date_parse_from_format($format, $date) {
  $dMask = array(
    'H'=>'hour',
    'i'=>'minute',
    's'=>'second',
    'y'=>'year',
    'm'=>'month',
    'd'=>'day'
  );
  $format = preg_split('//', $format, -1, PREG_SPLIT_NO_EMPTY); 
  $date = preg_split('//', $date, -1, PREG_SPLIT_NO_EMPTY); 
  foreach ($date as $k => $v) {
    if ($dMask[$format[$k]]) $dt[$dMask[$format[$k]]] .= $v;
  }
  return $dt;
}
?>
Run Code Online (Sandbox Code Playgroud)

例1:

<?php
    print_r(date_parse_from_format('mmddyyyy','03232011');
?>
Run Code Online (Sandbox Code Playgroud)

输出1:

数组([月] => 03 [日] => 23 [年] => 2011)

例2:

 <?php
    print_r(date_parse_from_format('yyyy.mm.dd HH:ii:ss','2011.03.23 12:03:00'));
 ?>
Run Code Online (Sandbox Code Playgroud)

输出2:

数组([年] => 2011 [月] => 03 [日] => 23 [小时] => 12 [分] => 03 [秒] => 00)

  • 究竟?为什么?不可能.也许你应该给PHP家族写一封非常好的信,要求他们将它反向移植到5.2.哦,不等待5.2不再受到积极支持= p (3认同)

小智 5

这是我改进的版本,我认为完整.仅考虑错误和警告.

if( !function_exists('date_parse_from_format') ){
    function date_parse_from_format($format, $date) {
        // reverse engineer date formats
        $keys = array(
            'Y' => array('year', '\d{4}'),              //Année sur 4 chiffres
            'y' => array('year', '\d{2}'),              //Année sur 2 chiffres
            'm' => array('month', '\d{2}'),             //Mois au format numérique, avec zéros initiaux
            'n' => array('month', '\d{1,2}'),           //Mois sans les zéros initiaux
            'M' => array('month', '[A-Z][a-z]{3}'),     //Mois, en trois lettres, en anglais
            'F' => array('month', '[A-Z][a-z]{2,8}'),   //Mois, textuel, version longue; en anglais, comme January ou December
            'd' => array('day', '\d{2}'),               //Jour du mois, sur deux chiffres (avec un zéro initial)
            'j' => array('day', '\d{1,2}'),             //Jour du mois sans les zéros initiaux
            'D' => array('day', '[A-Z][a-z]{2}'),       //Jour de la semaine, en trois lettres (et en anglais)
            'l' => array('day', '[A-Z][a-z]{6,9}'),     //Jour de la semaine, textuel, version longue, en anglais
            'u' => array('hour', '\d{1,6}'),            //Microsecondes
            'h' => array('hour', '\d{2}'),              //Heure, au format 12h, avec les zéros initiaux
            'H' => array('hour', '\d{2}'),              //Heure, au format 24h, avec les zéros initiaux
            'g' => array('hour', '\d{1,2}'),            //Heure, au format 12h, sans les zéros initiaux
            'G' => array('hour', '\d{1,2}'),            //Heure, au format 24h, sans les zéros initiaux
            'i' => array('minute', '\d{2}'),            //Minutes avec les zéros initiaux
            's' => array('second', '\d{2}')             //Secondes, avec zéros initiaux
        );

        // convert format string to regex
        $regex = '';
        $chars = str_split($format);
        foreach ( $chars AS $n => $char ) {
            $lastChar = isset($chars[$n-1]) ? $chars[$n-1] : '';
            $skipCurrent = '\\' == $lastChar;
            if ( !$skipCurrent && isset($keys[$char]) ) {
                $regex .= '(?P<'.$keys[$char][0].'>'.$keys[$char][1].')';
            }
            else if ( '\\' == $char ) {
                $regex .= $char;
            }
            else {
                $regex .= preg_quote($char);
            }
        }

        $dt = array();
        // now try to match it
        if( preg_match('#^'.$regex.'$#', $date, $dt) ){
            foreach ( $dt AS $k => $v ){
                if ( is_int($k) ){
                    unset($dt[$k]);
                }
            }
            if( !checkdate($dt['month'], $dt['day'], $dt['year']) ){
                $dt['error_count'] = 1;
            } else {
                $dt['error_count'] = 0;
            }
        }
        else {
            $dt['error_count'] = 1;
        }

        $dt['errors'] = array();
        $dt['fraction'] = '';
        $dt['warning_count'] = 0;
        $dt['warnings'] = array();
        $dt['is_localtime'] = 0;
        $dt['zone_type'] = 0;
        $dt['zone'] = 0;
        $dt['is_dst'] = '';
        return $dt;
    }
}
Run Code Online (Sandbox Code Playgroud)