set output to {}
repeat with indx from -401 to 401
if Date_Info_Is_Leap_Year(indx) then set the end of output to indx & " "
end repeat
display dialog "" & output
on Date_Info_Is_Leap_Year(dateYear)
--https://www.macscripter.net/u/Nigel_Garvey https://www.macscripter.net/t/testing-for-a-leap-year/77975/4
if dateYear < 1 then set dateYear to (dateYear * -1) - 1
return ((dateYear mod 4 is 0) and ((dateYear mod 100 > 0) or (dateYear mod 400 is 0)))
end Date_Info_Is_Leap_Year
A nice adaptation of the handler! ![]()
The rest’s quick and dirty though — building a list of lists and assuming the TIDs will be {“”} or “” when it’s coerced to text. ![]()
Thanks. I love tersely perspicuous AppleScript code. ![]()
Fair enough. But the TIDS are going to be {“”}. ![]()
FWIW, the Shortcuts Get Date from Input action doesn’t work with dates in the BC era and cannot be used to get leap years. Somewhat surprisingly, the Adjust Date action will return a leap year (actually a leap day), but this would seem to be of no practical value. For the BC era, the math approach seems the best solution.
Sorry. A couple more takes on the slightly off-topic “leap years between … using AppleScript” theme. The first uses AppleScript date object math and can handle years between 0000 and 9999:
set startYear to 0
set endYear to 9999
leapYears(startYear, endYear)
on leapYears(startYear, endYear)
script o
property output : {}
end script
tell (startYear + 3) to set startYear to it - it mod 4
tell (current date) to set {testDate, its day, its month, its year} to {it, 1, January, startYear}
set fourYears to 1461 * days
repeat with y from startYear to endYear by 4
set testDate to testDate + fourYears
if (testDate's day is 1) then
set o's output's end to y
else
set testDate's day to 1
end if
end repeat
return o's output
end leapYears
The other simply runs the 400-year cycles, jumping in and out at the appropriate years. It’s slightly faster than the date object script over the same range and can go way beyond it in either direction using the astronomical year convention:
set startYear to -9999
set endYear to 12000
leapYears(startYear, endYear)
on leapYears(startYear, endYear)
script o
property output : {}
end script
-- Initialise a loop variable y to the next multiple of 4 after or including startYear.
set roundingAdjustment to 3 * ((startYear comes after 0) as integer) -- Positives and negatives are rounded up slightly differently.
tell (startYear + roundingAdjustment) to set y to it - it mod 4
if (y mod 400 = 0) then
-- y's the last year of a 400-year cycle. Store it immediately and set up to start the next cycle.
set o's output's end to y
set y to y + 4
set centuriesToEndOfCycle to 4
else
-- Otherwise, if it's one of the other century years, skip it.
if (y mod 100 = 0) then set y to y + 4
-- Work out which of the cycle's centuries, counting from the end, contains y.
set centuriesToEndOfCycle to 1 + roundingAdjustment - y div 100 mod 4
end if
-- Initialise a variable representing the 96th year of each century to that before the current y.
set centuryLimit to y - y mod 100 - 100 * ((y comes before 1) as integer) - 4
repeat -- Each 400-year cycle.
repeat centuriesToEndOfCycle times
-- Generate the leap year numbers from y to this century's 96th year, or until endYear if that comes first.
set centuryLimit to centuryLimit + 100
if (centuryLimit comes after endYear) then set centuryLimit to endYear
repeat with y from y to centuryLimit by 4
set o's output's end to y
end repeat
set y to y + 8 -- Skip the century year …
end repeat
set cycleEndYear to y - 4 -- … except at the end of the cycle.
if (cycleEndYear comes after endYear) then exit repeat
set o's output's end to cycleEndYear
set centuriesToEndOfCycle to 4
end repeat
return o's output
end leapYears
Nigel. I happened to notice that -2004 is shown as a year leap if -2004 is the startYear, but -2000 is not shown as a leap year if -2000 is the startYear.
Thanks, peavine. How annoying. I’ve tracked down what was causing the problem, but fixing it caused something else to fall apart! I’ve removed the script from my post while I do some more work on it….
Thanks again, peavine. I’ve now special-cased the start year being the last year of a 400-year cycle, which seems to have fixed the problem. ![]()
Just for the sake of completeness, there’s another approach that’s probably obvious but should be mentioned, and that’s to include a list of leap years in the shortcut. This approach may give an erroneous result if any year contains three or fewer digits. The timing result is less than 10 milliseconds.
Leap Year Test.shortcut (22.4 KB)

