Skip to content

Commit

Permalink
Easter calculation (#2)
Browse files Browse the repository at this point in the history
* Add Easter month and day calculation

* Add comment on algorithm source

* Documentation cleanup
  • Loading branch information
sbooth authored Oct 31, 2023
1 parent 056f72b commit a043bf8
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
51 changes: 51 additions & 0 deletions Sources/JulianDayNumber/Easter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Copyright © 2021-2023 Stephen F. Booth <[email protected]>
// Part of https://github.com/sbooth/JulianDayNumber
// MIT license
//

import Foundation

// From the Explanatory Supplement to the Astronomical Almanac, 3rd edition, S.E Urban and P.K. Seidelmann eds., (Mill Valley, CA: University Science Books), Chapter 15, pp. 585-624.

/// Returns the month `M` and day `D` of Easter in year `Y`.
///
/// Years before 1582 are interpreted in the Julian calendar and years after
/// 1582 are interpreted in the Gregorian calendar.
///
/// - parameter year: A year number.
///
/// - returns: The month and day of Easter in the requested year.
public func easter(year Y: Int) -> (month: Int, day: Int) {
return Y < 1582 ? easterInJulianCalendar(year: Y) : easterInGregorianCalendar(year: Y)
}

/// Returns the month `M` and day `D` of Easter in year `Y` in the Julian calendar.
///
/// - parameter year: A year number.
///
/// - returns: The month and day of Easter in the requested year.
public func easterInJulianCalendar(year Y: Int) -> (month: Int, day: Int) {
let a = 22 + ((225 - 11 * (Y % 19)) % 30)
let g = a + ((56 + 6 * Y - Y / 4 - a) % 7)
let M = 3 + g / 32
let D = 1 + ((g - 1) % 31)
return (M, D)
}

/// Returns the month `M` and day `D` of Easter in year `Y` in the Gregorian calendar.
///
/// - parameter year: A year number.
///
/// - returns: The month and day of Easter in the requested year.
public func easterInGregorianCalendar(year Y: Int) -> (month: Int, day: Int) {
let a = Y / 100
let b = a - a / 4
let c = (Y % 19)
let e = ((15 + 19 * c + b - (a - (a - 17) / 25) / 3) % 30)
let f = e - (c + 11 * e) / 319
let g = 22 + f + ((140004 - Y - Y / 4 + b - f) % 7)
let M = 3 + g / 32
let D = 1 + ((g - 1) % 31)
return (M, D)
}
23 changes: 23 additions & 0 deletions Tests/JulianDayNumberTests/EasterTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// Copyright © 2021-2023 Stephen F. Booth <[email protected]>
// Part of https://github.com/sbooth/JulianDayNumber
// MIT license
//

import XCTest
@testable import JulianDayNumber

final class EasterTests: XCTestCase {
func testEaster() {
// Dates from Meeus (1998)
XCTAssertTrue(easter(year: 1991) == (3, 31))
XCTAssertTrue(easter(year: 1992) == (4, 19))
XCTAssertTrue(easter(year: 1993) == (4, 11))
XCTAssertTrue(easter(year: 1954) == (4, 18))
XCTAssertTrue(easter(year: 2000) == (4, 23))
XCTAssertTrue(easter(year: 1818) == (3, 22))
XCTAssertTrue(easter(year: 179) == (4, 12))
XCTAssertTrue(easter(year: 711) == (4, 12))
XCTAssertTrue(easter(year: 1243) == (4, 12))
}
}

0 comments on commit a043bf8

Please sign in to comment.