How to check for leap year

This checks for leap year and if Month is 2 sets the date to the 28th:

Public Function CheckLeapYr(ldDate As Date) as Date
  Dim ldReturnDate As New Date
  
  ldReturnDate = ldDate
  if ldDate.Year mod 4 = 0 then
    if ldDate.Month = 2 then
      ldReturnDate.day = 28
    end
  end
  
  Return ldReturnDate
End Function

How would I do this with DateTime?

Public Function calcLeapYear(inYear as Integer) as boolean
  Return (((inYear MOD 4)=0) AND ((inYear MOD 100)<>0)) OR (inYear MOD 400)=0

End Function

Just send in the integers. This is what I do for my Calendar and Timer Chooser Project.

It does that, its setting Feb 28th that’s the question?

FYI, you use the New keyword to create a new Date, then immediately replace it with the given date. You then, maybe, update the Day property of the given date.

The variable ldReturnDate serves no purpose in this code as it is just ldDate. Did you mean to do

dim ldReturnDate as new Date(ldDate)

?

Want to use DateTime.

Your title says “How to check for leap year”. My code does that by returning a boolean value if this year integer you pass in is a leap year or not thus abstracting the need to pass in any date/datetime objects. Perhaps modify your title for future onlookers?

Thanks Richard.
Mike

Part of Mike’s response was correctly showing an accurate way to test if a given year is a leap year, instead of the single test of your code which only checks if the year is divisible by 4. That method works for 1901-2099 but fails for years ending 00 unless also divisible by 400 (like the year 2000). Thus years like 1900 or 2100 are NOT leap years. So be careful of assumptions like Year mode 4= 0.

But I’m also confused by why your original code sets the day to 28 anytime the month is 2 when you think it is a leap year. The thread title is “How to check for leap year” but you are returning a date of Feb 28 of the current year anytime you are in February of what you think is a leap year.

Try this:

Public Function CheckLeapYr(dt As DateTime) as DateTime
  var feb28 as new DateTime(dt.Year, 2, 28)
  var feb29 as DateTime = feb28.AddInterval(0, 0, 1)
  if feb29.Day = 29 then
    return feb28
  else
    return dt
  end if
End Function
1 Like

Hehehe – If our apps are running still in 2099 into 2100 then wow!! :slight_smile: :slight_smile: Neo and Morphius would be impressed! :slight_smile: :slight_smile:

I have purposefully created a Y10K problem in some of my code, thus ensuring my future employment to fix it. #thinkingahead

1 Like

HAHAHA! That is total future proofing right there brother :slight_smile:

I too would like to know why the OP is doing this.

Specifically, in one of our database tables, an end date can be NULL, meaning “none”, but we have to check for an overlap among records, so I substitute END_OF_TIME for NULL, where it’s defined as “9999-12-31”. That’s going to cause problems in the year 10,000, but I’ll be there for it.*

* Assumptions based on my previous track record of not dying.

2 Likes

That is perfect, Thank you!

DateTime LR entry states:

If you pass invalid values (such as 32 for the day, 13 for the month) when creating a DateTime, an [InvalidArgumentException](http://documentation.xojo.com/api/exceptions/invalidargumentexception.html) is raised.

Well, depending on the application you can have historical dates before 1901, and future dates of 2100+. So very much depends on the application. I plan on retiring before worrying about years beyond 9999, so will let @Kem Tekinay resolve those.

As somebody once said, “I plan on being immortal. So far, so good.”

2 Likes

I use an extension method to add a LeapYear method that I can treat as a boolean value.

Public Function LeapYear(Extends dt As DateTime) as Boolean
  Var tDate As New DateTime(dt.Year, 12, 31, 12, 0, 0, 0, TimeZone.Current)
  Return tDate.DayOfYear = 366
End Function

Drop this into a module and all your dates now have a LeapYear “property”

7 Likes

Awesome Wayne thanks!!!