How to invert dates in PHP, regardless of format?

18

How to invert dates in PHP? I need to invert dates in PHP regardless of the input format, either YYYY-mm-dd or dd/mm/YYYYY .

    
asked by anonymous 18.06.2014 / 15:59

5 answers

22

Version with explode() :

function inverteData($data){
    if(count(explode("/",$data)) > 1){
        return implode("-",array_reverse(explode("/",$data)));
    }elseif(count(explode("-",$data)) > 1){
        return implode("/",array_reverse(explode("-",$data)));
    }
}

Example usage:

$data = "1992-10-01"; //ou 01/10/1992
echo inverteData($data);
  

Note: Remembering that this solution works correctly only with the entries dd/mm/YYYY or YYYY-mm-dd , alternating the result between the two formats.

    
18.06.2014 / 17:18
18

Instead of using larger functions, you can follow 2 "faster" or "better" paths to my look.

If you are using a SQL database and want it to return the already formatted date you can use:

SELECT DATE_FORMAT(tbl_data,'%d/%m/%Y') as data FROM tb_tabela

If you want to convert to PHP yourself, use:

date('d-m-Y', strtotime($ln['data_cadastro']));
    
18.06.2014 / 17:00
9

Based on what has been described ...

function swap_date($date_str)
{
    if ($date = \DateTime::createFromFormat('Y-m-d', $date_str)) {
        return $date->format('d/m/Y');
    } elseif ($date = \DateTime::createFromFormat('d/m/Y', $date_str)) {
        return $date->format('Y-m-d');
    }

    throw new \InvalidArgumentException('Invalid input date format.');
}
    
19.06.2014 / 21:13
8

A really elegant solution in my opinion, created by a forum colleague revolves around the solution proposed by Harry Potter just above (or below: p):

/**
 * Altera uma data para outro formato
 * 
 * @param string $date String contendo a data a ser formatada
 * @param string $outputFormat Formato de saida
 * @throws Exception Quando não puder converter a data
 * @return string Data formatada
 * @author Hugo Ferreira da Silva
 */
function parseDate($date, $outputFormat = 'd/m/Y'){
    $formats = array(
        'd/m/Y',
        'd/m/Y H',
        'd/m/Y H:i',
        'd/m/Y H:i:s',
        'Y-m-d',
        'Y-m-d H',
        'Y-m-d H:i',
        'Y-m-d H:i:s',
    );

    foreach($formats as $format){
        $dateObj = DateTime::createFromFormat($format, $date);
        if($dateObj !== false){
            break;
        }
    }

    if($dateObj === false){
        throw new Exception('Invalid date:' . $date);
    }

    return $dateObj->format($outputFormat);
}

In it we can inform the date in any input format and an output format. As long as the format is supported by the DateTime class:

$testDates = array(
    '2012-10-30 00:00:00',
    '06/01/1986 14',
    '06/12/1983 14:30:10',
    '1984-01-06 14:30:10',
);

foreach($testDates as $date){
    echo parseDate($date, 'd/m/Y H:i:s'), PHP_EOL;
}

Demo no PHP Sandbox

The solution currently marked for best answer , apologize for the frankness, suffers from a serious conceptual problem described in the paradigm of the DRY (Do not Repeat Yourself), which is not something solely oriented to Object orientation.

In the solution presented all logic could be reused by using parameterization. It seems complicated because of the curse (: p), but it is simple, just add another parameter with the separator to be used:

function invertDate( $date, $separator ) {
    return implode( $separator, array_reverse( explode( $separator, $date ) ) );
}

And everything is solved in a single line.

Some people say that this simplification is detrimental because even though it reverses the date, it maintains the input separator.

For these, I can make two considerations:

  • If the Application needs to normalize an input data, it theoretically must store the normalized data in a single format. In this case, you would need to change the first occurrence of $ separator to a fixed string:

    function invertDate( $date, $separator ) {
        return implode( '/', array_reverse( explode( $separator, $date ) ) );
    }
    
  • If the input data accepts multiple input formats, the Application has serious modeling problems and / or lacks data validation.

  • But it is still possible to improve so that there is no repetition. One of many possibilities would be, after removing the letters from the input data, count the number of non-numeric characters of the string and use it as a separator. Here , a rough code that demonstrates the idea.

    The idea is to analyze the string to see which character does not (alpha-) numeric most repeat and use it as a separator.

      

    The above link code was not optimized where possible because it was not EVEN the best alternative.

        
    18.06.2014 / 21:20
    4
    function InvertData($campo){
    
        if(substr($campo,2,1)=='/'){
            $campo=substr($campo,6,4).'-'.substr($campo,3,2).'-'.substr($campo,0,2);//2012-10-10
        } else {
            $campo=substr($campo,8,2).'/'.substr($campo,5,2).'/'.substr($campo,0,4); //10/10/2012
        }
    
        return($campo);
    
    }
    
        
    18.06.2014 / 15:59