Friday, January 13, 2006
Escrevendo (código) Demais
Resolvi escrever esta nota, não para criticar os desenvolvedores que gostam de codificar de tudo, mas alertar que quanto mais simples e comentado deixamos o código, melhor será nossa vida no futuro - e tomando emprestado o ditado: "quem fala demais dá bom-dia a cavalo", escrever código desnecessariamente também não é uma boa idéia.
Dias atrás, estava navegando através dos forums e me deparei com uma dúvida relacionada ao código abaixo. Não me lembro da dúvida, porque a primeira coisa que eu faço quando leio uma, é otimizar a semântica, não a sintaxe, portanto tento entender o que a pessoa pretende, para ajudá-la.
Neste caso, nosso herói queria escrever uma função para converter data Gregoriana em data Juliana (número de dias desde as 12:00 de 1 de janeiro de 4713 aC). Ora, de primeira minha resposta foi: por que está codificando algo que já existe? Se o TO_CHAR( date, 'J' ) faz isso! Mas o pior foi constatar que a função estava errada!
Me Mostra?
No código, eu retirei os comentários para evitar identificação. Não estou preocupado em apontar o dedo à ninguém e sim alertar para: primeiro procurar esgotar as possibilidades que o built-in oferece. Além de já estar pronto e testado, preserva o código como legado em migrações futuras.
Eis a função.
Substituindo agora para reverter de juliana para gregoriana. Aqui é a prova dos nove.
Agora sim, podemos ver nitidamente que o valor obtido pela função TO_JULIANA (vermelho) não está nem de perto correto. Neste caso, a função seria:
Dias atrás, estava navegando através dos forums e me deparei com uma dúvida relacionada ao código abaixo. Não me lembro da dúvida, porque a primeira coisa que eu faço quando leio uma, é otimizar a semântica, não a sintaxe, portanto tento entender o que a pessoa pretende, para ajudá-la.
Neste caso, nosso herói queria escrever uma função para converter data Gregoriana em data Juliana (número de dias desde as 12:00 de 1 de janeiro de 4713 aC). Ora, de primeira minha resposta foi: por que está codificando algo que já existe? Se o TO_CHAR( date, 'J' ) faz isso! Mas o pior foi constatar que a função estava errada!
Me Mostra?
No código, eu retirei os comentários para evitar identificação. Não estou preocupado em apontar o dedo à ninguém e sim alertar para: primeiro procurar esgotar as possibilidades que o built-in oferece. Além de já estar pronto e testado, preserva o código como legado em migrações futuras.
Eis a função.
CREATE OR REPLACE Function to_juliana (dt_a_converter DATE )
RETURN NUMBER IS
dt_juliana NUMBER;
BEGIN
/* ------ -- ------- -- --------- ---- ---- ------- */
dt_juliana := 0;
dt_juliana := To_Char( TO_DATE( dt_a_converter ) , 'YYYYDDD') - 1900000 ;
/* ---------- - ------- -- ------ */
RETURN( dt_juliana );
END To_Juliana;
/
ops$marcio@LNX10GR2>
ops$marcio@LNX10GR2> CREATE OR REPLACE Function to_juliana (dt_a_converter DATE )
2 RETURN NUMBER IS
3 dt_juliana NUMBER;
4
5 BEGIN
6 /* ------ -- ------- -- --------- ---- ---- ------- */
7
8 dt_juliana := 0;
9 dt_juliana := To_Char( TO_DATE( dt_a_converter ) , 'YYYYDDD') - 1900000 ;
10
11 /* ---------- - ------- -- ------ */
12 RETURN( dt_juliana );
13 END To_Juliana;
14 /
Function created.
ops$marcio@LNX10GR2> select to_juliana(sysdate) x,
2 to_number(to_char(sysdate, 'j')) y
3 from dual
4 /
X Y
------------- -------------
106013 2453749
1 row selected.
Substituindo agora para reverter de juliana para gregoriana. Aqui é a prova dos nove.
ops$marcio@LNX10GR2> select to_date( 106013, 'j') feito,
2 to_date( 2453749, 'j') builtin
3 from dual
4 /
FEITO BUILTIN
------------------- -------------------
01/04/4422 00:00:00 13/01/2006 00:00:00
1 row selected.
Agora sim, podemos ver nitidamente que o valor obtido pela função TO_JULIANA (vermelho) não está nem de perto correto. Neste caso, a função seria:
create or replace
function to_juliana ( p_date in date ) return number
is
begin
return to_number(to_char(p_date, 'j'));
end;
/
ops$marcio@LNX10GR2> select to_juliana( sysdate ) from dual;
TO_JULIANA(SYSDATE)
-------------------
2453749
1 row selected.
ops$marcio@LNX10GR2> select to_date( 2453749, 'j' ) from dual;
TO_DATE(2453749,'J'
-------------------
13/01/2006 00:00:00
1 row selected.
Comments:
<< Home
a função to_juliana nunca poderia estar coreta, já que o ano tem 365 dias. usando a mascara 'yyyyddd' nunca teriamos por exemplo uma data "juliana" com os 3 ultimos algarismos terminando com um numero entre 366 e 999.
O problema é que a função to_juliana existiu e estava em um forum onde participo. Quis mostrar exatamente isso: que além de não haver necessidade da codificação, o código está errado.
Post a Comment
<< Home