Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP date_parse_from_format( ) alternative in PHP 5.2

Since date_parse_from_format( ) is available only in PHP 5.3, I need to write a function that mimics its behaviour in PHP 5.2.

Is it possible to write this function for PHP 5.2 and make it work exactly the same way that it does in PHP 5.3?

Example:

For this input:

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

I need this output:

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] => 
)
like image 542
Acacio Avatar asked Jul 12 '11 17:07

Acacio


People also ask

What is date_parse () function in PHP?

The date_parse () function returns an associative array with detailed information about a specified date. Required. Specifies a date (in a format accepted by strtotime ()) Returns an associative array containing information about the parsed date on success.

What is date_create_from_format in PHP?

This is a string value representing the format in which you need to format the info about the date. This is a string value representing the date for which you need the information about. PHP date_create_from_format () function returns array holding the information about the given date in the specified format.

What does date_parse_from_format() return?

Return an associative array with detailed information about a specified date, according to the specified format: The date_parse_from_format () function returns an associative array with detailed information about a specified date, according to the specified format. Required.

What is the format accepted by datetime ()?

Format accepted by DateTime::createFromFormat () . String representing the date/time. Returns associative array with detailed info about given date/time. The zone element of the returned array represents seconds instead of minutes now, and its sign is inverted.


2 Answers

<?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;
}
?>

Example 1:

<?php
    print_r(date_parse_from_format('mmddyyyy','03232011');
?>

Output 1:

Array ( [month] => 03 [day] => 23 [year] => 2011 )

Example 2:

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

Output 2:

Array ( [year] => 2011 [month] => 03 [day] => 23 [hour] => 12 [minute] => 03 [second] => 00 )

like image 75
Ujjwal Manandhar Avatar answered Sep 23 '22 14:09

Ujjwal Manandhar


Here is my improved version and I think complete. Only errors and warnings are not taken into account.

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;
    }
}
like image 39
OscarRyz Avatar answered Sep 23 '22 14:09

OscarRyz