Board index » delphi » Leap year function

Leap year function

Can someone please provide a function that determines whether the
current year is a leap year.
 

Re:Leap year function


Well, leap years are every 4 years, except every 100 years which are not,
except every 400 years which are.  So I think  this should do it?

function LeapYear(year:integer):boolean;
begin
  if  (year mod 4=0)
  and ((year mod 100>0) or (year mod 400 = 0)) then result:=true
 else result:=false;
end;

"mod 4=0" is true for every 4th year,  "mod 100>0" is true except for 100
year multiples, or'd with  "mod 400 =0" puts the 400 year multiples back in.
You can use DecodeDate to get the year for the current date.

________________________
Gary
http://www.delphiforfun.org
_________________________

Quote
"Mark Shapiro" <info...@swbell.net> wrote in message

news:cnvq2tkt9fla8sv8ms4s4rmkkfr8u2ddti@4ax.com...
Quote
> Can someone please provide a function that determines whether the
> current year is a leap year.

Re:Leap year function


On Tue, 05 Dec 2000 17:49:30 -0600, Mark Shapiro <info...@swbell.net>
wrote:

Quote
>Can someone please provide a function that determines whether the
>current year is a leap year.

If you're using D3 or better there's an IsLeapYear function in
SysUtils, to find out if THIS year is a leap year you can use (copied
from the on-line help):

function IsThisLeapYear: Boolean;
var
Yr, Mnth, Day: Word;
begin
   DecodeDate(Date, Yr, Mnth, Day);
   Result := IsLeapYear(Yr);
end;

If you're using pre-D3 then the algorithm is pretty straightforward:

If the year is divisible by 4, and not divisible by 100; unless it's
also divisible by 400; then it's a leap year.

function IsLeapYear(Year: Word): Boolean;
begin  
  Result := False;
  if ((Year div 4) = 0 and not ((Year div 100) = 0)) or
    ((Year div 400) = 0) then
      Result := True;
end;

HTH

Stephen Posey
slpo...@concentric.net

Re:Leap year function


Quote
Stephen Posey wrote:
> On Tue, 05 Dec 2000 17:49:30 -0600, Mark Shapiro <info...@swbell.net>
> wrote:

> >Can someone please provide a function that determines whether the
> >current year is a leap year.

> If you're using D3 or better there's an IsLeapYear function in
> SysUtils, to find out if THIS year is a leap year you can use (copied
> from the on-line help):

> function IsThisLeapYear: Boolean;
> var
> Yr, Mnth, Day: Word;
> begin
>    DecodeDate(Date, Yr, Mnth, Day);
>    Result := IsLeapYear(Yr);
> end;

> If you're using pre-D3 then the algorithm is pretty straightforward:

> If the year is divisible by 4, and not divisible by 100; unless it's
> also divisible by 400; then it's a leap year.

> function IsLeapYear(Year: Word): Boolean;
> begin
>   Result := False;
>   if ((Year div 4) = 0 and not ((Year div 100) = 0)) or
>     ((Year div 400) = 0) then
>       Result := True;
> end;

Surely you meant to use "mod" rather than "div" in there ?

And I've always been a little curious about the range of years for which
this is valid.   Suppose I manage to find a reason to need to know if
the year  1804 BC was a leap year ?

Rob

Re:Leap year function


Here is some code I've just copied from one of my C++ files (sorry about the
cultural clash).
I'll try a translation into Delphi on the fly

Boolean Date::leapYear(short y)
{
  if ( ( y % 4 == 0 ) && ( y % 100 != 0 ) ||
   ( y % 400 == 0 ) )     //  it's a leap year
 return TRUE;
  else return FALSE;

Quote
}

In Delphi (Pascal) something like this should work:

function isLeapYear(const year : integer) : boolean
begin
  isLeapYear := false;
  if year mod 400 = 0 then isLeapYear := true    // any year divisible by
