Converta um formato de data para outro em PHP

336

Existe uma maneira simples de converter um formato de data para outro formato de data no PHP?

Eu tenho isto:

$old_date = date('y-m-d-h-i-s');            // works

$middle = strtotime($old_date);             // returns bool(false)

$new_date = date('Y-m-d H:i:s', $middle);   // returns 1970-01-01 00:00:00

Mas é claro que eu gostaria que retornasse uma data atual, em vez do amanhecer. O que estou fazendo errado?

Tom
fonte

Respostas:

293

O segundo parâmetro para date()precisa ser um carimbo de data / hora adequado (segundos desde 1 de janeiro de 1970). Você está passando uma string que date () não pode reconhecer.

Você pode usar strtotime () para converter uma string de data em um carimbo de data / hora. No entanto, mesmo strtotime () não reconhece o y-m-d-h-i-sformato.

PHP 5.3 e superior

Use DateTime::createFromFormat. Ele permite que você especifique uma máscara exata - usando a date()sintaxe - para analisar as datas de string recebidas.

PHP 5.2 e inferior

Você precisará analisar os elementos (ano, mês, dia, hora, minuto, segundo) manualmente usando substr()e entregando os resultados para mktime () que criará um carimbo de data / hora.

Mas isso dá muito trabalho! Eu recomendo usar um formato diferente que o strftime () possa entender. strftime () entende qualquer entrada de data que não seja the next time joe will slip on the ice. por exemplo, isso funciona:

$old_date = date('l, F d y h:i:s');              // returns Saturday, January 30 10 02:06:34
$old_date_timestamp = strtotime($old_date);
$new_date = date('Y-m-d H:i:s', $old_date_timestamp);   
Pekka
fonte
Obrigado Pekka, acabei de editar minha pergunta, tentei isso, mas ele não parece funcionar.
Tom
Editei a resposta enquanto você a aceitava :) Adicionei mais alguns exemplos e referências.
Pekka
Entendi, esse é realmente o problema. É um nome de arquivo fixo que eu preciso converter novamente em uma data (precisa estar nesse formato), então vou descobrir uma solução alternativa.
Tom
Nota: De acordo com o php.net DateTimeexiste desde o PHP 5.2 no núcleo do PHP e o suporte experimental para DateTimepode ser ativado para o PHP 5.1 na compilação. secure.php.net/manual/en/datetime.installation.php
Charlotte Dunois
108

A maneira mais fácil de fazer isso é

$myDateTime = DateTime::createFromFormat('Y-m-d', $dateString);
$newDateString = $myDateTime->format('m/d/Y');

Você está dando primeiro a ele o formato $ dateString. Depois, você está dizendo o formato em que deseja que $ newDateString esteja.

Isso também evita o uso de strtotime, que pode ser difícil de trabalhar às vezes.

Se você não está transformando de um formato de data para outro, mas apenas deseja a data atual (ou data e hora) em um formato específico, é ainda mais fácil:

$now = new DateTime();
$timestring = $now->format('Y-m-d h:i:s');

Essa outra pergunta também se refere ao mesmo tópico: Converter formato de data aaaa-mm-dd => dd-mm-aaaa .

ceiroa
fonte
E como é duplicado se eu fiz a pergunta antes da pergunta a que você está se referindo?
Tom
11
Eu editei a resposta. Eu só queria salientar que essas duas perguntas deveriam estar ligadas de alguma forma.
Cesara
disponível no php 5.3+
Zorox
$timestring = $now->format('Y-m-d h:i:s');certamente? mpor meses, ipor minutos
Mark Baker
@madlopt ~ métodos estáticos: secure.php.net/manual/en/language.oop5.static.php
ceiroa
53

O básico

A maneira simplista para converter um formato de data para outra é usar strtotime()com date(). strtotime()converterá a data em um carimbo de data e hora do Unix . Esse carimbo de data e hora do Unix pode ser passado date()para convertê-lo no novo formato.

