Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Something for the weekend #5: Testing for a leap year 6

Status
Not open for further replies.

Mike Lewis

Programmer
Jan 10, 2003
17,505
Scotland
After our excursion into American TV history, today's exercise returns to VFP programming fundamentals.

Your task is to write a function that receives a year (e.g. 2015), and returns .T. if the year is a leap year.

That's all there is to it. As usual, kudos will go to the person who suggests the smallest function (that is, the least amount of code). It doesn't have to be particularly readable or easy to understand.

The function must not have any side effects. If it changes any aspect of the environment (such as SET values), it must change it back again.

If you are one of the first to respond, please use
tags to hide your answer. (An easy way to insert these tags is to use the little yellow icon to the right of the
Code:
 icon at the top of the editing window.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

[url=http://www.ml-consult.co.uk/foxstuff.htm]Visual FoxPro articles, tips and downloads[/url]
 
Ha, at last I'm the first!
FUNCTION leapyear(tnYear as Integer)
RETURN !EMPTY(DATE(m.tnYear,2,29))

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
That's way too easy.
<spoiler>lparameters tnYear
return !isblank(date(tnYear,2,29))</spolier>
 
A math approach
FUNCTION leapyear2(tnYear as Integer)
RETURN ((m.tnYear % 4) + FLOOR(m.tnYear / 100) * (SIGN(m.tnYear % 100) - 1)) % 4 =0

Tore Bleken said:
Really, is there no way to edit one of your own already submitted post?
Usually (but not always) I press Preview before Submit Post...

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Same here, but not in this case. However, I am surprised that you can't edit your own messages, at least until others have replied to it.
 
Oh, heck. This was obviously much too easy.

Vilhelm-Ion's first solution was the one I had in mind. His second one also works, of course, but the first one meets the size criterion. Well done to Tore for getting it as well.

I'm going to have to think of something more difficult next time. Or, better, how about one you guys setting a puzzle of your own?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I am surprised that you can't edit your own messages, at least until others have replied to it.

Yes, that's a common feature in forums. Either you can edit before someone replies, or there is a time window - typically half an hour - during which edits are allowed. But that's never been a feature of Tek Tips.

I always make a point of using the preview whenever I use any kind of tags.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Since I've already seen the solution, the empty return value from DATE(year,2,29) makes it easy to get the last february of any year as:
Code:
EVL(Date(tnYear,2,29),Date(tnYear,2,28))

Yet it's still simpler to compute
Code:
Date(tnYear,3,1)-1

And you may also test
Code:
? "leap year",Day(Date(tnYear,3,1)-1)=29

Bye, Olaf.
 
A quick follow-up.

Today is Friday 13th February 2015. Consider this code:

[tt]ldToday = {^2005-02-13}
? GOMONTH(ldToday, -1)[/tt]

The result is what you would expect.

Now try this:

[tt]ldToday = {^1753-02-13}
? GOMONTH(ldToday, -1)[/tt]

No surprise there either.

But then do this:

[tt]ldToday = {^1753-02-13}
ldLastMonth = GOMONTH(ldToday, -1)
? GOMONTH(ldLastMonth, -1)[/tt]

This time, you get a blank date. Why?

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
<spoiler>
?IsLeap(2016)
FUNCTION IsLeap(tnYear)
RETURN IIF(MONTH(CTOD('02/28/'+TRANSFORM(tnYear)) + 1) = 2,.t.,.f.)
ENDFUNC
</spoiler>

Ez Logic
Michigan
 
Thanks for your contribution, EZ. A couple of points:

Your solution will work, but it depends on DATE being set to American. To make it work consistently, you would have to save SET("DATE") to a variable, then SET DATE AMERICAN, then after executing the code SET DATE to what it was before.

Also, whenever you see code in this general form:

[tt]IIF(<condition>, .T., .F.)[/tt]

you can always shorten it to:

[tt]<condition>[/tt]

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike, Correct, i just simply slapped it together. To add to your observation, which is very good, I didn't even do a try catch either. Example, someone passed a negative year? or someone passed a year that is 4646464756, or a blank year? (maybe from a date field in the table, which is empty or null) etc..

I am sure it can get more refined, i just wanted to show a simple way (before too many elaboration on the function) on one of the ways that one can test for leap year.

Ez Logic
Michigan
 
Without reading anyone else's answer:

FUNCTION IsLeapYear(dDate)

RETURN EMPTY(DATE(YEAR(m.dDate), 2, 29))
 
And I see a couple of bugs already in my code. Take 2:

FUNCTION IsLeapYear(nYear)

RETURN NOT EMPTY(DATE(m.nYear, 2, 29))
 
On the 1752 question, the key issue is that 1752 is when the British empire adopted the Gregorian calendar.

Given that it's Presidents' Weekend here in the US, highly appropriate question because we (at least those of us of a certain age) were all taught that Washington's birthday is February 22, but in fact, he was born on February 11, 1732. When the Gregorian calendar was adopted in 1752, his birthday moved to February 22.

Tamar
 
Since several of you have posted the correct answer, I'll dispense with the spoilers. This is the one I had in mind:

[tt]FUNCTION IsLeapYear(nYear)
RETURN NOT EMPTY(DATE(m.nYear, 2, 29))[/tt]

Keeping in mind that I asked for the smallest function - not necessarily the most readable - we can make a small improvement:

[tt]FUNC IsLeapYear(nYear)
RETU ! EMPT(DATE(m.nYear, 2, 29))[/tt]

Personally, I hate abbreviating code in that way. I almost never use four-letter abbreviations for keywords, and I prefer to use NOT rather than !, because it is more readable. But I did ask for the smallest possible code.

So thank you for your replies. I hope you all found the exercise interesting.

Mike




__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top