400 is a leap year
  else                                     // otherwise it has to be
divisible by 4 and not divisible by 100
  if (year mod 4 = 0) and (year mod 100 <> 0) then isLeapYear := true;
end;

Quote
Mark Shapiro <info...@swbell.net> wrote in message

news:cnvq2tkt9fla8sv8ms4s4rmkkfr8u2ddti@4ax.com...
Quote
> Can someone please provide a function that determines whether the
> current year is a leap year.

Re:Leap year function


Why would you want to know if any date BC was a leap year? The Georgian
calendar was introduced in the 16th century (not sure), so calculating leap
years before that time is purely hypothetical.

"Rob Stow" <rob.s...@cnnsimail.com> schreef in bericht
news:3A2DD48C.E325B1C1@cnnsimail.com...

Quote
> Stephen Posey wrote:

> > On Tue, 05 Dec 2000 17:49:30 -0600, Mark Shapiro <info...@swbell.net>
> > wrote:

> > >Can someone please provide a function that determines whether the
> > >current year is a leap year.

> > If you're using D3 or better there's an IsLeapYear function in
> > SysUtils, to find out if THIS year is a leap year you can use (copied
> > from the on-line help):

> > function IsThisLeapYear: Boolean;
> > var
> > Yr, Mnth, Day: Word;
> > begin
> >    DecodeDate(Date, Yr, Mnth, Day);
> >    Result := IsLeapYear(Yr);
> > end;

> > If you're using pre-D3 then the algorithm is pretty straightforward:

> > If the year is divisible by 4, and not divisible by 100; unless it's
> > also divisible by 400; then it's a leap year.

> > function IsLeapYear(Year: Word): Boolean;
> > begin
> >   Result := False;
> >   if ((Year div 4) = 0 and not ((Year div 100) = 0)) or
> >     ((Year div 400) = 0) then
> >       Result := True;
> > end;

> Surely you meant to use "mod" rather than "div" in there ?

> And I've always been a little curious about the range of years for which
> this is valid.   Suppose I manage to find a reason to need to know if
> the year  1804 BC was a leap year ?

> Rob

Re:Leap year function


Quote
Mark Shapiro wrote:
> Can someone please provide a function that determines whether the
> current year is a leap year.

function leapyear(y: integer): boolean;
begin
  leapyear:=(y mod 4=0) and ((y mod 100<>0) or (y mod 400=0));
end;

--
Kent Briggs, kbri...@briggsoft.com
Briggs Softworks, http://www.briggsoft.com

Re:Leap year function


JRS:  In article <3A2DD48C.E325B...@cnnsimail.com> of Wed, 6 Dec 2000
05:50:48 seen in news:comp.lang.pascal.delphi.misc, Rob Stow

Quote
<rob.s...@cnnsimail.com> wrote:
>Stephen Posey wrote:

>> On Tue, 05 Dec 2000 17:49:30 -0600, Mark Shapiro <info...@swbell.net>
>> wrote:

>> >Can someone please provide a function that determines whether the
>> >current year is a leap year.

>> If you're using D3 or better there's an IsLeapYear function in
>> SysUtils, to find out if THIS year is a leap year you can use (copied
>> from the on-line help):

>> function IsThisLeapYear: Boolean;
>> var
>> Yr, Mnth, Day: Word;
>> begin
>>    DecodeDate(Date, Yr, Mnth, Day);
>>    Result := IsLeapYear(Yr);
>> end;

>> If you're using pre-D3 then the algorithm is pretty straightforward:

>> If the year is divisible by 4, and not divisible by 100; unless it's
>> also divisible by 400; then it's a leap year.

>> function IsLeapYear(Year: Word): Boolean;
>> begin
>>   Result := False;
>>   if ((Year div 4) = 0 and not ((Year div 100) = 0)) or
>>     ((Year div 400) = 0) then
>>       Result := True;
>> end;

