Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Sources/JulianDayNumber/ArmenianCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ public struct ArmenianCalendar: Calendar {
/// The converter for the Armenian calendar.
static let converter = JDNConverter(y: 5268, j: 317, m: 0, n: 13, r: 1, p: 365, q: 0, v: 0, u: 1, s: 30, t: 0, w: 0)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
converter.julianDayNumberFromDate(date)
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try converter.julianDayNumberFromDate(date)
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
converter.dateFromJulianDayNumber(J)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
try converter.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
12 changes: 8 additions & 4 deletions Sources/JulianDayNumber/AstronomicalCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ public struct AstronomicalCalendar: Calendar {
/// - parameter date: A date to convert.
///
/// - returns: The Julian day number corresponding to the specified date.
public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
date < firstGregorianCalendarDate ? JulianCalendar.julianDayNumberFromDate(date) : GregorianCalendar.julianDayNumberFromDate(date)
///
/// - throws: An error if the date could not be converted to a Julian Day Number.
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
date < firstGregorianCalendarDate ? try JulianCalendar.julianDayNumberFromDate(date) : try GregorianCalendar.julianDayNumberFromDate(date)
}

/// Converts a Julian day number to a date in the astronomical calendar.
Expand All @@ -38,8 +40,10 @@ public struct AstronomicalCalendar: Calendar {
/// - parameter J: A Julian day number.
///
/// - returns: The date corresponding to the specified Julian day number.
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
J < GregorianCalendar.effectiveJulianDayNumber ? JulianCalendar.dateFromJulianDayNumber(J): GregorianCalendar.dateFromJulianDayNumber(J)
///
/// - throws: An error if the Julian Day Number could not be converted to a date.
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
J < GregorianCalendar.effectiveJulianDayNumber ? try JulianCalendar.dateFromJulianDayNumber(J): try GregorianCalendar.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
8 changes: 4 additions & 4 deletions Sources/JulianDayNumber/BahaiCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ public struct BahaiCalendar: Calendar {
/// The converter for the Baháʼí calendar.
static let converter = JDNGregorianConverter(y: 6560, j: 1412, m: 19, n: 20, r: 4, p: 1461, q: 0, v: 3, u: 1, s: 19, t: 0, w: 0, A: 184, B: 274273, C: -50)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
converter.julianDayNumberFromDate(date)
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try converter.julianDayNumberFromDate(date)
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
converter.dateFromJulianDayNumber(J)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
try converter.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
18 changes: 12 additions & 6 deletions Sources/JulianDayNumber/Calendar+JulianDate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ extension Calendar {
/// - parameter s: A second number on the half-open interval `[0, 60)`.
///
/// - returns: The Julian date corresponding to the specified year, month, day, hour, minute, and second.
public static func julianDateFrom(year Y: Year, month M: Month, day D: Day, hour h: Hour = 0, minute m: Minute = 0, second s: Second = 0) -> JulianDate {
julianDateFrom(year: Y, month: M, day: Double(D) + fractionalDayFrom(hour: h, minute: m, second: s))
///
/// - throws: An error if the year, month, day, hour, minute, and second could not be converted to a Julian date.
public static func julianDateFrom(year Y: Year, month M: Month, day D: Day, hour h: Hour = 0, minute m: Minute = 0, second s: Second = 0) throws -> JulianDate {
try julianDateFrom(year: Y, month: M, day: Double(D) + fractionalDayFrom(hour: h, minute: m, second: s))
}

/// Converts the specified year, month, and decimal fractional day to a Julian date and returns the result.
Expand All @@ -53,20 +55,24 @@ extension Calendar {
/// - parameter D: A decimal fractional day number.
///
/// - returns: The Julian date corresponding to the specified year, month, and decimal day.
public static func julianDateFrom(year Y: Year, month M: Month, day D: FractionalDay) -> JulianDate {
///
/// - throws: An error if the year, month, and decimal fractional day could not be converted to a Julian date.
public static func julianDateFrom(year Y: Year, month M: Month, day D: FractionalDay) throws -> JulianDate {
let (day, dayFraction) = modf(D)
return Double(julianDayNumberFrom(year: Y, month: M, day: Int(day))) - 0.5 + dayFraction
return Double(try julianDayNumberFrom(year: Y, month: M, day: Int(day))) - 0.5 + dayFraction
}

/// Converts the specified Julian date to a year, month, day, hour, minute, and second and returns the result.
///
/// - parameter julianDate: A Julian date.
///
/// - returns: The year, month, day, hour, minute, and second corresponding to the specified Julian date.
public static func dateAndTimeFromJulianDate(_ julianDate: JulianDate) -> (year: Year, month: Month, day: Day, hour: Hour, minute: Minute, second: Second) {
///
/// - throws: An error if the Julian date could not be converted to a year, month, and decimal fractional day.
public static func dateAndTimeFromJulianDate(_ julianDate: JulianDate) throws -> (year: Year, month: Month, day: Day, hour: Hour, minute: Minute, second: Second) {
let julianDatePlus12Hours = julianDate + 0.5
let J = JulianDayNumber(julianDatePlus12Hours.rounded(.down))
let (Y, M, D) = dateFromJulianDayNumber(J)
let (Y, M, D) = try dateFromJulianDayNumber(J)
var (_, dayFraction) = modf(julianDatePlus12Hours)
if dayFraction < 0 {
dayFraction += 1
Expand Down
24 changes: 16 additions & 8 deletions Sources/JulianDayNumber/Calendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ extension Calendar {
/// - parameter D: A day number.
///
/// - returns: The Julian day number corresponding to the specified year, month, and day.
public static func julianDayNumberFrom(year Y: Year, month M: Month, day D: Day) -> JulianDayNumber {
julianDayNumberFromDate((Y, M, D))
///
/// - throws: An error if the year, month, and day could not be converted to a Julian Day Number.
public static func julianDayNumberFrom(year Y: Year, month M: Month, day D: Day) throws -> JulianDayNumber {
try julianDayNumberFromDate((Y, M, D))
}

/// An ordinal day.
Expand All @@ -90,8 +92,10 @@ extension Calendar {
/// - parameter D: A day number.
///
/// - returns: The ordinal day corresponding to the specified year, month, and day.
public static func ordinalDayFrom(year Y: Year, month M: Month, day D: Day) -> OrdinalDay {
OrdinalDay(julianDayNumberFrom(year: Y, month: M, day: D) - julianDayNumberFrom(year: Y, month: 1, day: 1) + 1)
///
/// - throws: An error if the year, month, and day could not be converted to an ordinal day.
public static func ordinalDayFrom(year Y: Year, month M: Month, day D: Day) throws -> OrdinalDay {
try OrdinalDay(julianDayNumberFrom(year: Y, month: M, day: D) - julianDayNumberFrom(year: Y, month: 1, day: 1) + 1)
}

/// Converts a year and ordinal day to a year, month, and day and returns the result.
Expand All @@ -100,8 +104,10 @@ extension Calendar {
/// - parameter N: An ordinal day number.
///
/// - returns: The year, month, and day corresponding to the specified year and ordinal day.
public static func dateFrom(year Y: Year, ordinalDay N: OrdinalDay) -> DateType {
dateFromJulianDayNumber(julianDayNumberFrom(year: Y, month: 1, day: 1) + JulianDayNumber(N) - 1)
///
/// - throws: An error if the year and ordinal day could not be converted to a date.
public static func dateFrom(year Y: Year, ordinalDay N: OrdinalDay) throws -> DateType {
try dateFromJulianDayNumber(julianDayNumberFrom(year: Y, month: 1, day: 1) + JulianDayNumber(N) - 1)
}
}

Expand All @@ -114,7 +120,9 @@ extension Calendar {
/// - parameter calendar: The calendar to use for conversion.
///
/// - returns: The specified date converted to a date in the specified calendar.
public static func convert<C>(year Y: Year, month M: Month, day D: Day, to calendar: C.Type) -> C.DateType where C: CalendarProtocol {
convertDate((Y, M, D), using: calendar)
///
/// - throws: An error if the year, month, and day could not be converted to a date in the specified calendar.
public static func convert<C>(year Y: Year, month M: Month, day D: Day, to calendar: C.Type) throws -> C.DateType where C: CalendarProtocol {
try convertDate((Y, M, D), using: calendar)
}
}
8 changes: 4 additions & 4 deletions Sources/JulianDayNumber/CopticCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ public struct CopticCalendar: Calendar {
/// The converter for the Coptic calendar.
static let converter = JDNConverter(y: 4996, j: 124, m: 0, n: 13, r: 4, p: 1461, q: 0, v: 3, u: 1, s: 30, t: 0, w: 0)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
converter.julianDayNumberFromDate(date)
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try converter.julianDayNumberFromDate(date)
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
converter.dateFromJulianDayNumber(J)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
try converter.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
8 changes: 4 additions & 4 deletions Sources/JulianDayNumber/EgyptianCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ public struct EgyptianCalendar: Calendar {
/// The converter for the Egyptian calendar.
static let converter = JDNConverter(y: 3968, j: 47, m: 0, n: 13, r: 1, p: 365, q: 0, v: 0, u: 1, s: 30, t: 0, w: 0)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
converter.julianDayNumberFromDate(date)
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try converter.julianDayNumberFromDate(date)
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
converter.dateFromJulianDayNumber(J)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
try converter.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
8 changes: 4 additions & 4 deletions Sources/JulianDayNumber/EthiopianCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ public struct EthiopianCalendar: Calendar {
/// The converter for the Ethiopian calendar.
static let converter = JDNConverter(y: 4720, j: 124, m: 0, n: 13, r: 4, p: 1461, q: 0, v: 3, u: 1, s: 30, t: 0, w: 0)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
converter.julianDayNumberFromDate(date)
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try converter.julianDayNumberFromDate(date)
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
converter.dateFromJulianDayNumber(J)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
try converter.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
8 changes: 4 additions & 4 deletions Sources/JulianDayNumber/FrenchRepublicanCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ public struct FrenchRepublicanCalendar: Calendar {
/// The converter for the French Republican calendar.
static let converter = JDNGregorianConverter(y: 6504, j: 111, m: 0, n: 13, r: 4, p: 1461, q: 0, v: 3, u: 1, s: 30, t: 0, w: 0, A: 396, B: 578797, C: -51)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
converter.julianDayNumberFromDate(date)
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try converter.julianDayNumberFromDate(date)
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
converter.dateFromJulianDayNumber(J)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
try converter.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
4 changes: 2 additions & 2 deletions Sources/JulianDayNumber/GregorianCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public struct GregorianCalendar: Calendar {
// Fliegel, H.F. & van Flandern, T.C. 1968, Communications of the ACM, 11, 657.
// https://doi.org/10.1145/364096.364097

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
// Years greater than maxY cause arithmetic overflow
// when computing J even when the final result is ≤ .max
// N.B. this is an estimated upper bound
Expand Down Expand Up @@ -93,7 +93,7 @@ public struct GregorianCalendar: Calendar {
return J
}

public static func dateFromJulianDayNumber(_ JD: JulianDayNumber) -> DateType {
public static func dateFromJulianDayNumber(_ JD: JulianDayNumber) throws -> DateType {
// JDN values greater than maxJD cause arithmetic overflow
// when computing L
let maxJD = .max - 68569
Expand Down
4 changes: 2 additions & 2 deletions Sources/JulianDayNumber/HebrewCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public struct HebrewCalendar: Calendar {
/// The recurrence cycle of the Hebrew calendar is 689,472 years, 8,527,680 months, 35,975,351 weeks, or 251,827,457 days.
static let recurrenceCycle = (years: 689472, days: 251827457)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
var Y = date.year
var cycles = 0

Expand All @@ -85,7 +85,7 @@ public struct HebrewCalendar: Calendar {
return J
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
var J = J
var cycles = 0

Expand Down
34 changes: 19 additions & 15 deletions Sources/JulianDayNumber/ISOCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ public struct ISOCalendar: CalendarProtocol {
/// This JDN corresponds to January 3, 1 CE in the Julian calendar.
public static let epoch = GregorianCalendar.epoch

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
GregorianCalendar.julianDayNumberFromDate(dateFromISO(year: date.year, week: date.week, weekday: date.weekday))
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try GregorianCalendar.julianDayNumberFromDate(dateFromISO(year: date.year, week: date.week, weekday: date.weekday))
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
let (Y, M, D) = GregorianCalendar.dateFromJulianDayNumber(J)
return isoDateFrom(year: Y, month: M, day: D)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
let (Y, M, D) = try GregorianCalendar.dateFromJulianDayNumber(J)
return try isoDateFrom(year: Y, month: M, day: D)
}

/// Returns the number of ISO full weeks in a year.
Expand All @@ -56,13 +56,13 @@ public struct ISOCalendar: CalendarProtocol {
return 52
}

/// Returns the ISO weekday for the specified year, month, and day.
/// Returns the ISO weekday for the specified Gregorian year, month, and day.
///
/// - parameter Y: A Gregorian year number.
/// - parameter M: A month number.
/// - parameter D: A day number.
///
/// - returns: The ISO weekday from `1` (Monday) to `7` (Sunday) corresponding to the specified year, month, and day.
/// - returns: The ISO weekday from `1` (Monday) to `7` (Sunday) corresponding to the specified Gregorian year, month, and day.
static func isoWeekdayFrom(year Y: Int, month M: Int, day D: Int) -> WeekdayNumber {
let weekday = GregorianCalendar.dayOfWeekFrom(year: Y, month: M, day: D) - 1
return weekday < 1 ? weekday + 7 : weekday
Expand All @@ -73,15 +73,17 @@ public struct ISOCalendar: CalendarProtocol {
date.weekday > 0 && date.weekday <= 7 && date.week > 0 && date.week <= isoWeeksInYear(date.year)
}

/// Returns the ISO week date for the specified year, month, and day.
/// Returns the ISO week date for the specified Gregorian year, month, and day.
///
/// - parameter Y: A Gregorian year number.
/// - parameter M: A month number.
/// - parameter D: A day number.
///
/// - returns: The ISO week date corresponding to the specified year, month, and day.
public static func isoDateFrom(year Y: Int, month M: Int, day D: Int) -> (year: Year, week: WeekNumber, weekday: WeekdayNumber) {
let N = GregorianCalendar.ordinalDayFrom(year: Y, month: M, day: D)
/// - returns: The ISO week date corresponding to the specified Gregorian year, month, and day.
///
/// - throws: An error if the year, month, and day could not be converted to an ISO week date.
public static func isoDateFrom(year Y: Int, month M: Int, day D: Int) throws -> (year: Year, week: WeekNumber, weekday: WeekdayNumber) {
let N = try GregorianCalendar.ordinalDayFrom(year: Y, month: M, day: D)
let weekday = isoWeekdayFrom(year: Y, month: M, day: D)
let w = (10 + N - weekday) / 7
if w == 0 {
Expand All @@ -92,15 +94,17 @@ public struct ISOCalendar: CalendarProtocol {
return (Y, w, weekday)
}

/// Returns the date for the specified year, ISO week number, and ISO weekday number.
/// Returns the Gregorian date for the specified year, ISO week number, and ISO weekday number.
///
/// - parameter Y: A Gregorian year number.
/// - parameter week: An ISO week number.
/// - parameter weekday: An ISO weekday number.
///
/// - returns: The date corresponding to the specified Gregorian year, ISO week number, and ISO weekday number.
public static func dateFromISO(year Y: Year, week: WeekNumber, weekday: WeekdayNumber) -> (year: Int, month: Int, day: Int) {
/// - returns: The Gregorian date corresponding to the specified Gregorian year, ISO week number, and ISO weekday number.
///
/// - throws: An error if the year, ISO week number, and ISO weekday number could not be converted to a date.
public static func dateFromISO(year Y: Year, week: WeekNumber, weekday: WeekdayNumber) throws -> GregorianCalendar.DateType {
let N = week * 7 + weekday - isoWeekdayFrom(year: Y, month: 1, day: 4) - 3
return GregorianCalendar.dateFrom(year: Y, ordinalDay: N)
return try GregorianCalendar.dateFrom(year: Y, ordinalDay: N)
}
}
8 changes: 4 additions & 4 deletions Sources/JulianDayNumber/IslamicCalendar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ public struct IslamicCalendar: Calendar {
/// The converter for the Islamic calendar.
static let converter = JDNConverter(y: 5519, j: 7664, m: 0, n: 12, r: 30, p: 10631, q: 14, v: 15, u: 100, s: 2951, t: 51, w: 10)

public static func julianDayNumberFromDate(_ date: DateType) -> JulianDayNumber {
converter.julianDayNumberFromDate(date)
public static func julianDayNumberFromDate(_ date: DateType) throws -> JulianDayNumber {
try converter.julianDayNumberFromDate(date)
}

public static func dateFromJulianDayNumber(_ J: JulianDayNumber) -> DateType {
converter.dateFromJulianDayNumber(J)
public static func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> DateType {
try converter.dateFromJulianDayNumber(J)
}

/// The number of months in one year.
Expand Down
8 changes: 6 additions & 2 deletions Sources/JulianDayNumber/JDNConverter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ struct JDNConverter {
/// - parameter date: A date to convert.
///
/// - returns: The Julian day number corresponding to the specified date.
func julianDayNumberFromDate(_ date: Calendar.YearMonthDay) -> JulianDayNumber {
///
/// - throws: An error if the date could not be converted to a Julian Day Number.
func julianDayNumberFromDate(_ date: Calendar.YearMonthDay) throws -> JulianDayNumber {
// Arithmetic upper limit
// `Y` values larger than this cause overflow when `e` is computed
let maxY = (.max / p) - y + (n - (date.month - m)) / n
Expand Down Expand Up @@ -93,7 +95,9 @@ struct JDNConverter {
/// - parameter J: A Julian day number.
///
/// - returns: The date corresponding to the specified Julian day number.
func dateFromJulianDayNumber(_ J: JulianDayNumber) -> Calendar.YearMonthDay {
///
/// - throws: An error if the Julian Day Number could not be converted to a date.
func dateFromJulianDayNumber(_ J: JulianDayNumber) throws -> Calendar.YearMonthDay {
// Arithmetic upper limit
// `J` values larger than this cause overflow when `e` is computed
let maxJ = (.max - v) / r - j
Expand Down
Loading