How to invert dates in PHP, regardless of format?

Asked

Viewed 22,797 times

18

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

5 answers

24


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 of use:

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

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

  • great solution to the problem!

  • 3

    -1 Assume that you will receive an expected entry without validating if it is indeed what is expected.

  • 1

    @Bacco from what I understood from his question, "independent of the input format" would relate to "YYYY-mm-dd or dd/mm/YYYYY" and not all types of date supported by language.

  • 1

    @Kazzkiq even understood this, what I find complicated is that in most of the answers, not only in yours, it is not clear what is day and what is month (but I agree that the question is in trouble, not the answer itself)

  • I agree that the ideal solution would be one that accepts any format and converts to any format that the user defines. But the question itself is superficial and covers only two cases. I do not know in these cases the best answer is thinking only the question, or a solution 100% complete.

  • 5

    The most interesting thing is that he did not state that he wants to invert from one format to another and vice versa, I could interpret in a thousand ways. The Accept is a sign that you did what he wanted (or, in the worst case, that he did not test both conditions). Really only @Flavianosilva commenting even to understand what he liked and what he didn’t like in each case :)

  • For my case was also perfect, thank you @Kazzkiq

Show 2 more comments

19

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

If you are using some 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 do the conversion in PHP itself, use :

date('d-m-Y', strtotime($ln['data_cadastro']));
  • 1

    That’s an excellent answer, congratulations ...

  • 1

    I’m grateful @Harrypotter

11

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.');
}

8

A very elegant solution, in my opinion, created by a fellow Member of the European Parliament revolves around of 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 enter the date in any input format and an output format. As long as the format is supported by the class Datetime:

$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 on PHP Sandbox


The solution currently marked as the best response, excuse the frankness, suffers from a serious conceptual problem described in the paradigm of DRY (Don’t Repeat Yourself) that is not something solely aimed at the orientation of objects.

In the solution presented all logic could be reused by using parameterization. It seems complicated because of the profanity (: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 say that this simplification is detrimental because despite reversing the date keeps the entry separator.

For these I can make two considerations:

  1. If the Application needs to normalize an input, it should theoretically store the normalized input in a single format. In that case, simply change the first occurrence of $separator by a fixed string:

    function invertDate( $date, $separator ) {
        return implode( '/', array_reverse( explode( $separator, $date ) ) );
    }
    
  2. If 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, count the number of non-numeric characters in the string and use it as a separator. Here, a coarse code that demonstrates the idea.

The idea is to parse the string to see whichnon- (alpha-)numeric character is most repeated and use it as a separator.

The link code above was not optimized where possible by not treating EVEN the best alternative.

  • That’s an excellent answer, congratulations ...

  • 1

    Apparently it is not the opinion of two citizens who preferred to negativate without clear reason. Tsc......

  • 1

    The answer emphasized more the function invertDate(), susceptible to the same problems as the original answer, as the parseDate(), in fact elegant and, more than that, suitable for working with dates. As the answer became long, if analyzed prematurely, it ends up leaving the desire... Even if an application validates its data before using a function like this, there is no way to assume that the function will actually receive the arguments in the expected way.

  • Yeah, looking at it from that angle, killing two birds with one stone might not even be the best way out. I’ll put at least one separator to make it more evident.

  • Reversing the answer, putting the elegant solution in evidence, and commenting on the marked solution as the best answer afterwards, would certainly add more to the answer. This is because, no matter where the die comes from or if it was changed before going through the function parseDate(), unlike the invertDate(), it will not fail to generate an error within it. :)

  • True, I hadn’t thought of it at the time. I’ll reverse.

Show 1 more comment

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

}
  • This function inverts dates of format dd/mm/yyyy to YYYY-mm-dd and from YYYY-mm-dd to dd/mm/yyyy.

  • 1

    -1 Assume that you will receive an expected entry without validating if it is indeed what is expected.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.