Hvordan finner du Leapyear i VBA?

stemmer
9

Hva er en god gjennomføring av en IsLeapYear funksjon i VBA?

Edit: I drev if-then og Dateserial gjennomføring med gjentakelser innpakket i et tidsur, og Dateserial var raskere på gjennomsnittet av 1-2 ms (5 løper på 300 iterasjoner, med en gjennomsnittlig cellearket formel også fungerer).

Publisert på 24/09/2008 klokken 14:10
kilden bruker
På andre språk...                            


10 svar

stemmer
17

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  

Jeg opprinnelig fikk denne funksjonen fra Chip Pearson store Excel nettstedet.

Pearson nettsted

Svarte 24/09/2008 kl. 14:10
kilden bruker

stemmer
12
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

Wikipedia for mer ... http://en.wikipedia.org/wiki/Leap_year

Svarte 24/09/2008 kl. 14:16
kilden bruker

stemmer
5

Hvis effektivitet er en vurdering og forventet år er tilfeldig, så kan det være litt bedre å gjøre den hyppigste saken først:

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
Svarte 24/09/2008 kl. 19:28
kilden bruker

stemmer
2

Jeg fant denne morsom en på CodeToad :

Public Function IsLeapYear(Year As Varient) As Boolean
  IsLeapYear = IsDate("29-Feb-" & Year)
End Function 

Selv om jeg er ganske sikker på at bruk av IsDate i en funksjon er trolig tregere enn et par hvis elseifs.

Svarte 24/09/2008 kl. 22:50
kilden bruker

stemmer
2

Som en variant av den Chip Pearson løsningen, kan du også prøve

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
Svarte 08/08/2011 kl. 03:15
kilden bruker

stemmer
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
Svarte 28/09/2013 kl. 13:30
kilden bruker

stemmer
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
Svarte 19/08/2014 kl. 04:13
kilden bruker

stemmer
0

Her er en annen enkel alternativ.

Leap_Day_Check = Day(DateValue("01/03/" & Required_Year) - 1)

Hvis Leap_Day_Check = 28 så er det ikke et skuddår, hvis det er 29 det er.

VBA vet hva datoen før 1 mars er i et år, og det vil sette den til å være enten 28 eller 29 februar for oss.

Svarte 19/11/2015 kl. 14:10
kilden bruker

stemmer
1

Jeg ser mange gode konsepter som tyder ekstra forståelse og bruk av dato funksjoner som er veldig bra å lære av ... I form av kode effektivitet .. vurdere maskinen koden som trengs for en funksjon for å utføre

snarere enn komplekse date funksjoner bruker bare ganske raske heltall funksjoner BASIC ble bygget på GOTO jeg mistenker at noe sånt under er raskere

  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
Svarte 13/04/2017 kl. 01:54
kilden bruker

stemmer
1

Sent svar å ta ytelsen spørsmålet.

TL / DR: de Math versjoner er ca 5x raskere


Jeg ser to grupper av svarene her

  1. Matematisk tolkning av skuddår definisjonen
  2. Utnytte Excel dato / klokkeslett funksjoner for å oppdage den 29 februar (disse faller inn i to leire: de som bygger en dato som en streng, og de som ikke gjør det)

Jeg kjørte tidstester på alle postet svar, en oppdaget Matematiske metoder er i ferd med 5x raskere enn dato / klokkeslett metoder.


Jeg gjorde noen optimalisering av metodene og kom opp med (tro det eller ei Integerer marginalt raskere enn Longi dette tilfellet, vet ikke hvorfor.)

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

Til sammenligning kom jeg opp (svært lite forskjell på bokført versjon)

Public Function IsLeapYear2(yr As Integer) As Boolean
    IsLeapYear2 = Month(DateSerial(yr, 2, 29)) = 2
End Function

Dato / klokkeslett versjoner som bygger en dato som en streng neddiskontert som de er mye tregere på nytt.

Testen var å få IsLeapYeari mange år 100..9999, gjentas 1000 ganger

resultater

  • Math versjon: 640ms
  • Dato / tid versjon: 3360ms

Test-koden var

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
Svarte 05/06/2018 kl. 03:28
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more