Ir para o conteúdo
carcleo

testar data em dois questões

Mensagens Recomendadas

carcleo

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;                 

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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;

Editado por nunopicado
Adicionada linguagem GeShi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Editado por 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
carcleo

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?

Editado por thoga31

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
carcleo

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?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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;

Editado por 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.