Skip to content

Commit ba52cc1

Browse files
committed
added support for safek mukaf choma, updated code with KosherJava changes
1 parent bfe64d8 commit ba52cc1

File tree

4 files changed

+80
-94
lines changed

4 files changed

+80
-94
lines changed

KosherSwiftNew.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |spec|
22

33
spec.name = "KosherSwiftNew"
4-
spec.version = "1.0.7"
4+
spec.version = "1.0.9"
55
spec.summary = "KosherJava Zmanim API / Library ported to Swift."
66

77
spec.description = "This Zmanim library is an API for a specialized calendar that can calculate different astronomical times including sunrise and sunset and Jewish zmanim or religious times for prayers and other Jewish religious duties.

Sources/KosherSwift/ComplexZmanimCalendar.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -4033,7 +4033,7 @@ public class ComplexZmanimCalendar : ZmanimCalendar {
40334033
* @see getHalfDayBasedZman(Date, Date, double)
40344034
*/
40354035
public func getSofZmanShmaGRASunriseToFixedLocalChatzos() -> Date? {
4036-
return getHalfDayBasedZman(startOfHalfDay: getSunrise(), endOfHalfDay: getFixedLocalChatzos(), hours: 3);
4036+
return getHalfDayBasedZman(startOfHalfDay: getElevationAdjustedSunrise(), endOfHalfDay: getFixedLocalChatzos(), hours: 3);
40374037
}
40384038

40394039
/**
@@ -4053,7 +4053,7 @@ public class ComplexZmanimCalendar : ZmanimCalendar {
40534053
* @see getHalfDayBasedZman(Date, Date, double)
40544054
*/
40554055
public func getSofZmanTfilaGRASunriseToFixedLocalChatzos() -> Date? {
4056-
return getHalfDayBasedZman(startOfHalfDay: getSunrise(), endOfHalfDay: getFixedLocalChatzos(), hours: 4);
4056+
return getHalfDayBasedZman(startOfHalfDay: getElevationAdjustedSunrise(), endOfHalfDay: getFixedLocalChatzos(), hours: 4);
40574057
}
40584058

40594059
/**
@@ -4093,7 +4093,7 @@ public class ComplexZmanimCalendar : ZmanimCalendar {
40934093
* @see ZmanimCalendar#getHalfDayBasedZman(Date, Date, double)
40944094
*/
40954095
public func getMinchaKetanaGRAFixedLocalChatzosToSunset() -> Date? {
4096-
return getHalfDayBasedZman(startOfHalfDay: getFixedLocalChatzos(), endOfHalfDay: getSunset(), hours: 3.5);
4096+
return getHalfDayBasedZman(startOfHalfDay: getFixedLocalChatzos(), endOfHalfDay: getElevationAdjustedSunset(), hours: 3.5);
40974097
}
40984098

40994099
/**
@@ -4114,7 +4114,7 @@ public class ComplexZmanimCalendar : ZmanimCalendar {
41144114
* @see ZmanimCalendar#getHalfDayBasedZman(Date, Date, double)
41154115
*/
41164116
public func getPlagHaminchaGRAFixedLocalChatzosToSunset() -> Date? {
4117-
return getHalfDayBasedZman(startOfHalfDay: getFixedLocalChatzos(), endOfHalfDay: getSunset(), hours: 4.75);
4117+
return getHalfDayBasedZman(startOfHalfDay: getFixedLocalChatzos(), endOfHalfDay: getElevationAdjustedSunset(), hours: 4.75);
41184118
}
41194119

41204120
/**

Sources/KosherSwift/hebrewcalendar/JewishCalendar.swift

+41-6
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,13 @@ public class JewishCalendar {
302302
*/
303303
public var isMukafChoma: Bool = false
304304

305+
/**
306+
* Is the calendar set to have a safek (doubtful) Purim <em>demukafim</em>, where Purim is celebrated (mainly) on the 14th and the 15th of Adar.
307+
* @see #getIsSafekMukafChoma()
308+
* @see #setIsSafekMukafChoma(boolean)
309+
*/
310+
public var isSafekMukafChoma = false
311+
305312
/**
306313
* List of <em>parshiyos</em> or special <em>Shabasos</em>. ``NONE`` indicates a week without a <em>parsha</em>, while the enum for
307314
* the <em>parsha</em> of ``VZOS_HABERACHA`` exists for consistency, but is not currently used. The special <em>Shabasos</em> of
@@ -678,6 +685,29 @@ public class JewishCalendar {
678685
self.isMukafChoma = isMukafChoma;
679686
}
680687

688+
/**
689+
* Returns if the city is set as a city that may have been surrounded by a wall from the time of Yehoshua, and
690+
* Shushan Purim should be celebrated as well as regular Purim.
691+
* @return if the city is set as a city that may have been surrounded by a wall from the time of Yehoshua, and
692+
* Shushan Purim should be celebrated as well as regular Purim.
693+
* @see #setIsSafekMukafChoma(boolean)
694+
*/
695+
public func getIsSafekMukafChoma() -> Bool {
696+
return isSafekMukafChoma
697+
}
698+
699+
/**
700+
* Sets if the location may have been surrounded by a wall from the time of Yehoshua, and Shushan Purim should be
701+
* celebrated as well as regular Purim. This can be set for Baghdad Iraq, or other cities around the world that
702+
* have the status of a "Safek Mukaf Choma". There are multiple cities in Israel that have this status.
703+
* The exception being Yerushalayim.
704+
* @param isSafekMukafChoma if the city may have been surrounded by a wall from the time of Yehoshua.
705+
* @see #getIsSafekMukafChoma()
706+
*/
707+
public func setIsSafekMukafChoma(isSafekMukafChoma: Bool) {
708+
self.isSafekMukafChoma = isSafekMukafChoma
709+
}
710+
681711
/**
682712
* The internal date object that all the calculations are dependant on. Change this date to effect all the other methods of the class. By default the date is set to the system's current time with the system's current timezone.
683713
*/
@@ -1544,7 +1574,7 @@ public class JewishCalendar {
15441574
if (day == 15 || (day == 16 && !inIsrael)) {
15451575
return JewishCalendar.SUCCOS;
15461576
}
1547-
if (day >= 17 && day <= 20 || (day == 16 && inIsrael)) {
1577+
if (day >= 16 && day <= 20) {
15481578
return JewishCalendar.CHOL_HAMOED_SUCCOS;
15491579
}
15501580
if (day == 21) {
@@ -1641,7 +1671,7 @@ public class JewishCalendar {
16411671
*/
16421672
public func isYomTov() -> Bool {
16431673
let holidayIndex = getYomTovIndex();
1644-
if ((isErevYomTov() && (holidayIndex != JewishCalendar.HOSHANA_RABBA || (holidayIndex == JewishCalendar.CHOL_HAMOED_PESACH && getJewishDayOfMonth() != 20)))
1674+
if ((isErevYomTov() && !( holidayIndex == JewishCalendar.HOSHANA_RABBA || holidayIndex == JewishCalendar.CHOL_HAMOED_PESACH))
16451675
|| (isTaanis() && holidayIndex != JewishCalendar.YOM_KIPPUR) || holidayIndex == JewishCalendar.ISRU_CHAG) {
16461676
return false;
16471677
}
@@ -2018,17 +2048,22 @@ public class JewishCalendar {
20182048

20192049
/**
20202050
* Returns if the day is Purim (<a href="https://en.wikipedia.org/wiki/Purim#Shushan_Purim">Shushan Purim</a>
2021-
* in a mukaf choma and regular Purim in a non-mukaf choma).
2022-
* @return if the day is Purim (Shushan Purim in a mukaf choma and regular Purim in a non-mukaf choma)
2051+
* in a mukaf choma and regular Purim in a non-mukaf choma. On both days if {@link #setIsSafekMukafChoma(boolean)} is true).
2052+
* @return if the day is Purim (Shushan Purim in a mukaf choma and regular Purim in a non-mukaf choma or on both days
2053+
* if {@link #setIsSafekMukafChoma(boolean)} is true)
20232054
*
20242055
* @see #getIsMukafChoma()
20252056
* @see #setIsMukafChoma(boolean)
2057+
* @see #getIsSafekMukafChoma()
2058+
* @see #setIsSafekMukafChoma(boolean)
20262059
*/
20272060
public func isPurim() -> Bool {
20282061
if (isMukafChoma) {
2029-
return getYomTovIndex() == JewishCalendar.SHUSHAN_PURIM;
2062+
return getYomTovIndex() == JewishCalendar.SHUSHAN_PURIM
2063+
} else if (isSafekMukafChoma) {
2064+
return getYomTovIndex() == JewishCalendar.PURIM || getYomTovIndex() == JewishCalendar.SHUSHAN_PURIM
20302065
} else {
2031-
return getYomTovIndex() == JewishCalendar.PURIM;
2066+
return getYomTovIndex() == JewishCalendar.PURIM
20322067
}
20332068
}
20342069

Sources/KosherSwift/util/NOAACalculator.swift

+34-83
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,23 @@ public class NOAACalculator : AstronomicalCalculator {
5050
public init(geoLocation: GeoLocation) {
5151
NOAACalculator.geoLocation = geoLocation
5252
}
53+
54+
/**
55+
* An enum to indicate what type of solar event is being calculated.
56+
*/
57+
enum SolarEvent {
58+
/**SUNRISE A solar event related to sunrise*/case SUNRISE
59+
/**SUNSET A solar event related to sunset*/case SUNSET
60+
// possibly add the following in the future, if added, an IllegalArgumentException should be thrown in getSunHourAngle
61+
// /**NOON A solar event related to noon*/NOON, /**MIDNIGHT A solar event related to midnight*/MIDNIGHT
62+
}
5363

5464
/**
5565
* Returns the name of the algorithm.
5666
* @return the descriptive name of the algorithm.
5767
*/
5868
public func getCalculatorName() -> String {
59-
return "US National Oceanic and Atmospheric Administration Algorithm";
69+
return "US National Oceanic and Atmospheric Administration Algorithm"; // Implementation of the Jean Meeus algorithm
6070
}
6171

6272
/**
@@ -72,8 +82,7 @@ public class NOAACalculator : AstronomicalCalculator {
7282
public override func getUTCSunrise(date: Date, geoLocation: GeoLocation, zenith: Double, adjustForElevation: Bool) -> Double {
7383
let elevation = adjustForElevation ? geoLocation.getElevation() : 0;
7484
let adjustedZenith = adjustZenith(zenith: zenith, elevation: elevation);
75-
76-
var sunrise = NOAACalculator.getSunriseUTC(julianDay: NOAACalculator.getJulianDay(date: date), latitude: geoLocation.getLatitude(), longitude: -geoLocation.getLongitude(), zenith: adjustedZenith);
85+
var sunrise = NOAACalculator.getSunRiseSetUTC(julianDay: NOAACalculator.getJulianDay(date: date), latitude: geoLocation.getLatitude(), longitude: -geoLocation.getLongitude(), zenith: adjustedZenith, solarEvent: SolarEvent.SUNRISE);
7786
sunrise = sunrise / 60;
7887

7988
// ensure that the time is >= 0 and < 24
@@ -111,7 +120,7 @@ public class NOAACalculator : AstronomicalCalculator {
111120
let elevation = adjustForElevation ? geoLocation.getElevation() : 0;
112121
let adjustedZenith = adjustZenith(zenith: zenith, elevation: elevation);
113122

114-
var sunset = NOAACalculator.getSunsetUTC(julianDay: NOAACalculator.getJulianDay(date: date), latitude: geoLocation.getLatitude(), longitude: -geoLocation.getLongitude(),zenith: adjustedZenith);
123+
var sunset = NOAACalculator.getSunRiseSetUTC(julianDay: NOAACalculator.getJulianDay(date: date), latitude: geoLocation.getLatitude(), longitude: -geoLocation.getLongitude(),zenith: adjustedZenith, solarEvent: SolarEvent.SUNSET);
115124
sunset = sunset / 60;
116125

117126
// ensure that the time is >= 0 and < 24
@@ -360,28 +369,9 @@ public class NOAACalculator : AstronomicalCalculator {
360369
return toDegrees(radians: equationOfTime) * 4.0; // in minutes of time
361370
}
362371

363-
/**
364-
* Return the <a href="https://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun in
365-
* <a href="https://en.wikipedia.org/wiki/Radian">radians</a> at sunrise for the latitude.
366-
*
367-
* @param lat
368-
* the latitude of observer in degrees
369-
* @param solarDec
370-
* the declination angle of sun in degrees
371-
* @param zenith
372-
* the zenith
373-
* @return hour angle of sunrise in <a href="https://en.wikipedia.org/wiki/Radian">radians</a>
374-
*/
375-
private static func getSunHourAngleAtSunrise(lat: Double, solarDec: Double, zenith: Double) -> Double {
376-
let latRad = toRadians(degrees: lat);
377-
let sdRad = toRadians(degrees: solarDec);
378-
379-
return acos(cos(toRadians(degrees: zenith)) / (cos(latRad) * cos(sdRad)) - tan(latRad) * tan(sdRad)); // in radians
380-
}
381-
382372
/**
383373
* Returns the <a href="https://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun in <a href=
384-
* "https://en.wikipedia.org/wiki/Radian">radians</a>at sunset for the latitude.
374+
* "https://en.wikipedia.org/wiki/Radian">radians</a>at for the latitude.
385375
* @todo use - {@link #getSunHourAngleAtSunrise(double, double, double)} implementation to avoid duplication of code.
386376
*
387377
* @param lat
@@ -390,14 +380,19 @@ public class NOAACalculator : AstronomicalCalculator {
390380
* the declination angle of sun in degrees
391381
* @param zenith
392382
* the zenith
383+
* @param solarEvent
384+
* If the hour angle is for sunrise or sunset
393385
* @return the hour angle of sunset in <a href="https://en.wikipedia.org/wiki/Radian">radians</a>
394386
*/
395-
private static func getSunHourAngleAtSunset(lat: Double, solarDec: Double, zenith: Double) -> Double {
396-
let latRad = toRadians(degrees: lat);
397-
let sdRad = toRadians(degrees: solarDec);
398-
399-
let hourAngle = (acos(cos(toRadians(degrees: zenith)) / (cos(latRad) * cos(sdRad)) - tan(latRad) * tan(sdRad)));
400-
return -hourAngle; // in radians
387+
private static func getSunHourAngle(latitude: Double, solarDeclination: Double, zenith: Double, solarEvent: SolarEvent) -> Double {
388+
let latRad = toRadians(degrees: latitude);
389+
let sdRad = toRadians(degrees: solarDeclination);
390+
391+
var hourAngle = (acos(cos(toRadians(degrees: zenith)) / (cos(latRad) * cos(sdRad)) - tan(latRad) * tan(sdRad)));
392+
if (solarEvent == SolarEvent.SUNSET) {
393+
hourAngle = -hourAngle;
394+
}
395+
return hourAngle;
401396
}
402397

403398
/**
@@ -474,52 +469,6 @@ public class NOAACalculator : AstronomicalCalculator {
474469
return toDegrees(radians: atan(sin(hourAngle_rad) / ((cos(hourAngle_rad) * sin(lat_rad)) - (tan(dec_rad) * cos(lat_rad)))))+180.0;
475470

476471
}
477-
478-
/**
479-
* Return the <a href="https://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
480-
* of sunrise for the given day at the given location on earth.
481-
*
482-
* @param julianDay
483-
* the Julian day
484-
* @param latitude
485-
* the latitude of observer in degrees
486-
* @param longitude
487-
* the longitude of observer in degrees
488-
* @param zenith
489-
* the zenith
490-
* @return the time in minutes from zero UTC
491-
*/
492-
private static func getSunriseUTC(julianDay:Double, latitude:Double, longitude:Double, zenith:Double) -> Double {
493-
let julianCenturies = getJulianCenturiesFromJulianDay(julianDay: julianDay);
494-
495-
// Find the time of solar noon at the location, and use that declination. This is better than start of the
496-
// Julian day
497-
498-
let noonmin = getSolarNoonUTC(julianCenturies: julianCenturies, longitude: longitude);
499-
let tnoon = getJulianCenturiesFromJulianDay(julianDay: julianDay + noonmin / 1440.0);
500-
501-
// First pass to approximate sunrise (using solar noon)
502-
503-
var eqTime = getEquationOfTime(julianCenturies: tnoon);
504-
var solarDec = getSunDeclination(julianCenturies: tnoon);
505-
var hourAngle = getSunHourAngleAtSunrise(lat: latitude, solarDec: solarDec, zenith: zenith);
506-
507-
var delta = longitude - toDegrees(radians: hourAngle);
508-
var timeDiff = 4 * delta; // in minutes of time
509-
var timeUTC = 720 + timeDiff - eqTime; // in minutes
510-
511-
// Second pass includes fractional Julian Day in gamma calc
512-
513-
let newt = getJulianCenturiesFromJulianDay(julianDay: getJulianDayFromJulianCenturies(julianCenturies: julianCenturies) + timeUTC
514-
/ 1440.0);
515-
eqTime = getEquationOfTime(julianCenturies: newt);
516-
solarDec = getSunDeclination(julianCenturies: newt);
517-
hourAngle = getSunHourAngleAtSunrise(lat: latitude, solarDec: solarDec, zenith: zenith);
518-
delta = longitude - toDegrees(radians: hourAngle);
519-
timeDiff = 4 * delta;
520-
timeUTC = 720 + timeDiff - eqTime; // in minutes
521-
return timeUTC;
522-
}
523472

524473
/**
525474
* Return the <a href="https://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
@@ -572,7 +521,7 @@ public class NOAACalculator : AstronomicalCalculator {
572521
* @see #getUTCNoon(Calendar, GeoLocation)
573522
*/
574523
private static func getSolarNoonUTC(julianCenturies: Double, longitude: Double) -> Double {
575-
// First pass uses approximate solar noon to calculate equation of time
524+
// Only 1 pass for approximate solar noon to calculate equation of time
576525
let tnoon = getJulianCenturiesFromJulianDay(julianDay: getJulianDayFromJulianCenturies(julianCenturies: julianCenturies) + longitude / 360.0);
577526
var eqTime = getEquationOfTime(julianCenturies: tnoon);
578527
let solNoonUTC = 720 + (longitude * 4) - eqTime; // min
@@ -586,7 +535,7 @@ public class NOAACalculator : AstronomicalCalculator {
586535

587536
/**
588537
* Return the <a href="https://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
589-
* of sunset for the given day at the given location on earth.
538+
* of sunrise or sunset for the given day at the given location on earth.
590539
*
591540
* @param julianDay
592541
* the Julian day
@@ -596,13 +545,15 @@ public class NOAACalculator : AstronomicalCalculator {
596545
* longitude of observer in degrees
597546
* @param zenith
598547
* zenith
548+
* @param solarEvent
549+
* Is the calculation for sunrise or sunset
599550
* @return the time in minutes from zero Universal Coordinated Time (UTC)
600551
*/
601-
private static func getSunsetUTC(julianDay:Double, latitude:Double, longitude: Double, zenith:Double) -> Double {
552+
private static func getSunRiseSetUTC(julianDay: Double, latitude: Double, longitude: Double, zenith: Double, solarEvent: SolarEvent) -> Double {
602553
let julianCenturies = getJulianCenturiesFromJulianDay(julianDay: julianDay);
603554

604-
// Find the time of solar noon at the location, and use that declination. This is better than start of the
605-
// Julian day
555+
// Find the time of solar noon at the location, and use that declination.
556+
// This is better than start of the Julian day
606557

607558
let noonmin = getSolarNoonUTC(julianCenturies: julianCenturies, longitude: longitude);
608559
let tnoon = getJulianCenturiesFromJulianDay(julianDay: julianDay + noonmin / 1440.0);
@@ -611,7 +562,7 @@ public class NOAACalculator : AstronomicalCalculator {
611562

612563
var eqTime = getEquationOfTime(julianCenturies: tnoon);
613564
var solarDec = getSunDeclination(julianCenturies: tnoon);
614-
var hourAngle = getSunHourAngleAtSunset(lat: latitude, solarDec: solarDec, zenith: zenith);
565+
var hourAngle = getSunHourAngle(latitude: latitude, solarDeclination: solarDec, zenith: zenith, solarEvent: solarEvent);
615566

616567
var delta = longitude - toDegrees(radians: hourAngle);
617568
var timeDiff = 4 * delta;
@@ -623,7 +574,7 @@ public class NOAACalculator : AstronomicalCalculator {
623574
/ 1440.0);
624575
eqTime = getEquationOfTime(julianCenturies: newt);
625576
solarDec = getSunDeclination(julianCenturies: newt);
626-
hourAngle = getSunHourAngleAtSunset(lat: latitude, solarDec: solarDec, zenith: zenith);
577+
hourAngle = getSunHourAngle(latitude: latitude, solarDeclination: solarDec, zenith: zenith, solarEvent: solarEvent);
627578

628579
delta = longitude - toDegrees(radians: hourAngle);
629580
timeDiff = 4 * delta;

0 commit comments

Comments
 (0)