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
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
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?
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.
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
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.
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.”
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”