Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Saber si un año es bisiesto (https://www.clubdelphi.com/foros/showthread.php?t=41585)

JM75 20-03-2007 11:29:03

Saber si un año es bisiesto
 
Hola a todos. En la aplicación que estoy desarrollando necesito saber si un año es bisiesto o no según la fecha que se introduzca. ¿Hay alguna forma de calcularlo?

Gracias.

Bicho 20-03-2007 11:46:38

Hola,

aquí tienes una manera sencilla:

Código Delphi [-]
Function EsBisiesto(Anyo: string) : Boolean;
var FecAux : tDateTime;
begin
     try
        FecAux := StrToDate('29/02/'+Anyo);
        Result := True;
     except
        Result := False;
     end;
end;

Espero te sirva.

Saludos

JM75 20-03-2007 12:02:09

Hola Bicho,
la función que me has pasado funciona. Aunque si la fecha no existe te da un mensaje de error y después continua bien. ¿Hay alguna forma de que no salte el mensaje de error?
Gracias

Bicho 20-03-2007 12:07:31

Hola,

¿has copiado el try.. except? Si no es así ponlo para capturar el error y evitar que te salga.
Si lo has puesto y aún así te salta un error (te lo debe estar dando si lo ejecutas desde Delphi, ¿no?) debes desactivar los errores del debuger:
Menú Tools => Debugger Options => Pestaña Language Exceptions => Desmarcar: Stop On Delphi Exceptions.

Saludos

JM75 20-03-2007 12:42:57

Al desactivar la opción que has dicho ya no sale más.

Gracias por todo.

DarKraZY 20-03-2007 12:58:25

Creo que esta función es todavía más sencilla, te la brinda la unidad de Delphi SysUtils:
Código Delphi [-]
function IsLeapYear(Year: Word): Boolean;

Saludos!!!

basti 20-03-2007 16:19:46

Sólo como curiosidad, los años bisiestos son todos los divisibles entre 4, excepto los que sean divisibles entre 100 y no entre 400. Algo así:

Código Delphi [-]
function bisiesto(year : word): boolean;
begin
  Result := (year mod 4 = 0) and ((year mod 100 <> 0) or (year mod 400 = 0));
end;

poliburro 20-03-2007 17:51:29

Además de IsLeapYear tenemos DaysInAYear

Function EsBisiesto(PwAnio: Word): Boolean;
Begin
Result := DaysInAYear(PwAnio) = 366
End;

roman 20-03-2007 17:57:51

Pero DaysInAYear utiliza IsLeapYear:

Código Delphi [-]
const
  DaysPerYear: array [Boolean] of Word = (365, 366);

function DaysInAYear(const AYear: Word): Word;
begin
  Result := DaysPerYear[IsLeapYear(AYear)];
end;

// Saludos

richi 20-03-2007 18:11:13

Otra posible manera de hace lo seria poner el primer dia de la fecha del siguiente mes y restandole 1 nos daria los dias.

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  fechaUsar : TDate;
  ano, mes, dia : word;
  anoComprobar : string;
begin
  anoComprobar:= '2007';
  fechaUsar:= strtodate('01/03/' +  anoComprobar) - 1;
  DecodeDate(fechaUsar,ano,mes,dia);

  if dia = 29 then
    ShowMessage('Bisiesto')
  else
    ShowMessage('No es bisiesto');
end;

roman 20-03-2007 18:26:57

Viene a ser lo mismo que comenté antes. DecodeDate necesitará saber si el año es bisiesto para determinar cuál es el día anterior al primero de marzo.

// Saludos

Bicho 20-03-2007 18:27:06

Hola,

Cita:

Empezado por richi
Otra posible manera de hace lo seria poner el primer dia de la fecha del siguiente mes y restandole 1 nos daria los dias.


Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  fechaUsar : TDate;
  ano, mes, dia : word;
  anoComprobar : string;
begin
  anoComprobar:= '2007';
  fechaUsar:= strtodate('01/03/' +  anoComprobar) - 1;
  DecodeDate(fechaUsar,ano,mes,dia);

  if dia = 29 then
    ShowMessage('Bisiesto')
  else
    ShowMessage('No es bisiesto');
end;

Hombre para eso creo más cómodo lo que he puesto en la primera respuesta. No es muy elegante el forzar el error pero tremendamente efectivo y rápido, sin andarse con rodeos.

Saludos

roman 20-03-2007 18:35:15

Oye Bicho, ¿cómo crees que hace StrToDate para generar el error en caso de que le pases un año que no es bisiesto? :p

// Saludos

Bicho 20-03-2007 18:52:14

Esto es lo que hay, que yo tambien se mirarlo, eh? :p
Código Delphi [-]
function StrToDate(const S: string): TDateTime;
begin
  if not TryStrToDate(S, Result) then
    ConvertErrorFmt(@SInvalidDate, [S]);
end;

//Y

function TryStrToDate(const S: string; out Value: TDateTime): Boolean;
var
  Pos: Integer;
begin
  Pos := 1;
  Result := ScanDate(S, Pos, Value) and (Pos > Length(S));
end;

Saludos

roman 20-03-2007 18:57:50

Ajá, y ScanDate utiliza TryEncodeDate:

Código Delphi [-]
function TryEncodeDate(Year, Month, Day: Word; out Date: TDateTime): Boolean;
var
  I: Integer;
  DayTable: PDayTable;
begin
  Result := False;
  DayTable := @MonthDays[IsLeapYear(Year)];
  if (Year >= 1) and (Year <= 9999) and (Month >= 1) and (Month <= 12) and
    (Day >= 1) and (Day <= DayTable^[Month]) then
  begin
    for I := 1 to Month - 1 do Inc(Day, DayTable^[i]);
    I := Year - 1;
    Date := I * 365 + I div 4 - I div 100 + I div 400 + Day - DateDelta;
    Result := True;
  end;
end;

:p

// Saludos

poliburro 20-03-2007 19:04:30

Creo que se están corriendo en círculos, solo es necesario utilizar IsLeapYear.

Para que codificar algo que ya está hecho,

cmpimentel 20-03-2007 19:07:15

hola......
 
hola....


escribeme a mi correo es mas practico y pueda ayudarte en lo que necesites [email protected]:p



Cita:

Empezado por JM75
Hola a todos. En la aplicación que estoy desarrollando necesito saber si un año es bisiesto o no según la fecha que se introduzca. ¿Hay alguna forma de calcularlo?

Gracias.


cmpimentel 20-03-2007 19:09:58

[quote=cmpimentel]hola....


escribeme a mi correo es mas practico y pueda ayudarte en lo que necesites [email protected] soy informatico sivernetico y vivo en ciudad de la habana, cuba

roman 20-03-2007 19:12:34

Cita:

Empezado por poliburro
Creo que se están corriendo en círculos, solo es necesario utilizar IsLeapYear.

¡Pues a eso me refiero! Los métodos que describen, requieren, de una u otra forma, saber si el año es o no bisiesto. Por ello, lo más práctico es, o usar IsLeapYear que usa la fórmula que comenta basti.

// Saludos

roman 20-03-2007 19:13:30

Cita:

Empezado por cmpimentel
escribeme a mi correo es mas practico y pueda ayudarte en lo que necesites

¡Eso! ¡Abajo los foros! :p

// Saludos

Bicho 20-03-2007 19:18:49

Cita:

Empezado por cmpimentel
hola....

escribeme a mi correo es mas practico y pueda ayudarte en lo que necesites [email protected]

¿Y nosotros no estamos ayudando? :confused:
¿No es práctica esta discusión? :confused:

Saludos

egostar 20-03-2007 19:54:07

Cita:

Empezado por roman
¡Pues a eso me refiero! Los métodos que describen, requieren, de una u otra forma, saber si el año es o no bisiesto. Por ello, lo más práctico es, o usar IsLeapYear que usa la fórmula que comenta basti.

// Saludos

Y si a mi me gusta complicarme la vida y no quiero usar esa función de IsLeapYear.......

Bueno, aqui les dejo un pequeño código que iba a poner en el hilo de código sin utilidad.:D

Código Delphi [-]
function TForm1.EsBisiesto(year:integer):bool;
begin
  result := false;
  If ( (year mod 100)= 0) or
     ( (year mod 400)= 0) or
     ( (year mod 4)= 0) then
     result := true;
end;

//Con el método DecodeDate se obtiene el año y es pasado a la función
  DecodeDate(Now,Anio,Mes,Dia);
  If EsBisiesto(Anio) then
     ShowMessage('Es Bisiesto')
  else ShowMessage('NO es Bisiesto');

Saludos.

egostar 20-03-2007 19:56:19

[quote=cmpimentel]
Cita:

Empezado por cmpimentel
hola....


escribeme a mi correo es mas practico y pueda ayudarte en lo que necesites [email protected] soy informatico sivernetico y vivo en ciudad de la habana, cuba

Ya veo, seguro es más práctico.:rolleyes:

DarKraZY 20-03-2007 20:00:55

Cita:

Empezado por egostar
Y si a mi me gusta complicarme la vida y no quiero usar esa función de IsLeapYear.......

¿Por qué no copiamos toda la VCL y la metemos en el form principal? :P

egostar 20-03-2007 20:04:30

Cita:

Empezado por DarKraZY
¿Por qué no copiamos toda la VCL y la metemos en el form principal? :P

:D:D:D, Hombre, que el comentario no es tan literal, no es que YO me quiera complicar la vida, pero me parecio atinado colocarla aqui ya que como lo señalé en su oportunidad, estaba destinado al hilo de código sin utilidad.

Saludos.

roman 20-03-2007 20:04:36

Cita:

Empezado por egostar
Bueno, aqui les dejo un pequeño código que iba a poner en el hilo de código sin utilidad

No te ofendas, pero este código sí que sería inútil pues marca 1900 como bisiesto, siendo que no lo fue. :p

Yo supongo que te refieres al código que puso basti anteriormente:

Código Delphi [-]
function bisiesto(year : word): boolean;
begin
  Result := (year mod 4 = 0) and ((year mod 100 <> 0) or (year mod 400 = 0));
end;

// Saludos

egostar 20-03-2007 20:08:50

Cita:

Empezado por roman
No te ofendas, pero este código sí que sería inútil pues marca 1900 como bisiesto, siendo que no lo fue. :p

Yo supongo que te refieres al código que puso basti anteriormente:

Código Delphi [-]function bisiesto(year : word): boolean; begin Result := (year mod 4 = 0) and ((year mod 100 <> 0) or (year mod 400 = 0)); end;


// Saludos

Y porque iba a ofenderme, si ya sabia que era inutil de procedencia.:D:D:D

Saludos.

basti 20-03-2007 22:43:20

Acabo de ver la implementación de IsLeapYear, y es idéntica a lo que puse antes. Voy a decirle a los de Borland que no me copien más código, jeje

JM75 21-03-2007 10:48:06

Perdonad que no haya contestado antes. Y retomando el tema de este hilo, me acaban de decir que existe la función DaysInMonth que devuelve los días del mes de la fecha que se indique. Si ponemos febrero en la fecha, nos dirá si ese año en febrero hay 28 o 29 días.


DaysInMonth(StrToDate('19/02/2007')); -> Devuelve 28


Por cierto, en mi opinión, los foros permiten que varias personas puedan aportar sus ideas y discutir sobre ellas con lo que el resultado es más de lo que espera uno.

Gracias a todos.

[quote=cmpimentel]
Cita:

Empezado por cmpimentel
hola....


escribeme a mi correo es mas practico y pueda ayudarte en lo que necesites [email protected] soy informatico sivernetico y vivo en ciudad de la habana, cuba


Neftali [Germán.Estévez] 21-03-2007 17:25:28

Cita:

Empezado por cmpimentel
...escribeme a mi correo es mas practico y pueda ayudarte en lo que necesites

Pues no, no es más práctico.
La gracia de los foros es que aquí todos podemos preguntar y responder y las respuestas pueden servir después a otras personas que tienen la misma duda.

Neftali [Germán.Estévez] 21-03-2007 17:33:04

Cita:

Empezado por egostar
Y si a mi me gusta complicarme la vida y no quiero usar esa función de IsLeapYear...

Otra opción es una array con todos los años bisiestos. Para saber si es o no, basta con hacer un recorrido secuencial. La mejor optimización sería utilizar listas ordenadas o una HashList.
El único inconveniente es que tendrás que recompilar cada 4 años, pero ¡¡quien no recompila cada 3 o 4 años!!! :D:D:D

Héctor Randolph 21-03-2007 18:27:03

Cita:

Empezado por JM75
me acaban de decir que existe la función DaysInMonth que devuelve los días del mes de la fecha que se indique. Si ponemos febrero en la fecha, nos dirá si ese año en febrero hay 28 o 29 días.

Según recuerdo esa función también hace uso de IsLeapYear, lo dicho, entramos en un círculo vicioso :D:D:D

Saludos


La franja horaria es GMT +2. Ahora son las 10:42:54.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi