Formatação de datas – Java

Ontem eu estava apanhando para fazer formatação de data no Velocity (leia o que é Velocity?) para um template e antes de implementar uma POG com vários elseif´s, pedi uma ajuda para o Chris para saber se já existia alguma classe ou função disponível para formatação de datas em texto (em número já estava funcionando).

Danger!

Antecipo que qualquer coisa relacionada a Java ainda é uma novidade para mim, escrevi este post baseado na documentação da Sun (de uma classe) mas mesmo assim caso tenha alguma bobagem no conteúdo comentem, a internet está aí para possibilidades de correção e melhoria do conteúdo! 😉

O Chris me enviou um ótimo link de referência sobre a classe SimpleDateFormat do Java (me corrijam se estiver errado), que como o nome diz é para formatação de datas.

Não acho necessário a tradução da tabela, o funcionamento é simples: ao chamar a função para formatar data você segue os padrões indicado pela primeira coluna, que irá retornar o elemento indicado pela segunda coluna.

 

Letter Date or Time Component Examples
G Era designator AD
y Year 1996; 96
M Month in year July; Jul; 07
w Week in year 27
W Week in month 2
D Day in year 189
d Day in month 10
F Day of week in month 2
E Day in week Tuesday; Tue
a Am/pm marker PM
H Hour in day (0-23) 0
k Hour in day (1-24) 24
K Hour in am/pm (0-11) 0
h Hour in am/pm (1-12) 12
m Minute in hour 30
s Second in minute 55
S Millisecond 978
z Time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone -0800

 Tabela  da classe SimpleDateFormat (site da Sun)

 

Dicas para formatação e exibição das datas

Ainda existe algumas dicas para selecionar como será exibido o resultado, por extenso, número ou texto. Segue uma explicação rápida e algumas dicas para formatar e exibir a data:

Texto

Para formatar o texto, se a letra do padrão se repetir 4 vezes ou mais, a forma completa é utilizada, caso contrário a forma abreviada é exibida (se existir).

Número

Para a formatação, o número de repetição da letra padrão (primeira coluna da tabela) indica o número mínimo de dígitos do número, as casas que "faltaram" são preenchidas com zeros.

Year (ano)

Para a formatação, 2 repetições da letra truncam o ano para 2 dígitos.

Mês

Se a letra repetir por 3 vezes ou mais é exibido como texto, caso contrário como número.

 

 

Exemplos

Acho que a formatação de data é complicada de explicar, mas com exemplos -> resultados prontos fica masi fácil, então segue uma tabelinha que utiliza os padrões SimpleDateFormat.

Date and Time Pattern Result
"yyyy.MM.dd G "at" HH:mm:ss z" 2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ""yy" Wed, Jul 4, "01
"h:mm a" 12:08 PM
"hh "o""clock" a, zzzz" 12 o"clock PM, Pacific Daylight Time
"K:mm a, z" 0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa" 02001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z" Wed, 4 Jul 2001 12:08:56 -0700
"yyMMddHHmmssZ" 010704120856-0700

 Tabela  da classe SimpleDateFormat (site da Sun)

 

É isso, espero ter ajudado! Para mais informações sobre formatação de data no Java leia a documentação completa da classe citada neste post.

Fazer um loop (foreach) no Velocity, com array ou limite numérico

O Chris certa vez publicou aqui um guia inicial de Velocity que ensina os conceitos básicos dessa linguagem para desenvolvimento de templates com objetos Java.

Quando li o post não entendi patavinas, hoje trabalhando com o Chris aqui na MMCafé estou um pouco mais familiarizado com o Velocity, por isso resolvi publicar aqui algumas soluções que estão facilitando minha vida! 😀

Como fazer um loop no velocity com array

Primeiro o básico, listar os itens de um array:

#set ($arr= ["flush", "straight", "full house"])
#foreach($item in $arr)
  Mão no poker: $item
#end

Como fazer um loop no velocity com limite numérico

Agora o que achei que seria mais simples, mas demorei um pouco mais para encontrar em posts e documentações pela interwebs, como fazer um loop de N até 3N por exemplo:

