VBA中IsLeapYear函数的一个很好的实现是什么?
编辑:我运行了if-then和DateSerial实现,迭代包含在一个计时器中,而DateSerial的平均速度提高了1-2毫秒(5次运行300次迭代, 1平均单元格工作表公式也有效。)
答案 0 :(得分:21)
Public Function isLeapYear(Yr As Integer) As Boolean
' returns FALSE if not Leap Year, TRUE if Leap Year
isLeapYear = (Month(DateSerial(Yr, 2, 29)) = 2)
End Function
我最初从Chip Pearson的Excel网站上获得了这个功能。
答案 1 :(得分:14)
public function isLeapYear (yr as integer) as boolean
isLeapYear = false
if (mod(yr,400)) = 0 then isLeapYear = true
elseif (mod(yr,100)) = 0 then isLeapYear = false
elseif (mod(yr,4)) = 0 then isLeapYear = true
end function
维基百科了解更多...... http://en.wikipedia.org/wiki/Leap_year
答案 2 :(得分:5)
如果考虑效率并且预期年份是随机的,那么首先做最常见的案例可能稍好一些:
public function isLeapYear (yr as integer) as boolean
if (mod(yr,4)) <> 0 then isLeapYear = false
elseif (mod(yr,400)) = 0 then isLeapYear = true
elseif (mod(yr,100)) = 0 then isLeapYear = false
else isLeapYear = true
end function
答案 3 :(得分:2)
我在CodeToad上发现了这个有趣的一个:
Public Function IsLeapYear(Year As Varient) As Boolean
IsLeapYear = IsDate("29-Feb-" & Year)
End Function
虽然我很确定在一个函数中使用IsDate可能比一些if,elseifs慢。
答案 4 :(得分:2)
作为Chip Pearson解决方案的变体,您也可以尝试
Public Function isLeapYear(Yr As Integer) As Boolean
' returns FALSE if not Leap Year, TRUE if Leap Year
isLeapYear = (DAY(DateSerial(Yr, 3, 0)) = 29)
End Function
答案 5 :(得分:1)
Public Function ISLeapYear(Y As Integer) AS Boolean
' Uses a 2 or 4 digit year
'To determine whether a year is a leap year, follow these steps:
'1 If the year is evenly divisible by 4, go to step 2. Otherwise, go to step 5.
'2 If the year is evenly divisible by 100, go to step 3. Otherwise, go to step 4.
'3 If the year is evenly divisible by 400, go to step 4. Otherwise, go to step 5.
'4 The year is a leap year (it has 366 days).
'5 The year is not a leap year (it has 365 days).
If Y Mod 4 = 0 Then ' This is Step 1 either goto step 2 else step 5
If Y Mod 100 = 0 Then ' This is Step 2 either goto step 3 else step 4
If Y Mod 400 = 0 Then ' This is Step 3 either goto step 4 else step 5
ISLeapYear = True ' This is Step 4 from step 3
Exit Function
Else: ISLeapYear = False ' This is Step 5 from step 3
Exit Function
End If
Else: ISLeapYear = True ' This is Step 4 from Step 2
Exit Function
End If
Else: ISLeapYear = False ' This is Step 5 from Step 1
End If
End Function
答案 6 :(得分:1)
Public Function isLeapYear(Optional intYear As Variant) As Boolean
If IsMissing(intYear) Then
intYear = Year(Date)
End If
If intYear Mod 400 = 0 Then
isLeapYear = True
ElseIf intYear Mod 4 = 0 And intYear Mod 100 <> 0 Then
isLeapYear = True
End If
End Function
答案 7 :(得分:1)
我看到许多伟大的概念表明了更多的理解 以及可以学习的日期函数的使用...... 在代码效率方面.. 考虑执行函数所需的机器代码
而不是复杂的日期函数 只使用相当快的整数函数 BASIC建立在GOTO之上 我怀疑下面的东西更快
Function IsYLeapYear(Y%) As Boolean
If Y Mod 4 <> 0 Then GoTo NoLY ' get rid of 75% of them
If Y Mod 400 <> 0 And Y Mod 100 = 0 Then GoTo NoLY
IsYLeapYear = True
NoLY:
End Function
答案 8 :(得分:1)
解决性能问题的最后答案。
TL / DR:数学版本约快5倍
我在这里看到两组答案
我对所有发布的答案进行了时间测试,发现数学方法比日期/时间方法快5倍。
然后我对这些方法进行了一些优化并提出(相信与否Integer
在这种情况下比Long
略快,不知道为什么。)
Function IsLeapYear1(Y As Integer) As Boolean
If Y Mod 4 Then Exit Function
If Y Mod 100 Then
ElseIf Y Mod 400 Then Exit Function
End If
IsLeapYear1 = True
End Function
为了比较,我提出了(与发布的版本差别很小)
Public Function IsLeapYear2(yr As Integer) As Boolean
IsLeapYear2 = Month(DateSerial(yr, 2, 29)) = 2
End Function
将日期构建为字符串的日期/时间版本打折,因为它们再次慢得多。
测试是获得IsLeapYear
年100 ... 9999,重复1000次
<强>结果
测试代码是
Sub Test()
Dim n As Long, i As Integer, j As Long
Dim d As Long
Dim t1 As Single, t2 As Single
Dim b As Boolean
n = 1000
Debug.Print "============================="
t1 = Timer()
For j = 1 To n
For i = 100 To 9999
b = IsYLeapYear1(i)
Next i, j
t2 = Timer()
Debug.Print 1, (t2 - t1) * 1000
t1 = Timer()
For j = 1 To n
For i = 100 To 9999
b = IsLeapYear2(i)
Next i, j
t2 = Timer()
Debug.Print 2, (t2 - t1) * 1000
End Sub
答案 9 :(得分:0)
这是另一个简单的选择。
Leap_Day_Check = Day(DateValue("01/03/" & Required_Year) - 1)
如果Leap_Day_Check = 28那么它不是闰年,如果它是29,那么。
VBA知道3月1日之前的日期是一年,所以我们会将其定为2月28日或29日。