Proving Leap Year is NOT Every Four Years with PowerShell

Last week, I saw a couple of tweets from PowerShell MVP Jeffery Hicks about leap year that caught my attention:

030614-1.png

One of the reasons that I found those tweets so interesting is that I had just heard the night before on of all places, Wheel of Fortune, that leap year wasn't every four years. I'd always been told that leap year was every four years and it has been for my entire life so it was time to investigate further.

I decided to start with one of Jeff's examples and add some code to it to determine which years should be leap years but weren't based on the popular belief that leap year is every four years:

1$leapYears = 1600..2250 | where {[datetime]::DaysInMonth($_,2) -eq 29}
2
3foreach ($leapYear in $leapYears) {
4    $nextLeapYear = $leapYear + 4
5
6    if ($leapYears -notcontains $nextLeapYear -and $leapYear -ne $leapYears[-1]) {
7        Write-Output "$nextLeapYear"
8    }
9}

030614-2b.png

Now that's interesting. Why aren't those years, shown in the previous example, leap years? I found a Wikipedia article about leap year with the answer to that question which I documented in the description section of the comments in the function shown in the following example. That Wikipedia article also provided some pseudo-code which I converted into PowerShell:

 1function Get-LeapYear {
 2
 3<#
 4.SYNOPSIS
 5   Get-LeapYear is used to determine whether or not a specific year is a leap year.
 6.DESCRIPTION
 7   Get-LeapYear is a function that is used to determine whether or not the specified
 8   year(s) are leap years. Contrary to popular belief, leap year does not occur every
 9   four years. According to Wikipedia, if a year is divisible by 400 then it's a leap
10   year, else if the year is divisible by 100 then it's a normal year, else if the year
11   is divisible by 4 then it's a leap year, else it's a normal year. Source:
12   http://en.wikipedia.org/wiki/Leap_year
13.PARAMETER Year
14   The year(s) specified in integer form that you would like to determine
15   whether or not they are a leap year.
16.EXAMPLE
17   Get-LeapYear
18.EXAMPLE
19   Get-LeapYear -Year 2010, 2011, 2012, 2013, 2014, 2015
20.EXAMPLE
21   1890..1910 | Get-LeapYear
22.INPUTS
23   Integer
24.OUTPUTS
25   String
26.NOTES
27   Author:  Mike F Robbins
28   Website: http://mikefrobbins.com
29   Twitter: @mikefrobbins
30#>
31
32    [CmdletBinding()]
33    param (
34        [Parameter(ValueFromPipeline=$true)]
35        [ValidateRange(1582,9999)]
36        [int[]]$Year = (Get-Date).Year
37    )
38
39    PROCESS {
40        foreach ($y in $Year) {
41            if ($y / 400 -is [int]) {
42                Write-Output "$y is a leap year"
43            }
44            elseif ($y / 100 -is [int]) {
45                Write-Output "$y is not a leap year"
46            }
47            elseif ($y / 4 -is [int]) {
48                Write-Output "$y is a leap year"
49            }
50            else {
51                Write-Output "$y is not a leap year"
52            }
53        }
54    }
55}

030614-3a.png

As you can see 1900 was not a leap year and there were 8 years between leap years from 1896 to 1904. Eight years between leap years won't occur again until years 2096 to 2104 .

µ