#foreach($i in [3..9])
   <li>$i</li>
#end

 

Pronto, simples assim! Espero ter ajudado quem está começando com o Velocity!

Em tempo, vejam essa programação mágica (POG de primeira) que o Chris publicou lá no blog dele.

Velocity – linguagem de templates

Quando comecei a trabalhar na empresa em que estou até hoje, 4 anos atrás, fui "jogado" no mundo de aplicações java para web. Antes, só tinha mexido de verdade com PHP. E de cara comecei a mexer com o que, hoje em dia, é muito comum: templates.

Existem inúmeras opções de frameworks que usam templates, para as mais variadas linguagens (inclusive foi lançado um, em PHP, que parece ser bem bacana, o Spaghetti).
Em java, muito se usa JSP. Mas nem de longe são os mais bacanas: se você quer implementar uma aplicação MVC mesmo, deve usar o JSTL ou Velocity.

E Velocity é com o que eu trabalho atualmente. Ela é ótima para uma aplicação de grande porte, que usa MVC: você escreve seu XHTML normalmente e, depois, utiliza os objetos que a camada de negócios te dá. Ou seja, você coloca apenas lógica de interface na interface. E a lógica de negócios fica na camada de negócios. E não tem como misturar uma coisa com a outra (ok, até tem, mas vai dar tanto trabalho e é tão mais difícil de fazer isso quando comparado com JSP, que desestimula qualquer POG…).

Vamos falar um pouco, então, dele:




Velocity

Conceito

É um engine baseado em java para a construção de templates. Um template velocity é um documento que permite a escrita de html com a inserção de lógica usando objetos do Java na sua inteligência, aplicando o conceito de MVC para separar a camada de negócios da camada de apresentação.

Tipos

Sendo baseado em Java, o código Velocity tem os mesmos tipos de objetos do Java, e podem ser usados todos os métodos dos objetos Java. Objetos são sempre chamados através do identificador $
Por exemplo:
$nome ou $quantidade
Para definir um valor a um objeto, é usada a diretiva #set(
objeto = valor)
Não é necessário definir o tipo do objeto. O engine do Velocity se encarrega de definir a qual tipo ele pertence.
Por exemplo: #set($nome = "Eduardo") ou #set($quantidade = 5)

Arrays

Para criar um array – um objeto que contêm uma lista de outros objetos, há duas formas:
#set($meu_array = ["a", "b", "c", "d", "e"]) ##instancia-se o objeto e já passa o valor a ele
ou

#set($meu_array = []) ##instancia um objeto e cria uma lista vazia
##adiciona item a item os objetos da lista, usando o método add() da classe Array
#set($foo = $meu_array.add("a"))
#set($foo = $meu_array.add("b"))
#set($foo = $meu_array.add("c"))
#set($foo = $meu_array.add("d"))
#set($foo = $meu_array.add("e"))
##como o método add() tem um valor de retorno, jogamos o valor do método em uma variável qualquer, $foo, para que esse valor não seja printado na tela

Tomada de decisão

Há um tipo de estrutura de decisão no Velocity, que é definida pela seguinte sintaxe:
#if(condição)

#elseif(condição)

#else

#end

Nesse caso, apenas a diretiva #if(condição) e #end são obrigatórios; as demais ficam por conta da necessidade da implementação. A lógica é a mesma de qualquer estrutura de outras linguagens. Segue um exemplo completo:
#if($c<5)
##só entra quando $c for menor do que cinco
#elseif($c==5)
##só entra quando $c for igual a c
#else
##entre nos demais casos
#end

Laço de repetição

Há um tipo de estrutura para laço de peteição no Velocity – ou seja, como percorrer um Array (lista), que é definida pela seguinte sintaxe:
#foreach($iter in $lista)

#end

Usando aquele Array criado no item Arrays, segue um exemplo completo da utilização:
#set($meu_array = ["a", "b", "c", "d", "e"])
#foreach($letra in $meu_array)
$letra ##printa na tela a letra
#end

É possível também criar uma repetição de n vezes. Por exemplo, no código abaixo serão feitas 3 iterações (de 1 até 3):
#foreach($c in [1..3])
$c
#end

