Colegas, sorry mas em 99,99% das vezes, quando eu vejo funções tipo 'calcula
bissexto', 'adiciona_dias', ou quetais são Puro desperdício, pois o bd Oracle
já faz adição / subtração de dias E faz o cálculo de meses já levando em
consideração anos bissextos e TUDO O MAIS - coincidentemente há algumas semas
dei um Treinamento zás-trás de PL/SQL (assumi uma turma temporária,num cursinho
de dias, na verdade) prum pessoal que não trabalhava com Oracle, foi uma
novidade Total isso pra eles, pois é uma característica que não é comum em
outros BDs... E já que NECESSARIAMENTE SEMPRE temos 12 meses no ano,
rigorosamente não há necessidade Alguma de funções, diferença se faz
diretamente, assumindo 12 meses ao ano, tipo assim :
sc...@o10gr2:SQL>l
1 DECLARE
2 v_start_date date := to_date('&dia_mes_ano_ini', 'dd/mm/yyyy');
3 v_end_date date := to_date('&dia_mes_ano_fim', 'dd/mm/yyyy');
4 BEGIN
5 dbms_output.put_line( 'anos=' || trunc(months_between(v_end_date,
v_start_date) / 12) ||
6 ',meses=' || trunc(mod(months_between(v_end_date,
v_start_date), 12)) ||
7 ',dias=' || trunc(v_end_date -
add_months(v_start_date, trunc(months_between(v_end_date, v_start_date))))
8 );
9* END;
==> vejamos uns exemplos :
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 20/11/2009
Informe o valor para dia_mes_ano_fim: 20/11/2009
anos=0,meses=0,dias=0
=> ok, pegou o caso de sem diferença, agora vamos bottar uns anos (E VEJA que
teve bissextos no intervalo, não terá prob algum ) :
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 20/02/2000
Informe o valor para dia_mes_ano_fim: 28/02/2009
anos=9,meses=0,dias=8
==> agora pegando séculos diferentes :
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 10/01/1998
Informe o valor para dia_mes_ano_fim: 31/03/2009
anos=11,meses=2,dias=21
==> agora pegando mais de cem anos, ie, vários séculos no intervalo, mas com
números redondos sempre pra ficar fácil de conferir :
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 01/01/1800
Informe o valor para dia_mes_ano_fim: 31/12/2130
anos=330,meses=11,dias=30
==> finalmente, um caso de número do dia de início e/ou mês maior que o dia/mês
final, que não tinha tido :
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 30/12/2005
Informe o valor para dia_mes_ano_fim: 15/08/2009
anos=3,meses=7,dias =16
==> no exemplo acima, SE vc fizesse a contragem simples , de 2005 até 2009
daria 04, e de dezembro (Mês 12, o final) até o mês 08 daria 8 meses, ** MAS **
é esse o correto, quando não completou anos/meses extaos se quer a fração nesse
caso - a rotina reconheceu que NÃO chegou a completar 4 anos nem 8 meses, yes
??? Veja o que acontece se eu "completar" os 16 dias que ficaram de fração :
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 30/12/2005
Informe o valor para dia_mes_ano_fim: 31/08/2009
anos=3,meses=8,dias =1
==> Belezinha, a rotina ** reconheceu ** certinho que o mês fechou, ** mas **
como o Mês de Agosto tem 31 dias tá lá o dia extra da fração .... Vamos
completar o ano, com e sem o dia extra que Dezembro tem ???
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 30/12/2005
Informe o valor para dia_mes_ano_fim: 31/12/2009
anos=4,meses=0,dias =1
e...
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 30/12/2005
Informe o valor para dia_mes_ano_fim: 30/12/2009
anos=4,meses=0,dias =0
Procedimento PL/SQL concluído com sucesso.
==>> TAÍ, reconheceu CERTINHO quando foi o número exato de anos e/ou meses, a
fração (se houve) foi pra Dias...Veja o que acontece se eu não completar o Mês :
sc...@o10gr2:SQL>/
Informe o valor para dia_mes_ano_ini: 30/12/2005
Informe o valor para dia_mes_ano_fim: 25/12/2009
anos=3,meses=11,dias =25
==> Certinho, ela reconhecu que havia menos de 4 anos, a 'sobra' era de 3 anos
, 11 meses e 25 dias... Legal ?? Veja que a ÚNICA exigência é que realmente a
data inicial seja MESMO menor que a data final, pois a contagem será feita A
partir dela, ok ? Creio que sem probs, pela definição do colega q fez a
pergunta....
[]s
Chiappa
--- Em [email protected], Elis Azevedo Nery <elisn...@...> escreveu
>
> Aí vai um código tirado da net:
> CREATE OR REPLACE FUNCTION BISSEXTO (VANO IN NUMBER) RETURN BOOLEAN
> IS
> VRESTO1 NUMBER(5,2);
> VRESTO2 NUMBER(5,2);
> VRESTO3 NUMBER(5,2);
> BEGIN
> VRESTO1 := MOD(VANO,4);
> VRESTO2 := MOD(VANO,100);
> VRESTO3 := MOD(VANO,400);
>
> IF ((VRESTO1 = 0 AND VRESTO2 <> 0 ) OR VRESTO3 = 0) THEN
> DBMS_OUTPUT.PUT_LINE(VANO || ' É UM ANO BISSEXTO');
> RETURN TRUE;
> ELSE
> DBMS_OUTPUT.PUT_LINE (VANO || ' NÃO É UM ANO BISSEXTO');
> RETURN FALSE;
> END IF;
>
>
> Abraço
> Elis
>
>
>
>
> ________________________________
> De: grimaldol_lopes <grimaldo_lo...@...>
> Para: [email protected]
> Enviadas: Sexta-feira, 20 de Novembro de 2009 18:54:17
> Assunto: [oracle_br] Re: Calculo de datas - Ano Mes e Dia
>
>
>
> Dougla , meu amigo, obrigado pela ajuda, mas o problema é que o calculo deve
> envolver os anos bissextos, este é o problema, como você havia feito eu
> realemnte tinha aqui comigo, mas o cliente quer com os bissextos, e ai,
> alguma dica?, Obrigado.
>
> --- Em oracle...@yahoogrup os.com.br, Douglas Falcão <listas.dfalcao@ ...>
> escreveu
> >
> > Grimaldo..
> >
> > sabendo que Data2 - Data1 = diferenca_em_ dias, bastam alguns cálculos sobre
> > esse número para que chegue onde quer
> >
> > Ex.:
> >
> > SQL> select sysdate from dual;
> > SYSDATE
> > --------
> > 20/11/09
> > SQL> select sysdate - to_date('10/ 03/1981', 'dd/mm/yyyy' ) from dual;
> > SYSDATE-TO_DATE( '10/03/1981' ,'DD/MM/YYYY' )
> > ------------ --------- --------- --------- ---
> > 10482,5882
> >
> > PARA CACULAR o ANO:
> >
> > SQL> select 10482.5882 /365 from dual;
> > ----------
> > 28,7194197
> >
> > SQL> select trunc(10482. 5882 /365) anos from dual;
> > ANOS
> > ----------
> > 28
> >
> > PARA CALCULAR OS MESES
> >
> > SQL> select 12 * 0.7194197 from dual;
> > 12*0.7194197
> > ------------
> > 8,6330364
> > SQL> select trunc(12 * 0.7194197) meses from dual;
> >
> > MESES
> > ----------
> > 8
> >
> > Segue o mesmo raciocínio para a quantidade de dias, horas, minutos, sempre
> > trablahando com a parte decimal.
> >
> >
> > DICA: Coloca essa encrenca de forma procedural e cria uma função que retorne
> > o que tu quiser cfe. parâmetros.
> >
> >
> > Att.
> >
> > Douglas Falcão.
> >
> >
> > 2009/11/20 Grimaldo Lopes <grimaldo_lopes@ ...>
> >
> > >
> > >
> > >
> > >
> > > Caros colegas, necessio de um select para que me retorne a diferença entre
> > > duas datsa em anos mes e dias.
> > >
> > > Ex: 01/01/2009
> > >
> > > 10/02/2010
> > >
> > > Resposta: 01 ano 01 mes e 09 dias
> > >
> > > Isso é possível?.
> > >
> > > Grimaldo
> > >
> > >
> > > ____________ _________ _________ _________ _________ _________ _
> > > Converse e compartilhe fotos ao mesmo tempo. Saiba como no novo Site de
> > > Windows Live.
> > > http://www.windowsl ive.com.br/ ?ocid=WindowsLiv e09_MSN_Hotmail_
> > > Tagline_out09
> > >
> > > [As partes desta mensagem que não continham texto foram removidas]
> > >
> > >
> > >
> >
> >
> >
> > --
> > Douglas Falcão
> > ------------ --------- --------- --------- --------- -------
> > Oracle Certified Application Developer
> > Sun Java Certified Associate
> > ------------ --------- --------- --------- --------- -------
> > Business Analyst / Business Intelligence Analyst
> > mail: douglas dot falcao at gmail dot com
> >
> >
> > [As partes desta mensagem que não continham texto foram removidas]
> >
>
>
>
>
>
>
> ____________________________________________________________________________________
> Veja quais são os assuntos do momento no Yahoo! +Buscados
> http://br.maisbuscados.yahoo.com
>
> [As partes desta mensagem que não continham texto foram removidas]
>