$timestamp = strtotime('2008-07-01T22:35:17.02');
$new_date_format = date('Y-m-d H:i:s', $timestamp);

Ou como uma linha:

$new_date_format = date('Y-m-d H:i:s', strtotime('2008-07-01T22:35:17.02'));

Lembre-se de que strtotime()exige que a data esteja em um formato válido . A falha em fornecer um formato válido resultará no strtotime()retorno de false, o que fará com que sua data seja 1969-12-31.

Usando DateTime()

A partir do PHP 5.2, o PHP ofereceu a DateTime()classe que nos oferece ferramentas mais poderosas para trabalhar com datas (e hora). Podemos reescrever o código acima usando DateTime()o seguinte:

$date = new DateTime('2008-07-01T22:35:17.02');
$new_date_format = $date->format('Y-m-d H:i:s');

Trabalhando com carimbos de data e hora Unix

date() usa um timeatamp do Unix como seu segundo parâmetro e retorna uma data formatada para você:

$new_date_format = date('Y-m-d H:i:s', '1234567890');

DateTime () funciona com registros de data e hora do Unix adicionando um @antes do registro de data e hora:

$date = new DateTime('@1234567890');
$new_date_format = $date->format('Y-m-d H:i:s');

Se o carimbo de data / hora existente estiver em milissegundos (pode terminar em 000e / ou o carimbo de data / hora tem 13 caracteres), será necessário convertê-lo em segundos antes de poder convertê-lo em outro formato. Há duas maneiras de fazer isso:

  • Corte os três últimos dígitos usando substr()

O corte dos três últimos dígitos pode ser obtido de várias maneiras, mas o uso substr()é o mais fácil:

$timestamp = substr('1234567899000', -3);
  • Divida o substr por 1000

Você também pode converter o registro de data e hora em segundos, dividindo por 1000. Como o registro de data e hora é muito grande para sistemas de 32 bits fazerem matemática, você precisará usar a biblioteca BCMath para fazer a matemática como seqüências de caracteres:

$timestamp = bcdiv('1234567899000', '1000');

Para obter um registro de data e hora do Unix, você pode usar o strtotime()que retorna um registro de data e hora do Unix:

$timestamp = strtotime('1973-04-18');

Com DateTime () você pode usar DateTime::getTimestamp()

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->getTimestamp();

Se você estiver executando o PHP 5.2, poderá usar a Uopção de formatação:

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->format('U');

Trabalhando com formatos de data não padrão e ambíguos

Infelizmente, nem todas as datas com as quais um desenvolvedor precisa trabalhar estão em um formato padrão. Felizmente, o PHP 5.3 nos forneceu uma solução para isso. DateTime::createFromFormat()nos permite dizer ao PHP em que formato uma string de data está, para que possa ser analisada com sucesso em um objeto DateTime para manipulação adicional.

$date = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM');
$new_date_format = $date->format('Y-m-d H:i:s');

No PHP 5.4, ganhamos a capacidade de acessar membros da classe por instanciação, o que nos permite transformar nosso DateTime()código em uma única linha:

$new_date_format = (new DateTime('2008-07-01T22:35:17.02'))->format('Y-m-d H:i:s');

$new_date_format = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM')->format('Y-m-d H:i:s');
John Conde
fonte
27

Tente o seguinte:

$old_date = date('y-m-d-h-i-s');
$new_date = date('Y-m-d H:i:s', strtotime($old_date));
Sarfraz
fonte
Não funcionará, strtotime () não reconhece o formato. Apenas tentei.
Pekka
concordou, eu apenas coloquei o código de formato do questionador, deve haver o formato apropriado especificado.
Sarfraz 30/01
Funcionou para mim. Meu $ old_date era algo como isto 2012-05-22T19: 16: 37 + 01: 00. Por falar nisso, agradeço!
VishwaKumar # 25/12
15

Para converter $datea partir dd-mm-yyyy hh:mm:ssde uma data e hora MySQL apropriado que eu vá como este:

$date = DateTime::createFromFormat('d-m-Y H:i:s',$date)->format('Y-m-d H:i:s');
Jelle de Fries
fonte
4
Você não deve encadear esses métodos, a menos que tenha 110% de certeza que $ date é uma data válida e se ajusta ao formato. Com isso dito, uma data inválida que não corresponde exatamente o formato retornará: Fatal error: Call to a member function format() on a non-object. Apenas um alerta!
Meio enlouquecido
É verdade que uma solução melhor é fazer isso em três etapas, com uma verificação nula como a etapa do meio.
Jelle de Fries
11

A seguir, é um método fácil de converter datas em diferentes formatos.

// Create a new DateTime object
$date = DateTime::createFromFormat('Y-m-d', '2016-03-25');

// Output the date in different formats
echo $date->format('Y-m-d')."\n";
echo $date->format('d-m-Y')."\n";
echo $date->format('m-d-Y')."\n";
Pedro
fonte
10
$old_date = date('y-m-d-h-i-s');       // works

você está fazendo errado aqui, isso deve ser

$old_date = date('y-m-d h:i:s');       // works

separador de tempo é ':'


Eu acho que isso ajudará...

$old_date = date('y-m-d-h-i-s');              // works

preg_match_all('/(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)/', $old_date, $out, PREG_SET_ORDER);
$out = $out[0];
$time = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]);

$new_date = date('Y-m-d H:i:s', $time); 

OU


$old_date = date('y-m-d-h-i-s');              // works

$out = explode('-', $old_date);
$time = mktime($out[3], $out[4], $out[5], $out[1], $out[2], $out[0]);

$new_date = date('Y-m-d H:i:s', $time); 
Rifat
fonte
Sim, claro, obrigado, é um nome de arquivo GUID que desejo converter novamente em um formato de data adequado.
Tom
8

Essa maneira nativa ajudará a converter qualquer formato inserido no formato desejado.

$formatInput = 'd-m-Y'; //Give any format here, this would be converted into your format
$dateInput = '01-02-2018'; //date in above format

$formatOut = 'Y-m-d'; // Your format
$dateOut = DateTime::createFromFormat($formatInput, $dateInput)->format($formatOut);
Nishad Up
fonte
7

Você precisa converter o $ old_date novamente em um registro de data e hora, pois a função date exige um registro de data e hora como seu segundo argumento.

John Parker
fonte
7

strtotime resolverá isso. as datas não são as mesmas e estão todas no formato americano.

<?php
$e1 = strtotime("2013-07-22T12:00:03Z");
echo date('y.m.d H:i', $e1);
echo "2013-07-22T12:00:03Z";