Macro
Uma macro pode ter seu conceito simplificado para
função carregada em memória. Deve ser utilizada quando um trecho de código é repetido várias vezes em diversos locais do seu código. Por ser carregada em memória e não interpretada em tempo de execução, a performance é maior.
A sintaxe para criação e posterior acesso a ela segue o seguinte padrão:
#macro(meu_nome $param1 $param2 .. $paramn)
##lógica da macro
#end
##chama a macro
#meu_nome($p1 $p2 .. $pn)

Vale ressaltar que n é a quantidade de parâmetros que a macro recebe. Se ela não receber nenhum, é chamada a macro com os parênteses em branco.

Referência: User Guide

 

Como matar o dragão e salvar a princesa – pelos programador

Certa vem um dragão aprisionou um alinda princesa em uma torre em uma ilha, a única forma de se acessar esta ilha era atravez de uma ponte na qual o dragão ficava dia e noite de vigia, então lá vão nossos "heróis" da informática salvar a princesa, cada uma sua maneira:

Programador Java
Chega, encontra o dragão. Desenvolve um framework para aniquilamento de dragões em múltiplas camadas. Escreve vários artigos sobre o framework, mas não mata o dragão.

Programador .NET
Chega, olha a ideia do Javanês e a copia, tenta matar o dragão, mas é comido pelo réptil.

Programador C
Chega, olha para o dragão com olhar de desprezo, puxa seu canivete, minúsculo extremamente leve e simples degola o dragão. Encontra a princesa, mas a ignora para ver os últimos checkins no cvs do kernel do linux.

Programador C++
Cria um canivete básico e vai juntando funcionalidades até ter uma espada complexa avassaladora, mas que apenas ele consegue entender … Mata o dragão, mas trava no meio da ponte por causa dos memory leaks.

Programador COBOL
Chega,olha o dragão, pensa que tá velho demais para conseguir matar um bicho daquele tamanho e pegar a princesa e, então, vai embora de volta ao seu mundinho.

Programador Pascal
Se prepara durante 10 anos para criar um sistema de aniquilamento de dragão… Chegando lá descobre que o programa só aceita lagartixas no máximo médias como entrada.

Programador VB
Monta uma arma de destruição de dragões a partir de vários componentes, parte pro pau pra cima do dragão e, na hora H, descobre que a espada só funciona durante noites chuvosas, e deve ser reiniciada a cada golpe para voltar a funcionar, só não sabe o pq disso…

Programador PL/SQL
Coleta dados de outros matadores de dragão, cria tabelas com N relacionamentos de complexidade ternaria, dados em 3 dimensões, OLAP, demora 15 anos para processar a informação. Enquanto isso a princesa virou lésbica.

Programador Ruby
Chega com uma p*t* fama, falando que é o melhor faz tudo, quando vai enfrentar o dragão ao invés de ir pros finalmente, mostra um videozinho dele matando um dragao … O dragão come ele de tédio.

Programador Smalltalk
chega, analisa o dragão e a princesa, vira as costas e vai embora, pois eles são muito inferiores.

Programador shell
cria uma arma poderosa para matar os dragões, mas, na hora H, não se lembra como usá-la.

Programador shell(2)
o cara chega no dragão com um script de 2 linhas que mata, corta, estripa, empala, pica em pedacinhos e empalha o bicho, mas na hora que ele roda, o script aumenta, engorda, enfurece e coloca álcool no fogo do dragão.

Programador ASSEMBLY
acha que está fazendo o mais certo e enxuto, porém troca um A por D, mata a princesa e transa com o dragão.

Programador Fortran
Chega desenvolve uma solução com 45000 linhas de codigo, mata o dragão vai ao encontro da princesa … mas esta o chama de tiuzinho e sai correndo atrás do programador java que era elegante e ficou rico.

Programador FOX PRO
Desenvolve um sistema para matar o dragão, por fora é bunitinho e funciona, mas por dentro está tudo remendado. Quando ele vai executar o aniquilador de dragões descobre que esqueceu de indexar os DBF´s.

