Jump to content
Carlos Rocha

testar data em dois questões

Recommended Posts

Carlos Rocha

Bom Dia Humberto.

Preciso testar dentro de um try 2 coisas:

Se uma data é valida e se ela é maior ou igual à data de hoje.

Se alguma dessas situaçoes ocorrerem avisar que a data é errada.

Mas não esta dando certo com o codigo abaixo.

Qual será o erro?

Function TfrmPrincipal.DataIdade(DataNascimento : String) : Double;
begin
  try
    strtodate(DataNascimento); //-- Verifica se a data é valida
    strtodate(DataNascimento)>= Date;
  except
    messagedlg('Data de nascimento inválida!', MTERROR, [MBOK], 0);
    abort;
  end;
  result := (Date - Strtodate(DataNascimento))/365.25;
end;

A ideia é saber se a data:

1) Esta no padrão

2) Válida menor que a data de hoje

3) Calcular a idade em anos e em meses à partir da data de nascimento informada.

A função de conversão que estou usando esta dando erro direto:


function TfrmPrincipal.IdadeExtenso(Idade:Double):String;
var
  IdadeAno,IdadeMes, textoAno, textoMes: String;
begin
  Idade:= StrToFloat(FormatFloat('0.00',Idade));
  IdadeAno:= IntTostr(trunc(Idade));
  IdadeMes:= copy(FloatTostr(Idade), length(FloatTostr(Idade)) -1, length(FloatTostr(Idade)));
  IdadeMes:= intTostr(
                       round(
                               (12 * strToint(IdadeMes)) / 100
                            )
                      );
  textoAno:=' Anos e ';
  textoMes:=' Mes(es).';

  if IdadeMes='0' then
  begin
   textoAno:='';
   textoMes:='';
   IdadeMes:='';
  end;
  result:= IdadeAno + textoAno + IdadeMes + textoMes;
end;


function TfrmPrincipal.retornaIdade():Double;
var
DataNascimento:string;
begin
DataNascimento:=copy (EditDataNascimento.text,1,2) + '/' + copy (EditDataNascimento.text,3,2) + '/' +  copy (EditDataNascimento.text,5,4);
result:= DataIdade(DataNascimento);
end;                 

Share this post


Link to post
Share on other sites
nunopicado

Duas coisas:

strtodate(DataNascimento)>= Date;

Esta linha, por causa dos operadores, é uma expressão, e como tal, não pode estar isolada numa instrução.

Deves declarar uma variavel do tipo boolean, e atribuir à variável o resultado.

var
  b:Boolean;
.
.
.
b:=strtodate(DataNascimento)>= Date;

Segundo:

Ao fazeres a gestão de excepções num try...except, as excepções não desaparecem. São levantadas ainda assim.

O que acontece é que antes do teu código de tratamento as apanhar, o Debugger do Delphi/Lazarus apanha-as.

Quer isto dizer que, para veres correctamente o comportamento do teu programa a gerir as excepções, tens de:

a) Em vez de correr o programa a partir do IDE, chama-o directamente no sistema operativo. Isto faz com que a única gestão de excepções a correr para o teu programa seja o proprio programa, e portanto, já não te dá um erro prévio ao que tu determinaste.

b) Ao executar pelo IDE, quando der o erro, escolhe a opção Continuar. O debugger deixa passar o erro, e de seguida será o código do Except a ser executado.


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
armizimm

E assim?

Function TfrmPrincipal.DataIdade(DataNascimento : String) : Double;
begin
  try
    strtodate(DataNascimento); //-- Verifica se a data é valida
    If (strtodate(DataNascimento) >= Date) then StrToInt('A');  // O correto não seria gerar a exceção, mas mostrar outra mensagem no lugar de StrToInt('A') colocar um ShowMessage(' Data inválida! ');
  except
    messagedlg('Data de nascimento inválida!', MTERROR, [MBOK], 0);
    abort;
  end;
  result := (Date - Strtodate(DataNascimento))/365.25;
end;

Edited by nunopicado
Adicionada linguagem GeShi

Share this post


Link to post
Share on other sites
nunopicado

Dar dá... Mas aquela forma de chamar uma excepção é muito pouco elegante, especialmente quando tens métodos próprios para o efeito.

Function Tform1.DataIdade(DataNascimento : String) : Double;
begin
  try
    If (strtodate(DataNascimento) >= Date) then raise Exception.Create('');
  except
    messagedlg('Data de nascimento inválida!', MTERROR, [MBOK], 0);
    abort;
  end;
  result := (Date - Strtodate(DataNascimento))/365.25;
end;

Também dispensas a primeira linha, porque ao testar se é maior que a data actual, se for inválida já vai haver excepção de qualquer maneira.

Edited by nunopicado

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

Ok

If (strtodate(DataNascimento) >= Date)

Mas e se data chegar até aqui com um formato irregular? Tipo 12-06-99. strtodate(DataNaciento)>= Date testa isso também?

Edited by thoga31

Share this post


Link to post
Share on other sites
nunopicado

Sim.

Antes do compilador efectuar a operação strtodate(DataNascimento) >= Date, tem de calcular o valor retornado por strtodate(DataNascimento), para que possa depois comparar se é ou não maior.

Ao calcular este resultado, se a data for inválida, dá imediatamente erro, e já não chega a comparar com a data.

Este erro é uma excepção do tipo EConvertError, que será apanhada pelo Try...Except.


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

Pois é.

Aí é que esta o problema.

Eu preciso fazer duas verificações no try.

Uma pra verificar se esta errado ou não o formato da data

E outra para verificar a regra de negocio que diz que a data não pode ser superior à data de hoje.

Isso é possível em um só try(como)?

Ou terei que usar 2 try's?

Aí fica esquisito não?

Share this post


Link to post
Share on other sites
nunopicado

Não seria esquisito, porque o Try é uma estrutura encadeável.

Podes usar um try...except dentro de um try...finally, por exemplo.

Mas neste caso, nem é preciso, porque estás à procura de excepções num só bloco de código, pelo que basta um try.

Caso a mensagem a mostrar ao utilizador seja a mesma ("Data Inválida"), basta manter como está.

Caso quisesses mensagens diferentes, aí sim, podias por dois try...except, ou melhor ainda, usar códigos de excepções diferentes e com um IF no Except a definir a mensagem.


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
nunopicado

Por exemplo:

Function DataIdade(DataNascimento : String) : Double;
begin
  try
    If (strtodate(DataNascimento) >= Date) then raise Exception.Create('');
  except
        on E: EConvertError Do
           messagedlg('Data de nascimento inválida!', MTERROR, [MBOK], 0);
        else messagedlg('Novo demais!', MTERROR, [MBOK], 0);
    abort;
  end;
  result := (Date - Strtodate(DataNascimento))/365.25;
end;

Edited by nunopicado

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.