>Surely you meant to use "mod" rather than "div" in there ?

>And I've always been a little curious about the range of years for which
>this is valid.   Suppose I manage to find a reason to need to know if
>the year  1804 BC was a leap year ?

For many practical purposes, it is sufficient to use
        Leap := (Year and 3) = 0 ;
which works for Gregorian and Julian Calendar Years in [1901..2099].
Depending on implementation, "and 3" is likely to equal or beat "mod 4".

For UK Inland Revenue Years, and for other financial years which start
after the end of February, the RHS  must be 3 ; UK FY 1999(-2000) was
Leap, as 1999-04-06..2000-04-05 contains 2000-02-29.

About the fastest full Gregorian Calendar rule (in BP7) is

   function Z00(Y : word) : boolean ; FAR ;
   begin Z00 := ((Y and 3) = 0) and ((Y mod 100 > 0) or (Y mod 400 = 0))
   end ;

//  "R := false ; if ... then R := true" is an abomination, as is
//  "if ... then R := true else R := false".

<URL: http://www.merlyn.demon.co.uk/programs/leapyear.pas> tests many
Leap expressions for correctness and speed.

Rob et al :  for 1804 BC & suchlike, read <URL: http://www.merlyn.demon.
co.uk/leapyear.htm> and links from it, including <URL: http://www.merlyn
.demon.co.uk/miscdate.htm>, <URL: http://www.merlyn.demon.co.uk/moredate
.htm>.  BTW, you realise that, as there was no BC/AD 0, 1804 BC is not a
multiple of 4 years ago?

Leap Years were invented around DCCXIII a.u.c, which later turned out to
be 46 BC; it was decided that they should be every four years, but the
Romans were bad at counting and slow at realising.  Therefore, the leap
years were:
        45 BC(?), 42 BC, 39 BC, 36 BC, 33 BC, 30 BC,
        27 BC, 24 BC, 21 BC, 18 BC, 15 BC, 12 BC, 9 BC,
        AD 8, AD 12, and every 4th year from then on.

The change to the 4/100/400 rule was in 1582 in Rome & nearby, in 1752
in the British Empire, and other dates elsewhere.

See <URL: http://www.tondering.dk/claus/calendar.html> also; and many
books.

<URL: http://www.merlyn.demon.co.uk/programs/tz-check.pas> will show
what your Windows thinks the Time Zone settings should be.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
 Web <URL: http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
 PAS, EXE in <URL: http://www.merlyn.demon.co.uk/programs/> - see 00index.txt.
 Do not Mail News to me.    Before a reply, quote with ">" or "> " (SoRFC1036)

Re:Leap year function


Thanks for the explanation.

Re:Leap year function


JRS:  In article <90ku7u$or...@porthos.nl.uu.net> of Wed, 6 Dec 2000
09:43:12 seen in news:comp.lang.pascal.delphi.misc, M.H. Avegaart

Quote
<avegaartNOS...@mccomm.nl> wrote:
>Why would you want to know if any date BC was a leap year? The Georgian
>calendar was introduced in the 16th century (not sure), so calculating leap
>years before that time is purely hypothetical.

>"Rob Stow" <rob.s...@cnnsimail.com> schreef in bericht
>news:3A2DD48C.E325B1C1@cnnsimail.com...
>> Stephen Posey wrote:
>> ...

Please answer after trimmed quotes, as called for by Usenet norms.

Not Georgian but Gregorian; 1582; but that only added the 100 & 400 year
rules to the 4-year rule of the Julian Calendar, which had been in force
(initially inaccurately) since 714 a.u.c.  Follow links below for more.

The tests for divisibility by 4, 100, 400 should be performed in that
order (with short-circuit evaluation of booleans), since that maximises
the chances of an early decision.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
 Web <URL: http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
 PAS, EXE in <URL: http://www.merlyn.demon.co.uk/programs/> - see 00index.txt.
 Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm  &c.