$e2 = strtotime("2013-07-23T18:18:15Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-23T18:18:15Z";

$e1 = strtotime("2013-07-21T23:57:04Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-21T23:57:04Z";
?>
de_nuit
fonte
5

Tente o seguinte:

$tempDate = explode('-','03-23-15');
$date = '20'.$tempDate[2].'-'.$tempDate[0].'-'.$tempDate[1];
vinha
fonte
5

Isso resolveu para mim,

$old = '18-04-2018';
$new = date('Y-m-d', strtotime($old));
echo $new;

Saída: 2018-04-18

Ashokkumar C
fonte
2

Essa é a outra maneira de converter o formato da data

 <?php
$pastDate = "Tuesday 11th October, 2016";
$pastDate = str_replace(",","",$pastDate);

$date = new DateTime($pastDate);
$new_date_format = $date->format('Y-m-d');

echo $new_date_format.' 23:59:59'; ?>
Varun Malhotra
fonte
1

Apenas usar strings, para mim é uma boa solução, menos problemas com o mysql. Detecta o formato atual e altera, se necessário, esta solução é apenas para o formato espanhol / francês e inglês, sem usar a função php datetime.

class dateTranslator {

 public static function translate($date, $lang) {
      $divider = '';

      if (empty($date)){
           return null;   
      }
      if (strpos($date, '-') !== false) {
           $divider = '-';
      } else if (strpos($date, '/') !== false) {
           $divider = '/';
      }
      //spanish format DD/MM/YYYY hh:mm
      if (strcmp($lang, 'es') == 0) {

           $type = explode($divider, $date)[0];
           if (strlen($type) == 4) {
                $date = self::reverseDate($date,$divider);
           } 
           if (strcmp($divider, '-') == 0) {
                $date = str_replace("-", "/", $date);
           }
      //english format YYYY-MM-DD hh:mm
      } else {

           $type = explode($divider, $date)[0];
           if (strlen($type) == 2) {

                $date = self::reverseDate($date,$divider);
           } 
           if (strcmp($divider, '/') == 0) {
                $date = str_replace("/", "-", $date);

           }   
      }
      return $date;
 }

 public static function reverseDate($date) {
      $date2 = explode(' ', $date);
      if (count($date2) == 2) {
           $date = implode("-", array_reverse(preg_split("/\D/", $date2[0]))) . ' ' . $date2[1];
      } else {
           $date = implode("-", array_reverse(preg_split("/\D/", $date)));
      }

      return $date;
 }

USAR

dateTranslator::translate($date, 'en')
Alejandro Aranda
fonte
1

Sei que isso é antigo, mas, ao encontrar um fornecedor que usa inconsistentemente 5 formatos de data diferentes em suas APIs (e servidores de teste com uma variedade de versões PHP dos anos 5 aos 7), decidi escrever um conversor universal que trabalha com uma infinidade de versões do PHP.

Esse conversor aceita praticamente qualquer entrada, incluindo qualquer formato padrão de data e hora (incluindo com ou sem milissegundos) e qualquer representação do Epoch Time (incluindo com ou sem milissegundos) e a converte em praticamente qualquer outro formato.

Para chamá-lo:

$TheDateTimeIWant=convertAnyDateTome_toMyDateTime([thedateIhave],[theformatIwant]);

O envio de nulo para o formato fará com que a função retorne a data e hora no Epoch / Unix Time. Caso contrário, envie qualquer string de formato suportada por date (), bem como com ".u" por milissegundos (eu trato de milissegundos também, apesar de date () retornar zeros).

Aqui está o código:

        <?php   
        function convertAnyDateTime_toMyDateTime($dttm,$dtFormat)
        {
            if (!isset($dttm))
            {
                return "";
            }
            $timepieces = array();
            if (is_numeric($dttm))
            {
                $rettime=$dttm;
            }
            else
            {
                $rettime=strtotime($dttm);
                if (strpos($dttm,".")>0 and strpos($dttm,"-",strpos($dttm,"."))>0)
                {
                    $rettime=$rettime.substr($dttm,strpos($dttm,"."),strpos($dttm,"-",strpos($dttm,"."))-strpos($dttm,"."));
                    $timepieces[1]="";
                }
                else if (strpos($dttm,".")>0 and strpos($dttm,"-",strpos($dttm,"."))==0)
                {               
                    preg_match('/([0-9]+)([^0-9]+)/',substr($dttm,strpos($dttm,"."))." ",$timepieces);
                    $rettime=$rettime.".".$timepieces[1];
                }
            }

            if (isset($dtFormat))
            {
                // RETURN as ANY date format sent
                if (strpos($dtFormat,".u")>0)       // Deal with milliseconds
                {
                    $rettime=date($dtFormat,$rettime);              
                    $rettime=substr($rettime,0,strripos($rettime,".")+1).$timepieces[1];                
                }
                else                                // NO milliseconds wanted
                {
                    $rettime=date($dtFormat,$rettime);
                }
            }
            else
            {
                // RETURN Epoch Time (do nothing, we already built Epoch Time)          
            }
            return $rettime;    
        }
    ?>

Aqui estão alguns exemplos de chamadas - você também observará que ele lida com qualquer dado de fuso horário (embora, como mencionado acima, qualquer horário não GMT seja retornado no seu fuso horário).

        $utctime1="2018-10-30T06:10:11.2185007-07:00";
        $utctime2="2018-10-30T06:10:11.2185007";
        $utctime3="2018-10-30T06:10:11.2185007 PDT";
        $utctime4="2018-10-30T13:10:11.2185007Z";
        $utctime5="2018-10-30T13:10:11Z";
        $dttm="10/30/2018 09:10:11 AM EST";

        echo "<pre>";
        echo "<b>Epoch Time to a standard format</b><br>";
        echo "<br>Epoch Tm: 1540905011    to STD DateTime     ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011","Y-m-d H:i:s")."<hr>";
        echo "<br>Epoch Tm: 1540905011          to UTC        ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011","c");
        echo "<br>Epoch Tm: 1540905011.2185007  to UTC        ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011.2185007","c")."<hr>";
        echo "<b>Returned as Epoch Time (the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC), minus leap seconds.)";
        echo "</b><br>";
        echo "<br>UTCTime1: ".$utctime1." ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime1,null);
        echo "<br>UTCTime2: ".$utctime2."       ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime2,null);
        echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,null);
        echo "<br>UTCTime4: ".$utctime4."      ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime4,null);
        echo "<br>UTCTime5: ".$utctime5."              ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime5,null);
        echo "<br>NO MILIS: ".$dttm."        ----RESULT: ".convertAnyDateTime_toMyDateTime($dttm,null);
        echo "<hr>";
        echo "<hr>";
        echo "<b>Returned as whatever datetime format one desires</b>";
        echo "<br>UTCTime1: ".$utctime1." ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime1,"Y-m-d H:i:s")."              Y-m-d H:i:s";
        echo "<br>UTCTime2: ".$utctime2."       ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime2,"Y-m-d H:i:s.u")."      Y-m-d H:i:s.u";
        echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,"Y-m-d H:i:s.u")."      Y-m-d H:i:s.u";
        echo "<p><b>Returned as ISO8601</b>";
        echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,"c")."        ISO8601";
        echo "</pre>";

