Function 你如何看待VBA的Leapyear?
什么是VBA中IsLeapYear函数的良好实现 编辑:我运行了if-then和DateSerial实现,迭代被包装在一个计时器中,DateSerial平均快了1-2毫秒(5次300次迭代,1个平均单元格工作表公式也起作用) 我最初是从Chip Pearson伟大的Excel网站获得此功能的 维基百科了解更多。。。Function 你如何看待VBA的Leapyear?,function,vba,excel,code-snippets,Function,Vba,Excel,Code Snippets,什么是VBA中IsLeapYear函数的良好实现 编辑:我运行了if-then和DateSerial实现,迭代被包装在一个计时器中,DateSerial平均快了1-2毫秒(5次300次迭代,1个平均单元格工作表公式也起作用) 我最初是从Chip Pearson伟大的Excel网站获得此功能的 维基百科了解更多。。。 如果效率是一个考虑因素,并且预期年份是随机的,那么最好先处理最常见的情况: public function isLeapYear (yr as integer) as boolea
如果效率是一个考虑因素,并且预期年份是随机的,那么最好先处理最常见的情况:
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
公共函数isLeapYear(yr为整数)为布尔值
如果(mod(yr,4))为0,则isLeapYear=false
elseif(mod(yr,400))=0,则isLeapYear=true
elseif(mod(yr,100))=0,则isLeapYear=false
else isLeapYear=true
端函数
我在以下网站上找到了这张有趣的照片:
虽然我很确定在函数中使用IsDate可能比使用几个if,elseifs慢。作为芯片上的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
公共函数isLeapYear(可选intYear作为变量)为布尔值
如果是失踪(年),那么
intYear=年(日期)
如果结束
如果intYear Mod 400=0,则
isLeapYear=True
否则,intYear Mod 4=0,intYear Mod 100=0
isLeapYear=True
如果结束
端函数
这里是另一个简单的选项
Leap_Day_Check = Day(DateValue("01/03/" & Required_Year) - 1)
如果闰年=28,则不是闰年,如果是29,则是闰年
VBA知道一年中3月1日之前的日期,因此我们会将其设置为2月28日或29日。我看到许多伟大的概念,表明我们需要额外的理解 以及日期函数的使用,非常值得学习。。。 在代码效率方面。。 考虑函数执行< /P>所需的机器代码。 而不是复杂的日期函数 仅使用相当快的整数函数 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
延迟回答性能问题 TL/DR:Math版本大约快了5倍
我在这里看到两组答案
然后我对这些方法进行了一些优化,并提出了(信不信由你,
Integer
比Long
稍微快一点,在这种情况下,我不知道为什么。)
为了比较,我提出了(与发布的版本差别很小)
将日期构建为字符串的日期/时间版本被打折了,因为它们再次慢了很多
这项测试是为了获得100到9999年的IsLeapYear
,重复1000次
结果
- 数学版:640ms
- 日期/时间版本:3360ms
测试代码是
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
这个可能更有效。我喜欢它特别采用闰年的定义,并将其应用到答案中。变量isLeap没有被使用。被4平均整除不是闰年!2100年不是闰年。测试的400除法部分应在4除法之前。创造性解决方案!我想知道它对其他帖子的表现如何。这并没有考虑到所有的闰年规则。事实上,如果你研究他们在做什么,它总是有效的。他们检查二月是否有29天,这使它成为一年。它基本上把leapyear规则押给了微软。芯片有很多很好的解决方案。如果效率是你的目标,你可以去掉isLeapYear=false,因为布尔值默认为false:)你的意思是使用DAY函数而不是MONTH函数吗?多少毫秒中有1-2毫秒?i、 e.相对效率增益是多少?只是好奇@珍,问得好,那是几年前的事了。当我下周回到工作岗位做更多的测试时,我会尽力记住,这会特别好,因为从那时起,有更多的答案。
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
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
Leap_Day_Check = Day(DateValue("01/03/" & Required_Year) - 1)
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
End Function
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
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