Fórum Tem BUG na função MonthsBetween #214328
15/02/2004
0
dataadm,datadem:TDateTime;
mes:integer
a atribuição é:
dataadm := StrToDate(MaskEdit1.Text);
datadem := StrToDate(MaskEdit2.Text);
//Calcular qtos meses tem nas datas informadas
mes := MonthsBetween(dataadm, datadem);
o formato da mascara é: 00/00/0000
Esse ´bug´ só ocorre no mês de fevereiro
Erro:
02/02/2004
02/03/2005
Ele retorna a quantidade de mês igual a 12, deveria ser 13
02/03/2004
02/04/2005
Ele retorna a quantidade de mês igual a 13
Eu notei q este erro só ocorre no mês de fevereiro, em um ano (ex: entre 02/[b:3fef76338d]03[/b:3fef76338d]/2004 a 02/[b:3fef76338d]04[/b:3fef76338d]/2006 retorna 25 meses, mais em 02/[b:3fef76338d]02[/b:3fef76338d]/2004 a 02/[b:3fef76338d]03[/b:3fef76338d]/2006 retorna 24 meses, antes q digam, eu diminui as mêses!!!, por tanto seria 25 tb )
E quando houver um diferença de 3 dias na data, da certo ex: se 01/03/2004 a 03/03/2004 tem 1 mês, 02/02/2004 a 05/03/2004 tem 1 mês, 03/03/2004 a 06/03/2004 tem 1 mês, etc... .
E tb:
01/01/2004 a 09/03/2004 ele retorna 2 meses, porem 01/03/2004 a 09/06/2004 ele retorna 3 meses, ele pula o mês de fevereiro
Desde já agradeço
O programa esta disponível em http://superdownloads.ubbi.com.br/download/i24496.html
Wolverine
Curtir tópico
+ 0Posts
15/02/2004
Beppe
Gostei + 0
15/02/2004
Wolverine
Gostei + 0
16/02/2004
Adilsond
procedure TForm1.Button1Click(Sender: TObject); var DataAdm, DataDem: TDateTime; Mes: Double; begin DataAdm := StrToDate(´02/02/2004´); DataDem := StrToDate(´02/03/2005´); Mes := DateUtil.MonthsBetween(DataAdm, DataDem); Edit1.Text := IntToStr(Trunc(Mes)); end;
O resultado é 13
Gostei + 0
16/02/2004
Wolverine
Gostei + 0
17/02/2004
Wolverine
Continuo perguntando!
[color=red:aeef98bdd8][size=24:aeef98bdd8][b:aeef98bdd8]Tem BUG na função MonthsBetween[/b:aeef98bdd8][/size:aeef98bdd8][/color:aeef98bdd8]
Gostei + 0
01/03/2004
Wolverine
uses DateUtils
var
DataAdm,
DataDem: TDateTime;
Mes: Double;
begin
DataAdm := StrToDate(´02/02/2004´);
DataDem := StrToDate(´02/03/2004´);
Mes := MonthsBetween(DataAdm, DataDem);
Edit1.Text := IntToStr(Trunc(Mes));
end;
Gostei + 0
01/03/2004
Wolverine
uses DateUtils
var
DataAdm,
DataDem: TDateTime;
Mes: Double;
begin
DataAdm := StrToDate(´02/02/2004´);
DataDem := StrToDate(´02/03/2004´);
Mes := MonthsBetween(DataAdm, DataDem);
Edit1.Text := IntToStr(Trunc(Mes));
end;
ele me retorna [b:11e095e861]0[/b:11e095e861]
Gostei + 0
02/03/2004
Adilsond
procedure TForm1.Button1Click(Sender: TObject); var DataAdm, DataDem: TDateTime; Mes: Double; begin ShortDateFormat := ´mm/dd/yyyy´; DataAdm := StrToDate(´02/02/2004´); DataDem := StrToDate(´02/03/2005´); Mes := DateUtil.MonthsBetween(DataAdm, DataDem); Edit1.Text := IntToStr(Trunc(Mes)); // o resultado é 12 end;
procedure TForm1.Button2Click(Sender: TObject); var DataAdm, DataDem: TDateTime; Mes: Double; begin ShortDateFormat := ´dd/mm/yyyy´; DataAdm := StrToDate(´02/02/2004´); DataDem := StrToDate(´02/03/2005´); Mes := DateUtil.MonthsBetween(DataAdm, DataDem); Edit1.Text := IntToStr(Trunc(Mes)); // o resultado é 13 end;
Utilizando a RXlib (´Uses DateUtil´). Testei utilizando o Delphi3 e o 5 e o resultado é o mesmo. A função desta biblioteca está abaixo:
function MonthsBetween(Date1, Date2: TDateTime): Double; var D, M, Y: Word; begin DateDiff(Date1, Date2, D, M, Y); Result := 12 * Y + M; if (D > 1) and (D < 7) then Result := Result + 0.25 else if (D >= 7) and (D < 15) then Result := Result + 0.5 else if (D >= 15) and (D < 21) then Result := Result + 0.75 else if (D >= 21) then Result := Result + 1; end;
Gostei + 0
04/03/2004
Wolverine
1° erro: a biblioteca DateUtil ñ exite exite DateUtil[b:5c36b8e702]s[/b:5c36b8e702]
2° erro: tanto Mes := DateUtil.MonthsBetween(DataAdm, DataDem); quanto Mes := DateUtil[b:5c36b8e702]s[/b:5c36b8e702].MonthsBetween(DataAdm, DataDem); da erro (Undeclered identifer:´DateUtil´ //ou DateUtil[b:5c36b8e702]s[/b:5c36b8e702])
3° erro: ele retorna 12
a unica solução q tive foi fazer a minha propria logica q deu certo
procedure TForm1.Button1Click(Sender: TObject); var DataAdm, DataDem: string; Mes: integer; begin ShortDateFormat := ´dd/mm/yyyy´; DataAdm := ´02/02/2004´; DataDem :=´02/03/2005´; Mes := mesentredatas(dataadm, DataDem); Edit1.Text := IntToStr(Trunc(Mes)); // o resultado é 13 end; function TForm1.mesentredatas(datatotainicial, datatotafinal: string): integer; var mesini,mesfin,mes,anoini,anofin,ano,cont,cont1,I:integer; begin mesini:=strtoint(copy (datatotainicial,4,2)); mesfin:=strtoint(copy (datatotafinal,4,2)); anoini:=strtoint(copy (datatotainicial,7,4)); anofin:=strtoint(copy (datatotafinal,7,4)); mes:=0; ano:=0; // um if para saber se o funcionário ficou mais de um ano na empresa if anoini<anofin then begin // este for é para contar(cont) quantos anos e adicionar 12(cont1)x quantidade(cont) em mêses for I:=anoini to anofin do begin cont:=cont+1; cont1:=cont1+12; end; mesini:=12-mesini; mes:=((mesini+mesfin+cont1)-24); end // este eles é para saber se ele ficou até um ano else begin mesini:=12-mesini; mesfin:=12-mesfin; mes:=(mesini-mesfin); end; Result:=mes end;
Gostei + 0
07/03/2004
Wolverine
Para resolver isso, eu escrevi essa rotina: Código: function MesEntreDatas(DataInicial, DataFinal: TDateTime): integer; var DataIni, DataFim: TDateTime; Dias, Meses, Anos: integer; begin if DataInicial > DataFinal then begin DataIni := Trunc(DataFinal); DataFim := Trunc(DataInicial); end else begin DataIni := Trunc(DataInicial); DataFim := Trunc(DataFinal); end; Dias := Trunc(DayOfTheMonth(DataFim) - DayOfTheMonth(DataIni)); Meses := Trunc(MonthOf(DataFim) - MonthOf(DataIni)); Anos := Trunc(YearOf(DataFim) - YearOf(DataIni)); if Dias < 0 then Dec(Meses); Result := Meses + (Anos * 12); end;
assim como a minha, tb da certo, so q com menos codigo e evita dar bug em relação com as configurações regionais de cada PC, falew :lol:
Gostei + 0
07/03/2004
Marco Salles
Gostei + 0
07/03/2004
Marco Salles
Veja a Função Abaixo Que Se Aproxima Em Principio Da Função MonthsBetween:
function MesEntreDatas2(DataInicial, DataFinal: TDateTime): integer; var Diferenca:TDateTime; begin Diferenca:=Abs(DataFinal-DataInicial); Result:=Trunc((12*Diferenca)/365.2421969697);//Obs:Valor Medio end;
Esta Função <Para Diferenças De Datas Pequena> Tenderá a Ter Um Comportamento Parecedissímo Com a Função MonthsBetween, e Para <Diferenças De Datas Grandes> Ela Tenderá a Se Comporta Com a Função Apresentada Pelo Emerson... Qual é a Certo :?: Ou Qual é a Que Esta Errada :?:
Isto, No Meu Ver Vai Depender Do Que Voce Procura :!: Para Um Sistema Financeiro Por Exemplo Onde a Quantidade De Dias é Fartor Crucial Eu não Aplicaria a Função Do Emerson..Explico:Se Voce Comprar Em 01/02/2003 em 01/03/2003 Já Se Foram 1 Mes..Mas Na Verdade Foram 28 Dias..Então Se Esta No Caso Antecipando o Pagamento..Em Termos De Juros Isto Tem Que Ser Considerado...
Já Para Um Sistema Onde Se Necessita De Meses E Não De Dias , Como Por Exemplo Uma Folha De Pagamento (Funcionário Que Trabalha No Mes Fevereiro= 28 Dias Recebe o Mesmo Valor Quando Trabalha No Mes De Março= 31Dias), O Sistema Do Emerson é Altamente Aplicavel...
O Que Quero Na Verdade Com Tudo Isto é Dar Minha Contribuição,
Esclarecendo Que Na Minha Opinião Não Há Bug Na Função MonthsBetween,E Dependendo Do Sistema Ela Pode Ser Conviavelmente Aplicada..
Mas Falando Nisso , Eu Ainda Não Consegui:
Gostei + 0
07/03/2004
Marco Salles
Veja a Função Abaixo Que Se Aproxima Em Principio Da Função MonthsBetween:
function MesEntreDatas2(DataInicial, DataFinal: TDateTime): integer; var Diferenca:TDateTime; begin Diferenca:=Abs(DataFinal-DataInicial); Result:=Trunc((12*Diferenca)/365.2421969697);//Obs:Valor Medio end;
Esta Função <Para Diferenças De Datas Pequena> Tenderá a Ter Um Comportamento Parecedissímo Com a Função MonthsBetween, e Para <Diferenças De Datas Grandes> Ela Tenderá a Se Comporta Com a Função Apresentada Pelo Emerson... Qual é a Certo :?: Ou Qual é a Que Esta Errada :?:
Isto, No Meu Ver Vai Depender Do Que Voce Procura :!: Para Um Sistema Financeiro Por Exemplo Onde a Quantidade De Dias é Fartor Crucial Eu não Aplicaria a Função Do Emerson..Explico:Se Voce Comprar Em 01/02/2003 em 01/03/2003 Já Se Foram 1 Mes..Mas Na Verdade Foram 28 Dias..Então Se Esta No Caso Antecipando o Pagamento..Em Termos De Juros Isto Tem Que Ser Considerado...
Já Para Um Sistema Onde Se Necessita De Meses E Não De Dias , Como Por Exemplo Uma Folha De Pagamento (Funcionário Que Trabalha No Mes Fevereiro= 28 Dias Recebe o Mesmo Valor Quando Trabalha No Mes De Março= 31Dias), O Sistema Do Emerson é Altamente Aplicavel...
O Que Quero Na Verdade Com Tudo Isto é Dar Minha Contribuição,
Esclarecendo Que Na Minha Opinião Não Há Bug Na Função MonthsBetween,E Dependendo Do Sistema Ela Pode Ser Conviavelmente Aplicada..
Mas Falando Nisso , Eu Ainda Não Consegui:
Gostei + 0
08/03/2004
Marco Salles
Wolverine Usando a Função MonthsBetween Observou Que a Função
Retornava Para Determinadas Datas Um Valor Que Fugia Da Razão:
Entre 01/02/20003 a 01/03/2003 Por Exemplo a Funçao Retorna ´Zero´...
A Expicação para Isto Foi Data Pelo Emerson Quando Em Sua Citação
Alegou Que Esta Função Trabalha ´Com Uma Média E O Mes De Fevereiro Esta Longe Disto´...E Além Disto Ele Mostrou Uma Função Que Parece Estar Bem Mais Próxima Da Realidade...O Que Eu Tentei Passar Que é Extremamente Plausível Existir Diferenças Na Definição De Meses..Um Mes o Que Que é :?: (30 Dias Decorridos De Uma Data :?: Se Completa Um Mes A Partir Da Data Do Mes Seguinte Que Suceder Imediatamente ao Dia Do Mes SubJacente :?: ) Ora Uma Definição Vai Levar Em Determinadas Situações Vantagens Em Relação a Outra ....
E Por Fim Eu Acredito Que Bug São Situações Inesperads Que Ocorrem e Onde Não Há Devido Tratamento Para Elas... Por visto o Autor Desta Função No Meu Entender Preferiu Trabalhar Com Media, E Como Se Definir a Função MonthsBetween, Como a Que Descrevi Anteriormente:
function MesEntreDatas2(DataInicial, DataFinal: TDateTime): integer; var Diferenca:TDateTime; begin Diferenca:=Abs(DataFinal-DataInicial); Result:=Trunc((12*Diferenca)/365.2421969697);//Obs:Valor Medio end;
Esta Função Irá Dar o Mesmo Problema Que A Função MonthsBetween...
Funcionou, Mas Independendo Disto Eu Gostaria De:
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)