Programador CLIPPER
Monta uma rotina que carrega um array de codeblocks para insultar o dragão, cantar a princesa, carregar a espada para memória, moer o dragão, limpar a sujeira, lascar leite condensado com morangos na princesa gostosa, transar com a princesa, tomar banho, ligar o carro, colocar gasolina e voltar pra casa. Na hora de rodar recebe um "Bound Error: Array Access" e o dragão come ele com farinha.

 

*texto retirado dessa comunidade do Orkut

A variável "Mochileiro das Galáxias" no javascript

O termo é novo, mas o conceito é antigo. Sabe aquela variável que você cria no javascript, global, que você acessa em qualquer função, em qualquer js? Eis o seu mochileiro da galáxia!

O conceito é simples, e foi batizado por autores de livros sobre Java usando o famoso livro Guia do Mochileiro da Galáxia; no livro, o protagonista descobre que seu melhor amigo é um extraterrestre e logo após, a Terra é destruída; a partir daí, começa uma grande viagem por várias galáxias. Na programação Java, é comum ver desenvolvedores criarem objetos (esqueça o conceito de variável por enquanto) que viajam entre diversas camadas da aplicação, funcionando como faz-tudo, passando por cima de qualquer escopo e, muitas vezes, tornando impossível descobrir quem está realmente alterando o quê no seu programa.
* a primeira vez que vi esse termo foi num artigo da revista Mundo Java, exposto em partes aqui.

 Agora, imagine: se em Java que a orientação a objetos é algo inerente ao desenvolvimento, imagine a dor-de-cabeça que tais variáveis (podem ser objetos também) podem causar no javascript, onde o desenvolvedor pode simplesmente implementar da forma que quiser – e, tenham certeza, a forma mais rápida é sempre aquela que dá mais brecha para problemas bizarros.
E digo isso por experiência própria: quantas vezes eu não criei uma variável global no javascript, e meses depois ia lá implementar (ou alguém da equipe ia pegar meu código) algo e do nada coisas começavam a quebrar… até descobrir que eu havia criado 2 variáveis globais!!!

Certamente a orientação a objetos ajuda -e muito – a diminuir essa questão. Para quem desenvolve e acha pataquada, dê um passo atrás e procure pelos benefícios da mesma. Existe claro a curva de aprendizado, há novos paradigmas para quem vêm da programação estruturada, é mais complexa, mas vale a pena a longo prazo.
Ao mesmo tempo, orientação a objetos não é tudo. Se fosse, implementações em Java não teriam tal problema.

Aqui vão algumas sugestões (e que podem valer para outras linguagens):

  • usar o mínimo possível de variáveis globais
  • dar nomes que façam sentido às suas variáveis, isso diminui o problema de você criar uma variável global com nomes iguais (como javascript é interpretado e não compilado, não existe uma verificação de variáveis sendo instanciadas com o mesmo nome, o que não ocorre no primeiro caso)
  • sempre que for criar uma variável, usar a diretiva var. Por exemplo, quando for num laço for usar um contador, fazer:
        for(var i=0; i<array.length; i++)
    

    Porque? Assim você garante que sua variável i comece sempre com o valor igual a 0 (vai por mim, já passei por muitos perrengues por ter variáveis em contadores não inicializadas)

  • documentar as funções/classes – o que elas fazem, quais e de onde vêm os parâmetros utilizados, etc…; isso ajuda muito você a, no futuro, entender porque aquela variável global está fazendo ali e de onde ela veio.
  • nunca, jamais nessa vida, utilizar variáveis globais em retornos de métodos ajax. Porque? Eles são assíncronos. Logo, você pode acessar uma variável que está com um valor qualquer num momento, assumir que está correta, e o valor mudar no instante seguinte – levando você a loucura sem entender porque o fluxo esperado não é seguido. E, denovo, vão por mim: já tive dores de cabeça com isso :-/

 

*se alguém tiver outras sugestões, por favor, enviem 🙂

E eu não estou aqui querendo dizer "não usem variáveis globais"; até porque eu sei o quão difícil é em muitos momentos desenvolver em javascript, devido às suas limitações. A idéia é apenas usar com cuidado 🙂