{"id":210,"date":"2015-12-15T20:02:03","date_gmt":"2015-12-15T20:02:03","guid":{"rendered":"https:\/\/sidroniolima.com.br\/blog\/?p=210"},"modified":"2015-12-15T20:02:43","modified_gmt":"2015-12-15T20:02:43","slug":"localdate-e-localdatetime-em-jsf-2-2","status":"publish","type":"post","link":"https:\/\/sidroniolima.com.br\/blog\/2015\/12\/15\/localdate-e-localdatetime-em-jsf-2-2\/","title":{"rendered":"LocalDate e LocalDateTime em JSF 2.2 e 2.3"},"content":{"rendered":"\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n<p><a href=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/tempo_122-692x360.jpg\" rel=\"attachment wp-att-212\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-212 size-full\" src=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/tempo_122-692x360.jpg\" alt=\"tempo_122-692x360\" width=\"692\" height=\"360\" srcset=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/tempo_122-692x360.jpg 692w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/tempo_122-692x360-300x156.jpg 300w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/tempo_122-692x360-620x323.jpg 620w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/><\/a><\/p>\n<p>Com a API Date-Time do Java 8 novos objetos\u00a0de representa\u00e7\u00e3o e tratamento de data e tempo foram introduzidos no cotidiano de desenvolvedores que recorriam \u00e0\u00a0implementa\u00e7\u00f5es diversas, como o\u00a0<a href=\"http:\/\/www.joda.org\/joda-time\/\" target=\"_blank\">Joda Time<\/a>.<\/p>\n<p>Como carater\u00edstica desta API pode ser destacados a facilidade na utiliza\u00e7\u00e3o o que n\u00e3o era presente nas vers\u00f5es anteriores com os objetos java.util.Date e java.sql.Date.<\/p>\n<p>Entretanto a vers\u00e3o\u00a0JSF 2.2 ainda n\u00e3o proporciona a convers\u00e3o nativa desses objetos. O que j\u00e1 incorporado na pr\u00f3xima vers\u00e3o, 2.3, programada para ser lan\u00e7ada em 2017 junto a Java EE 8.<\/p>\n<p>Assim, para utilizar os objetos LocalDate e LocalDateTime \u00e9 necess\u00e1rio criar conversores JSF e atribu\u00ed-los ao conversor da tag &lt;h:outputText&gt;. Abaixo o exemplo de utiliza\u00e7\u00e3o.<\/p>\n<p>Os converters devem implementar a interface\u00a0javax.faces.convert.Converter e ser anotados\u00a0com javax.faces.convert.FacesConverter, onde \u00e9 definido o nome (id).<\/p>\n<p><code>@FacesConverter(\"localDateTimeFacesConverter\")<br \/>\npublic class LocalDateTimeFacesConverter implements Converter {<\/code><\/p>\n<p>@Override<br \/>\npublic Object getAsObject(FacesContext context, UIComponent component, String stringValue) {<\/p>\n<p>if (null == stringValue || stringValue.isEmpty()) {<br \/>\nreturn null;<br \/>\n}<\/p>\n<p>LocalDateTime localDateTime = null;<\/p>\n<p>try {<\/p>\n<p>localDateTime = LocalDateTime.parse(<br \/>\nstringValue.trim(),<br \/>\nDateTimeFormatter.ofPattern(&#8220;dd\/MM\/yyyy hh:mm:ss&#8221;).withZone(ZoneId.systemDefault()));<\/p>\n<p>} catch (DateTimeParseException e) {<\/p>\n<p>throw new ConverterException(&#8220;O formato da data e hora deve ser 13\/11\/2015 12:00:00.&#8221;);<br \/>\n}<\/p>\n<p>return localDateTime;<\/p>\n<p>}<\/p>\n<p>@Override<br \/>\npublic String getAsString(FacesContext context, UIComponent component, Object localDateTimeValue) {<\/p>\n<p>if (null == localDateTimeValue) {<\/p>\n<p>return &#8220;&#8221;;<br \/>\n}<\/p>\n<p>return ((LocalDateTime) localDateTimeValue)<br \/>\n.format(DateTimeFormatter.ofPattern(&#8220;dd\/MM\/yyyy hh:mm:ss&#8221;)<br \/>\n.withZone(ZoneId.systemDefault()));<br \/>\n}<br \/>\n}<\/p>\n<p><code>@FacesConverter(\"localDateFacesConverter\")<br \/>\npublic class LocalDateFacesConverter implements Converter {<\/code><\/p>\n<p>@Override<br \/>\npublic Object getAsObject(FacesContext context, UIComponent component, String stringValue) {<\/p>\n<p>if (null == stringValue || stringValue.isEmpty()) {<br \/>\nreturn null;<br \/>\n}<\/p>\n<p>LocalDate localDate;<\/p>\n<p>try {<br \/>\nlocalDate = LocalDate.parse(<br \/>\nstringValue,<br \/>\nDateTimeFormatter.ofPattern(&#8220;dd\/MM\/yyyy&#8221;));<\/p>\n<p>} catch (DateTimeParseException e) {<\/p>\n<p>throw new ConverterException(&#8220;O ano deve conter 4 d\u00edgitos. Exemplo: 13\/11\/2015.&#8221;);<br \/>\n}<\/p>\n<p>return localDate;<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic String getAsString(FacesContext context, UIComponent component, Object localDateValue) {<\/p>\n<p>if (null == localDateValue) {<\/p>\n<p>return &#8220;&#8221;;<br \/>\n}<\/p>\n<p>return ((LocalDate) localDateValue).format(DateTimeFormatter.ofPattern(&#8220;dd\/MM\/yyyy&#8221;));<br \/>\n}<br \/>\n}<\/p>\n<p>Os Converters apenas fazem a convers\u00e3o do objeto para String e vice-versa, n\u00e3o h\u00e1 maiores problemas na implementa\u00e7\u00e3o. Caso o parse para o padr\u00e3o definido gere uma exce\u00e7\u00e3o esta \u00e9 lan\u00e7ada como ConverterException e exibida ao usu\u00e1rio. No entanto nos testes e em implementa\u00e7\u00f5es dessa l\u00f3gica esta mensagem n\u00e3o chega ao na view e deve ser definido o atributo converterMessage da tag &lt;h:inputText&gt;.<\/p>\n<p>&lt;code&gt;&lt;label for=&#8221;inputAdmissao&#8221;&gt;Data de admiss\u00e3o &lt;span class=&#8221;required&#8221;&gt;*&lt;\/span&gt;&lt;\/label&gt;<br \/>\n&lt;h:inputText<br \/>\nclass=&#8221;form-control input-sm m-bot15&#8243;<br \/>\nid=&#8221;inputAdmissao&#8221;<br \/>\npt:placeholder=&#8221;Admissao &#8221;<br \/>\nvalue=&#8221;#{cadastroFuncionarioBean.funcionario.dataDeAdmissao}&#8221;<br \/>\nrequired=&#8221;true&#8221;<br \/>\nrequiredMessage=&#8221;\u00c9 necess\u00e1rio informar a data de admiss\u00e3o.&#8221;<br \/>\nconverterMessage=&#8221;A data deve estar no formato dd\/MM\/aaaa&#8221;&gt;<\/p>\n<p>&lt;f:converter<br \/>\nconverterId=&#8221;localDateFacesConverter&#8221;<br \/>\nfor=&#8221;inputAdmissao&#8221;\/&gt;<\/p>\n<p>&lt;f:ajax<br \/>\nevent=&#8221;blur&#8221;<br \/>\nrender=&#8221;m_inputAdmissao&#8221; \/&gt;<\/p>\n<p>&lt;\/h:inputText&gt; &lt;\/code&gt;<\/p>\n<p><a href=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/data.png\" rel=\"attachment wp-att-225\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-225\" src=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/data.png\" alt=\"data\" width=\"368\" height=\"144\" srcset=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/data.png 368w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2015\/12\/data-300x117.png 300w\" sizes=\"auto, (max-width: 368px) 100vw, 368px\" \/><\/a><\/p>\n<p>A novidade que a vers\u00e3o do JSF 2.3 traz \u00e9 a adi\u00e7\u00e3o de type attributes para as classes\u00a0java.time.LocalDate e\u00a0java.time.LocalDateTime, respectivamente localDate e localTime. :-p<code><\/code><\/p>\n<p>&lt;code&gt;<\/p>\n<div class=\"line number1 index0 alt2\"><code class=\"xml plain\">&lt;<\/code><code class=\"xml keyword\">h:inputText<\/code> <code class=\"xml color1\">value<\/code><code class=\"xml plain\">=<\/code><code class=\"xml string\">\"#{myBean.startTime}\"<\/code><code class=\"xml plain\">&gt;<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"xml spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"xml plain\">&lt;<\/code><code class=\"xml keyword\">f:convertDateTime<\/code> <code class=\"xml color1\">type<\/code><code class=\"xml plain\">=<\/code><code class=\"xml string\">\"localDateTime\"<\/code> <code class=\"xml plain\">\/&gt;<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"xml plain\">&lt;\/<\/code><code class=\"xml keyword\">h:inputText<\/code><code class=\"xml plain\">&gt;<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"xml plain\">&lt;<\/code><code class=\"xml keyword\">h:outputText<\/code> <code class=\"xml color1\">value<\/code><code class=\"xml plain\">=<\/code><code class=\"xml string\">\"#{myBean.endDate}\"<\/code><code class=\"xml plain\">&gt;<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"xml spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"xml plain\">&lt;<\/code><code class=\"xml keyword\">f:convertDateTime<\/code> <code class=\"xml color1\">type<\/code><code class=\"xml plain\">=<\/code><code class=\"xml string\">\"localDate\"<\/code> <code class=\"xml color1\">pattern<\/code><code class=\"xml plain\">=<\/code><code class=\"xml string\">\"dd.MM.uu\"<\/code> <code class=\"xml plain\">\/&gt;<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"xml plain\">&lt;\/<\/code><code class=\"xml keyword\">h:outputText<\/code><code class=\"xml plain\">&gt;<\/code><\/div>\n<p>&lt;\/code&gt;<\/p>\n<p>\u00c9 isso. E para saber mais das novidades da nova vers\u00e3o do JSF segue esse link\u00a0<a href=\"http:\/\/arjan-tijms.omnifaces.org\/p\/jsf-23.html\" target=\"_blank\">What&#8217;s new in JSF 2.3?<\/a>.<\/p>\n\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Com a API Date-Time do Java 8 novos objetos\u00a0de representa\u00e7\u00e3o e tratamento de data e tempo foram introduzidos no cotidiano de desenvolvedores que recorriam \u00e0\u00a0implementa\u00e7\u00f5es diversas, como o\u00a0Joda Time. Como carater\u00edstica desta API pode ser destacados a facilidade na utiliza\u00e7\u00e3o o que n\u00e3o era presente nas vers\u00f5es anteriores com os objetos java.util.Date e java.sql.Date. Entretanto [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[27],"tags":[],"class_list":["post-210","post","type-post","status-publish","format-standard","hentry","category-java"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/210","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/comments?post=210"}],"version-history":[{"count":16,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/210\/revisions"}],"predecessor-version":[{"id":229,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/210\/revisions\/229"}],"wp:attachment":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/media?parent=210"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/categories?post=210"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/tags?post=210"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}