Re:Leap year function


On Wed, 06 Dec 2000 05:50:48 GMT, Rob Stow <rob.s...@cnnsimail.com>
wrote:

Quote
>Stephen Posey wrote:
>> function IsLeapYear(Year: Word): Boolean;
>> begin
>>   Result := False;
>>   if ((Year div 4) = 0 and not ((Year div 100) = 0)) or
>>     ((Year div 400) = 0) then
>>       Result := True;
>> end;

>Surely you meant to use "mod" rather than "div" in there ?

Oooops, indeed.  Shouldn't write functions when I'm half asleep,
thanks for catching that.

Quote
>And I've always been a little curious about the range of years for which
>this is valid.   Suppose I manage to find a reason to need to know if
>the year  1804 BC was a leap year ?

That's what would be called a "proleptic" use of a calendar, applying
its reconing beyond when it was actually in use.  

If you're into such things Lance Latham's book "Standard C Date/Time
Library" (ISBN: 0879304960) is an excellent treatise on the origins of
time keeping and many different calendars, over and above being a good
programming reference (even if the code IS in C ;-))

Stephen Posey
slpo...@concentric.net

Re:Leap year function


Why everybody programs things again?

Why do not simply use

{ IsLeapYear determines whether the given year is a leap year. }
function IsLeapYear(Year: Word): Boolean;

of Borlands Unit SysUtils?

Regards
Nicolas

Re:Leap year function


Mark Shapiro schrieb:

Quote
> I needed this function to perform computations based on the number of
> days in any given month. So in the interim, I rolled my own function
> to get the number of February days for any year:

The SysUtils unit, at least in D5, defines a const for this. Just use
the value

  i := MonthDays[IsLeapYear(theYear), theMonth];

-Michael

Re:Leap year function


Mark Shapiro schrieb:

Quote
> I needed this function to perform computations based on the number of
> days in any given month. So in the interim, I rolled my own function
> to get the number of February days for any year:

The SysUtils unit, at least in D5, defines a const for tX-Mozilla-Status: 0009ue

  i := MonthDays[IsLeapYear(theYear), theMonth];

-Michael

Re:Leap year function


JRS:  In article <b6fv2tg15ucrg62c8nneniu7c5avlgo...@4ax.com> of Thu, 7
Dec 2000 10:41:34 seen in news:comp.lang.pascal.delphi.misc, Mark

Quote
Shapiro <info...@swbell.net> wrote:
>My news server has been hiccuping for the past couple of days and I've
>only now received the good advice on the IsLeapYear function in
>Delphi. My earlier search in the index for "leapyear" found no
>matches.

>I needed this function to perform computations based on the number of
>days in any given month. So in the interim, I rolled my own function
>to get the number of February days for any year:

>function LastFebDay(fYear : integer) : integer;
>var
>  sYear, sMonth, sDay : word;
>  TestDate : TDateTime;
>begin
>  TestDate := EncodeDate(fYear, 3, 1);
>  DecodeDate(TestDate -1, sYear, sMonth, sDay);
>  Result := sDay;
>end;

Well, if time is not of the essence, that'll do.

You could compare Round(EncodeDate(Y,3,1)-EncodeDate(Y,2,1));

But   Result := 28+Ord((fYear and 3)=0)   should be much quicker, and
will work for over +-99 years.  The contents of the Ord() can be
replaced as below.

Borland's IsLeapYear implements  Result :=
    (AYear mod 4 = 0) and ((AYear mod 100 <> 0) or (AYear mod 400 = 0));
in D3 TCalendar, and uses that in
    if (AMonth = 2) and IsLeapYear(AYear) then Inc(Result);
to extend February.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
 Web <URL: http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
 PAS, EXE in <URL: http://www.merlyn.demon.co.uk/programs/> - see 00index.txt.
 Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm  &c.

Go to page: [1] [2]

Other Threads