From 353c595a252c08326001075684684159c795fce7 Mon Sep 17 00:00:00 2001 From: "Stephen F. Booth" Date: Tue, 31 Oct 2023 11:33:58 -0500 Subject: [PATCH] Add constants for calendar cycles --- .../JDN+GregorianCalendar.swift | 42 +++++++++++-------- .../JulianDayNumber/JDN+IslamicCalendar.swift | 42 +++++++++++-------- .../JulianDayNumber/JDN+JulianCalendar.swift | 42 +++++++++++-------- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/Sources/JulianDayNumber/JDN+GregorianCalendar.swift b/Sources/JulianDayNumber/JDN+GregorianCalendar.swift index 8af924e..fd2c18c 100644 --- a/Sources/JulianDayNumber/JDN+GregorianCalendar.swift +++ b/Sources/JulianDayNumber/JDN+GregorianCalendar.swift @@ -6,6 +6,16 @@ import Foundation +/// The number of years in a cycle of the Gregorian calendar. +/// +/// A cycle in the Gregorian calendar consists of 303 common years and 97 leap years. +let gregorianCalendarCycleYears = 400 + +/// The number of days in a cycle of the Gregorian calendar. +/// +/// A cycle in the Gregorian calendar consists of 303 years of 365 days and 97 leap year of 366 days. +let gregorianCalendarCycleDays = 146097 + /// Converts a date in the Gregorian calendar to a Julian day number. /// /// The Julian day number (JDN) is the integer assigned to a whole solar day in the Julian day count starting from noon Universal Time, @@ -21,18 +31,16 @@ import Foundation /// - returns: The JDN corresponding to the requested date. public func gregorianCalendarDateToJulianDayNumber(year Y: Int, month M: Int, day D: Int) -> Int { var Y = Y - var ΔleapCycles = 0 + var ΔcalendarCycles = 0 // Richards' algorithm is only valid for positive JDNs. // JDN 0 is -4713-Nov-24 in the proleptic Gregorian calendar. // Adjust the year of earlier dates forward in time by a multiple of - // 400 (to account for leap years in the Gregorian calendar) - // before calculating the JDN and then translate the result backward - // in time by the period of adjustment. + // the calendar's cycle before calculating the JDN, and then translate + // the result backward in time by the period of adjustment. if Y < -4713 || (Y == -4713 && (M < 11 || (M == 11 && D < 24))) { - // 400 years * 365.2425 days/year = 146,097 days - ΔleapCycles = (-4714 - Y) / 400 + 1 - Y += ΔleapCycles * 400 + ΔcalendarCycles = (-4714 - Y) / gregorianCalendarCycleYears + 1 + Y += ΔcalendarCycles * gregorianCalendarCycleYears } let h = M - m @@ -42,8 +50,8 @@ public func gregorianCalendarDateToJulianDayNumber(year Y: Int, month M: Int, da var J = e + (s * f + t) / u J = J - (3 * ((g + A) / 100)) / 4 - C - if ΔleapCycles > 0 { - J -= ΔleapCycles * 146097 + if ΔcalendarCycles > 0 { + J -= ΔcalendarCycles * gregorianCalendarCycleDays } return J @@ -66,17 +74,15 @@ let latestSupportedGregorianCalendarJDN = latestSupportedJDN /// - returns: The calendar date corresponding to `J`. public func julianDayNumberToGregorianCalendarDate(_ J: Int) -> (year: Int, month: Int, day: Int) { var J = J - var ΔleapCycles = 0 + var ΔcalendarCycles = 0 // Richards' algorithm is only valid for positive JDNs. // Adjust negative JDNs forward in time by a multiple of - // 400 years (to account for leap years in the Gregorian calendar) - // before calculating the proleptic Gregorian date and then translate - // the result backward in time by the amount of forward adjustment. + // the calendar's cycle before calculating the JDN, and then translate + // the result backward in time by the period of adjustment. if J < 0 { - // 400 years * 365.2425 days/year = 146,097 days - ΔleapCycles = -J / 146097 + 1 - J += ΔleapCycles * 146097 + ΔcalendarCycles = -J / gregorianCalendarCycleDays + 1 + J += ΔcalendarCycles * gregorianCalendarCycleDays } var f = J + j @@ -88,8 +94,8 @@ public func julianDayNumberToGregorianCalendarDate(_ J: Int) -> (year: Int, mont let M = ((h / s + m) % n) + 1 var Y = e / p - y + (n + m - M) / n - if ΔleapCycles > 0 { - Y -= ΔleapCycles * 400 + if ΔcalendarCycles > 0 { + Y -= ΔcalendarCycles * gregorianCalendarCycleYears } return (Y, M, D) diff --git a/Sources/JulianDayNumber/JDN+IslamicCalendar.swift b/Sources/JulianDayNumber/JDN+IslamicCalendar.swift index e168082..898a65a 100644 --- a/Sources/JulianDayNumber/JDN+IslamicCalendar.swift +++ b/Sources/JulianDayNumber/JDN+IslamicCalendar.swift @@ -7,6 +7,16 @@ import Foundation +/// The number of years in a cycle of the Islamic calendar. +/// +/// A cycle in the Islamic calendar consists of 19 common years and 11 leap years. +let islamicCalendarCycleYears = 30 + +/// The number of days in a cycle of the Islamic calendar. +/// +/// A cycle in the Islamic calendar consists of 19 years of 354 days and 11 leap years of 355 days. +let islamicCalendarCycleDays = 10631 + /// Converts a date in the Islamic calendar to a Julian day number. /// /// The Julian day number (JDN) is the integer assigned to a whole solar day in the Julian day count starting from noon Universal Time, @@ -22,18 +32,16 @@ import Foundation /// - returns: The JDN corresponding to the requested date. public func islamicCalendarDateToJulianDayNumber(year Y: Int, month M: Int, day D: Int) -> Int { var Y = Y - var ΔleapCycles = 0 + var ΔcalendarCycles = 0 // Richards' algorithm is only valid for positive JDNs. // JDN 0 is -5498-08-16 in the proleptic Islamic calendar. // Adjust the year of earlier dates forward in time by a multiple of - // 30 (to account for leap years in the Islamic calendar) - // before calculating the JDN and then translate the result backward - // in time by the period of adjustment. + // the calendar's cycle before calculating the JDN, and then translate + // the result backward in time by the period of adjustment. if Y < -5498 || (Y == -5498 && (M < 8 || (M == 8 && D < 16))) { - // 30 years = 10,631 days (19 years of 354 days and 11 leap years of 355 days) - ΔleapCycles = (-5498 - Y) / 30 + 1 - Y += ΔleapCycles * 30 + ΔcalendarCycles = (-5498 - Y) / islamicCalendarCycleYears + 1 + Y += ΔcalendarCycles * islamicCalendarCycleYears } let h = M - m @@ -42,8 +50,8 @@ public func islamicCalendarDateToJulianDayNumber(year Y: Int, month M: Int, day let e = (p * g + q) / r + D - 1 - j var J = e + (s * f + t) / u - if ΔleapCycles > 0 { - J -= ΔleapCycles * 10631 + if ΔcalendarCycles > 0 { + J -= ΔcalendarCycles * islamicCalendarCycleDays } return J @@ -66,17 +74,15 @@ let latestSupportedIslamicCalendarJDN = 37384751 /// - returns: The calendar date corresponding to `J`. public func julianDayNumberToIslamicCalendarDate(_ J: Int) -> (year: Int, month: Int, day: Int) { var J = J - var ΔleapCycles = 0 + var ΔcalendarCycles = 0 // Richards' algorithm is only valid for positive JDNs. // Adjust negative JDNs forward in time by a multiple of - // 30 years (to account for leap years in the Islamic calendar) - // before calculating the proleptic Islamic date and then translate - // the result backward in time by the amount of forward adjustment. + // the calendar's cycle before calculating the JDN, and then translate + // the result backward in time by the period of adjustment. if J < 0 { - // 30 years = 10,631 days (19 years of 354 days and 11 leap years of 355 days) - ΔleapCycles = -J / 10631 + 1 - J += ΔleapCycles * 10631 + ΔcalendarCycles = -J / islamicCalendarCycleDays + 1 + J += ΔcalendarCycles * islamicCalendarCycleDays } let f = J + j @@ -87,8 +93,8 @@ public func julianDayNumberToIslamicCalendarDate(_ J: Int) -> (year: Int, month: let M = ((h / s + m) % n) + 1 var Y = e / p - y + (n + m - M) / n - if ΔleapCycles > 0 { - Y -= ΔleapCycles * 30 + if ΔcalendarCycles > 0 { + Y -= ΔcalendarCycles * islamicCalendarCycleYears } return (Y, M, D) diff --git a/Sources/JulianDayNumber/JDN+JulianCalendar.swift b/Sources/JulianDayNumber/JDN+JulianCalendar.swift index 124fa79..361fdef 100644 --- a/Sources/JulianDayNumber/JDN+JulianCalendar.swift +++ b/Sources/JulianDayNumber/JDN+JulianCalendar.swift @@ -6,6 +6,16 @@ import Foundation +/// The number of years in a cycle of the Julian calendar. +/// +/// A cycle in the Julian calendar consists of 3 common years and 1 leap year. +let julianCalendarCycleYears = 4 + +/// The number of days in a cycle of the Julian calendar. +/// +/// A cycle in the Julian calendar consists of 3 years of 365 days and 1 leap year of 366 days. +let julianCalendarCycleDays = 1461 + /// Converts a date in the Julian calendar to a Julian day number. /// /// The Julian day number (JDN) is the integer assigned to a whole solar day in the Julian day count starting from noon Universal Time, @@ -20,18 +30,16 @@ import Foundation /// - returns: The JDN corresponding to the requested date. public func julianCalendarDateToJulianDayNumber(year Y: Int, month M: Int, day D: Int) -> Int { var Y = Y - var ΔleapCycles = 0 + var ΔcalendarCycles = 0 // Richards' algorithm is only valid for positive JDNs. // JDN 0 is -4712-01-01 in the proleptic Julian calendar. // Adjust the year of earlier dates forward in time by a multiple of - // 4 (the frequency of leap years in the Julian calendar) - // before calculating the JDN and then translate the result backward - // in time by the period of adjustment. + // the calendar's cycle before calculating the JDN, and then translate + // the result backward in time by the period of adjustment. if Y < -4712 { - // 4 years * 365.25 days/year = 1,461 days - ΔleapCycles = (-4713 - Y) / 4 + 1 - Y += ΔleapCycles * 4 + ΔcalendarCycles = (-4713 - Y) / julianCalendarCycleYears + 1 + Y += ΔcalendarCycles * julianCalendarCycleYears } let h = M - m @@ -40,8 +48,8 @@ public func julianCalendarDateToJulianDayNumber(year Y: Int, month M: Int, day D let e = (p * g + q) / r + D - 1 - j var J = e + (s * f + t) / u - if ΔleapCycles > 0 { - J -= ΔleapCycles * 1461 + if ΔcalendarCycles > 0 { + J -= ΔcalendarCycles * julianCalendarCycleDays } return J @@ -64,17 +72,15 @@ let latestSupportedJulianCalendarJDN = 38246057 /// - returns: The calendar date corresponding to `J`. public func julianDayNumberToJulianCalendarDate(_ J: Int) -> (year: Int, month: Int, day: Int) { var J = J - var ΔleapCycles = 0 + var ΔcalendarCycles = 0 // Richards' algorithm is only valid for positive JDNs. // Adjust negative JDNs forward in time by a multiple of - // 4 years (the frequency of leap years in the Julian calendar) - // before calculating the proleptic Julian date and then translate - // the result backward in time by the amount of forward adjustment. + // the calendar's cycle before calculating the JDN, and then translate + // the result backward in time by the period of adjustment. if J < 0 { - // 4 years * 365.25 days/year = 1,461 days - ΔleapCycles = -J / 1461 + 1 - J += ΔleapCycles * 1461 + ΔcalendarCycles = -J / julianCalendarCycleDays + 1 + J += ΔcalendarCycles * julianCalendarCycleDays } let f = J + j @@ -85,8 +91,8 @@ public func julianDayNumberToJulianCalendarDate(_ J: Int) -> (year: Int, month: let M = ((h / s + m) % n) + 1 var Y = e / p - y + (n + m - M) / n - if ΔleapCycles > 0 { - Y -= ΔleapCycles * 4 + if ΔcalendarCycles > 0 { + Y -= ΔcalendarCycles * julianCalendarCycleYears } return (Y, M, D)