{"id":398,"date":"2021-11-16T02:49:48","date_gmt":"2021-11-16T02:49:48","guid":{"rendered":"http:\/\/jplatz.com.br\/syntax\/?p=398"},"modified":"2021-11-16T03:23:31","modified_gmt":"2021-11-16T03:23:31","slug":"php-criando-datetime-com-construtor-sem-mascaras-de-formatacao","status":"publish","type":"post","link":"https:\/\/jplatz.com.br\/syntax\/2021\/11\/16\/php-criando-datetime-com-construtor-sem-mascaras-de-formatacao\/","title":{"rendered":"PHP Criando DateTime com Construtor  sem M\u00e1scaras de Formata\u00e7\u00e3o"},"content":{"rendered":"\n<pre class=\"wp-block-preformatted\">$string_date = '2010-08-07 08:39:00';\n[$y, $m, $d] = [null, null, null];\n\nswitch(true) {\n  case preg_match('\/^(\\d{4})-(\\d{2})-(\\d{2})\/', $string_date, $fragments):\n    list($y, $m, $d) = [$fragments[1], $fragments[2], $fragments[3]];\n    break;\n  case preg_match('\/^(\\d{4})\\\/(\\d{2})\\\/(\\d{2})\/', $string_date, $fragments):\n    list($y, $m, $d) = [$fragments[1], $fragments[2], $fragments[3]];\n    break;\n  case preg_match('\/^(\\d{2})-(\\d{2})-(\\d{4})\/', $string_date, $fragments):\n    list($d, $m, $y) = [$fragments[1], $fragments[2], $fragments[3]];\n    break;\n  case preg_match('\/^(\\d{2})\\\/(\\d{2})\\\/(\\d{4})\/', $string_date, $fragments):\n    list($m, $d, $y) = [$fragments[1], $fragments[2], $fragments[3]];\n    break;\n  default:\n    throw new Exception('String Date supplied with unknown format');\n}\n\nif (!checkdate($m, $d, $y)) {\n  throw new Exception ('String Date supplied with invalid date content');\n}\n\ntry {\n  $object_datetime = new DateTime($string_date);\n} catch (\\Exception $exception) {\n  echo 'String Date supplied impossible to convert to Date';\n  $object_datetime = null;\n}\n\nnull !== $object_date\n  ? $object_date->setTime(0,0)\n  ; null;\n\nvar_dump($object_datetime);<\/pre>\n\n\n\n<p>Pessoal, este c\u00f3digo surgiu da necessidade de se converter um campo de data fornecido como <strong>string<\/strong> numa integra\u00e7\u00e3o entre sistemas.<\/p>\n\n\n\n<p>O fato \u00e9 que quando se depende de informa\u00e7\u00f5es externas o processo pode facilmente quebrar quando as regras estabelecidas n\u00e3o forem estritamente respeitadas.<\/p>\n\n\n\n<p>No meu caso um campo que deveria ser enviado no formato date <strong>Y-m-d<\/strong> acabou sendo enviado num formato <strong>DateTime Y-m-d H:i:<em>s<\/em><\/strong><em>.<\/em> O problema se agravou pelo fato de que apenas um dos fornecedores acabou enviando desta forma e os demais fornecedores enviavam a informa\u00e7\u00e3o no formato acordado.<\/p>\n\n\n\n<p>D\u00favida cruel&#8230; solicitar ao fornecedor para corrigir o envio da informa\u00e7\u00e3o? Ou flexibilizar a entrada do dados de forma inteligente?<\/p>\n\n\n\n<p>Op\u00e7\u00e3o dois na veia! O fato \u00e9 que todos os fornecedores continuavam enviando uma data v\u00e1lida pra n\u00f3s, s\u00f3 que com formatos ou m\u00e1scaras diferentes, mas ainda assim eram datas v\u00e1lidas.<\/p>\n\n\n\n<p>Baseado neste preceito a solu\u00e7\u00e3o foi substituir a cria\u00e7\u00e3o do objeto <strong>DateTime<\/strong> calcada no <strong>createFromFormat<\/strong> a partir de m\u00e1scaras previamente conhecidas por simplesmente passar a <strong>string date<\/strong> recebida para o construtor do <strong>DateTime<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ stop creating date based on known format, this will fail when datetime content is sent\n$object_datetime = DateTime::createFromFormat('Y-m-d', $string_date);\n\n\/\/ start creating datetime based on constructor, this will work with any valid date\/time content\n$object_datetime = new DateTime($string_date);<\/pre>\n\n\n\n<p>A grande sacada consiste em validar se uma data v\u00e1lida foi enviada, no caso fazemos esta valida\u00e7\u00e3o para a por\u00e7\u00e3o <strong>Y-m-d<\/strong> somente. Se a valida\u00e7\u00e3o passar neste n\u00edvel a probabilidade da informa\u00e7\u00e3o ser uma data v\u00e1lida inclusive na sua por\u00e7\u00e3o hora ser\u00e1 muito grande.<\/p>\n\n\n\n<p>Para exemplificar a flexibilidade de entrada desta informa\u00e7\u00e3o, segue abaixo alguns exemplos de formatos v\u00e1lidos que ir\u00e3o funcionar com o construtor.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$object_datetime = new DateTime('2010-08');\nvar_dump($object_datetime); \/\/2010-08-01 00:00:00.000000\n<meta charset=\"utf-8\">\n<meta charset=\"utf-8\">$object_datetime = new DateTime('2010-08 08:39');\n<meta charset=\"utf-8\">var_dump($object_datetime); \/\/2010-08-01 08:39:00.000000\n<meta charset=\"utf-8\"><meta charset=\"utf-8\">\n$object_datetime = new DateTime('2010-08 08:39:53');\n<meta charset=\"utf-8\">var_dump($object_datetime); \/\/2010-08-01 08:39:53.000000\n\n<meta charset=\"utf-8\">$object_datetime = new DateTime('2010-08T08:39:53Z');\n<meta charset=\"utf-8\">var_dump($object_datetime); \/\/2010-08-01 08:39:53.000000\n\n<meta charset=\"utf-8\"><meta charset=\"utf-8\">$object_datetime = new DateTime('2010-08-07');\n<meta charset=\"utf-8\">var_dump($object_datetime); \/\/2010-08-07 00:00:00.000000\n<meta charset=\"utf-8\"><meta charset=\"utf-8\"><meta charset=\"utf-8\">\n$object_datetime = new DateTime('2010-08-07 08:39');\n<meta charset=\"utf-8\">var_dump($object_datetime); \/\/2010-08-07 08:39:00.000000\n<meta charset=\"utf-8\">\n$object_datetime = new DateTime('2010-08-07 08:39:53');\n<meta charset=\"utf-8\">var_dump($object_datetime); \/\/2010-08-07 08:39:53.000000\n\n<meta charset=\"utf-8\">$object_datetime = new DateTime('2010-08-07T08:39:53Z');\n<meta charset=\"utf-8\">var_dump($object_datetime); \/\/2010-08-07 08:39:53.000000<\/pre>\n\n\n\n<p>Considere ainda que podemos receber barras ao inv\u00e9s de h\u00edfen como separador que ir\u00e1 funcionar corretamente com todas as varia\u00e7\u00f5es acima apresentadas.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$object_datetime = new DateTime('2010\/08\/07 08:39:53');\nvar_dump($object_datetime); \/\/2010-08-07 08:39:53.000000\n\n<meta charset=\"utf-8\">$object_datetime = new DateTime('2010\/08\/07T08:39:53Z');\nvar_dump($object_datetime); \/\/2010-08-07 08:39:53.000000<\/pre>\n\n\n\n<p>Outra grande vantagem de se utilizar o construtor do <strong>DateTime<\/strong> \u00e9 que ele vai funcionar com o formato nativo americano <strong>m\/d\/Y<\/strong> quando separado por barras e com o formato nativo brit\u00e2nico <strong>m-d-Y<\/strong> quando separado por h\u00edfens. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$object_datetime = new DateTime('08\/07\/2010 08:39:53');\nvar_dump($object_datetime); \/\/2010-08-07 08:39:53.000000\n\n$object_datetime = new DateTime('07-08-2010 08:39:53');\nvar_dump($object_datetime); \/\/2010-08-07 08:39:53.000000<\/pre>\n\n\n\n<p>Lembrando que em nenhum momento tivemos que informar m\u00e1scaras de formata\u00e7\u00e3o para efetivamente criar o objeto <strong>DateTime<\/strong>. Simplesmente mandamos a string date para o construtor e pronto.<\/p>\n\n\n\n<p>E caso a informa\u00e7\u00e3o final deva ser uma data sem a por\u00e7\u00e3o hora, simplesmente zeramos esta por\u00e7\u00e3o depois do objeto criado, assim:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><meta charset=\"utf-8\"><meta charset=\"utf-8\">$object_datetime = new DateTime('08\/07\/2010 08:39:53');\nvar_dump($object_datetime); \/\/2010-08-07 08:39:53.000000\n\n<meta charset=\"utf-8\">$object_datetime-&gt;setTime(0,0);\nvar_dump($object_datetime); \/\/2010-08-07 00:00:00.000000\n<\/pre>\n\n\n\n<p>Depois desta demonstra\u00e7\u00e3o de flexibilidade de formatos acredito que as vantagens de cria\u00e7\u00e3o do <strong>DateTime<\/strong> utilizando o construtor tenham ficado claras.<\/p>\n\n\n\n<p>E \u00e9 claro que o c\u00f3digo do in\u00edcio do artigo merece um refactoring para ser mais <strong>CleanCode<\/strong> e tamb\u00e9m para suportar os demais formatos aceitos pelo construtor do <strong>DateTime<\/strong>, mas para fins did\u00e1ticos preferi mant\u00ea-lo mais simples mesmo.<\/p>\n\n\n\n<p>E agora? Troca ou n\u00e3o troca o <strong>DateTime::createFromFormat<\/strong> pelo <strong>new DateTime constructor<\/strong>? Voc\u00ea decide&#8230;<\/p>\n\n\n\n<p>Happy code!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>$string_date = &#8216;2010-08-07 08:39:00&#8217;; [$y, $m, $d] = [null, null, null]; switch(true) { case preg_match(&#8216;\/^(\\d{4})-(\\d{2})-(\\d{2})\/&#8217;, $string_date, $fragments): list($y, $m, $d) = [$fragments[1], $fragments[2], $fragments[3]]; break; case preg_match(&#8216;\/^(\\d{4})\\\/(\\d{2})\\\/(\\d{2})\/&#8217;, $string_date, $fragments): list($y, $m, $d) = [$fragments[1], $fragments[2], $fragments[3]]; break; case preg_match(&#8216;\/^(\\d{2})-(\\d{2})-(\\d{4})\/&#8217;, $string_date, $fragments): list($d, $m, $y) = [$fragments[1], $fragments[2], $fragments[3]]; break; case preg_match(&#8216;\/^(\\d{2})\\\/(\\d{2})\\\/(\\d{4})\/&#8217;, $string_date, $fragments): list($m, $d, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,2,3],"tags":[75,177,77,178],"class_list":["post-398","post","type-post","status-publish","format-standard","hentry","category-backend","category-coding","category-php","tag-datetime","tag-datetime-constructor","tag-datetimecreatefromformat","tag-new-datetime"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/posts\/398","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/comments?post=398"}],"version-history":[{"count":4,"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/posts\/398\/revisions"}],"predecessor-version":[{"id":405,"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/posts\/398\/revisions\/405"}],"wp:attachment":[{"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/media?parent=398"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/categories?post=398"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jplatz.com.br\/syntax\/wp-json\/wp\/v2\/tags?post=398"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}