Aqui está a saída:

Epoch Tm: 1540905011                        ----RESULT: 2018-10-30 09:10:11

Epoch Tm: 1540905011          to UTC        ----RESULT: 2018-10-30T09:10:11-04:00
Epoch Tm: 1540905011.2185007  to UTC        ----RESULT: 2018-10-30T09:10:11-04:00
Returned as Epoch Time (the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC), minus leap seconds.)

UTCTime1: 2018-10-30T06:10:11.2185007-07:00 ----RESULT: 1540905011.2185007
UTCTime2: 2018-10-30T06:10:11.2185007       ----RESULT: 1540894211.2185007
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 1540905011.2185007
UTCTime4: 2018-10-30T13:10:11.2185007Z      ----RESULT: 1540905011.2185007
UTCTime5: 2018-10-30T13:10:11Z              ----RESULT: 1540905011
NO MILIS: 10/30/2018 09:10:11 AM EST        ----RESULT: 1540908611
Returned as whatever datetime format one desires
UTCTime1: 2018-10-30T06:10:11.2185007-07:00 ----RESULT: 2018-10-30 09:10:11              Y-m-d H:i:s
UTCTime2: 2018-10-30T06:10:11.2185007       ----RESULT: 2018-10-30 06:10:11.2185007      Y-m-d H:i:s.u
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 2018-10-30 09:10:11.2185007      Y-m-d H:i:s.u
Returned as ISO8601
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 2018-10-30T09:10:11-04:00        ISO8601

A única coisa que não está nesta versão é a capacidade de selecionar o fuso horário em que você deseja que o horário de retorno retorne. Originalmente, escrevi isso para alterar qualquer horário para Epoch Time; portanto, não precisava de suporte de fuso horário. É trivial adicionar isso.

Robert Mauro
fonte