From 36a9d7dda2dc1294d3a326bb5efdebf097d1dafe Mon Sep 17 00:00:00 2001 From: KosherJava Date: Fri, 24 Apr 2026 15:04:07 -0400 Subject: [PATCH 01/12] Update CHANGELOG with latest 3.0.0 changes in the modernization branch --- CHANGELOG.md | 78 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79822449..7e466db8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,74 @@ ## 3.0.0 (future) ### Includes breaking changes -* Remove deprecated methods flagged for removal. -* Remove deprecated classes such as the redundant [GeoLocationUtils](https://github.com/KosherJava/zmanim/blob/master/src/main/java/com/kosherjava/zmanim/util/GeoLocationUtils.java). -* Possibly rename some classes such as the confusingly named [ComplexZmanimCalendar](https://github.com/KosherJava/zmanim/blob/master/src/main/java/com/kosherjava/zmanim/ComplexZmanimCalendar.java). +* Remove deprecated methods flagged for removal, including + * `ComprehensiveZmanimcalendar` class + * `getSofZmanShmaKolEliyahu()` + * `getTzaisGeonim3Point65Degrees()` - was prior to 13.5 minutes in Yerushalayim at the equinox/equilux. + * `getTzaisGeonim3Point676Degrees()` - was prior to 13.5 minutes in Yerushalayim at the equinox/equilux. + * `getSofZmanTfilahAteretTorah()` - use the `getSofZmanTfilaAteretTorah()` + * `getSofZmanShmaFixedLocal()` + * `getSofZmanTfilaFixedLocal()` + * `getMinchaGedolaBaalHatanyaGreaterThan30()` should now be calculated via `ZmanimCalendar.getMinchaGedolaGreaterThan30(Instant minchaGedolaBaalHatanya)` + * `getFixedLocalChatzosBasedZmanim(Date, Date, double)` + * Move ErevPesach zmanim to generic methods in the parent `ZmanimCalendar` class. + * Move `getSunriseBaalHatanya()` and `getSunsetBaalHatanya()` to the parent `ZmanimCalendar` class. + * various mispelled getBainHasmashos based zmanim (use the properly spelled getBainHasmashos versions + * `JewishCalendar` class + * `isVeseinTalUmatarStartDate()` - use `TefilaRules.isVeseinTalUmatarStartDate()` + * `isVeseinTalUmatarStartingTonight()` - use `TefilaRules.isVeseinTalUmatarStartingTonight()` + * `isVeseinTalUmatarRecited()` - use `TefilaRiles.isVeseinTalUmatarRecited()` + * `isVeseinBerachaRecited()` - use `TefilaRules.isVeseinBerachaRecited()` + * `isMashivHaruachStartDate` - use `TefilaRules.isMashivHaruachStartDate()` + * `isMashivHaruachEndDate()` - use `TefilaRules.isMashivHaruachEndDate()` + * `isMashivHaruachRecited()` - use `TefilaRules.isMashivHaruachRecited()` + * `isMoridHatalRecited()` - use `TefilaRules.isMoridHatalRecited()` +* Remove deprecated redundant [GeoLocationUtils](https://github.com/KosherJava/zmanim/blob/master/src/main/java/com/kosherjava/zmanim/util/GeoLocationUtils.java). Use the GeoLocation class instead. +* Move some methods from `ComprehensiveZmanimCalendar` to the parent `ZaminCalendar` classes. + * `getShaahZmanis72Minutes()` + * `getAlos16Point1Degrees()` + * `getSofZmanShmaMGA72Minutes()` + * `getSofZmanTfilaMGA72Minutes()` + * `getTzaisGeonim8Point5Degrees()` + * `getZmanisBasedOffset(double)` +* `ZmanimCalendar` class rename some genericly named method names to be more specific. The actual zmanim were not chnaged. + * rename `getTzais()` -> `getTzaisGeonim8Point5Degrees()` + * `getAlosHashachar()` -> `getAlos16Point1Degrees()` + * `getSofZmanShmaMGA()` -> `getSofZmanShmaMGA72Minutes()` + * `getSofZmanTfilaMGA()` -> `getSofZmanTfilaMGA72Minutes()` + * `getMinchaGedola()` -> `getMinchaGedolaGRA()` + * `getMinchaKetana()` -> `getMinchaKetanaGRA()` + * `getPlagHamincha()` -> `getPlagHaminchaGRA()` + * `getShaahZmanisMGA() ` -> `getShaahZmanis72Minutes()` + * `getAlos72()` -> `getAlos72Minutes()` + * `getTzais72()` -> `getTzais72Minutes()` + * `getShaahZmanisGra()` -> `getShaahZmanisGRA()` + * `getAlos120()` -> `getAlos120Minutes()` + * `getAlos96()` -> `getAlos96Minutes()` + * `getAlos90()` -> `getAlos90Minutes()` + * `getAlos72()` -> `getAlos72Minutes()` + * `getAlos60()` -> `getAlos60Minutes()` + * `getTzais50()` -> `getTzais50Minutes()` + * `getTzais60()` -> `getTzais60Minutes()` + * `getTzais72()` -> `getTzais72Minutes()` + * `getTzais90()` -> `getTzais90Minutes()` + * `getTzais96()` -> `getTzais96Minutes()` + * `getTzais120()` -> `getTzais120Minutes()` +* Rename some classes the confusingly named `ComplexZmanimCalendar` to `ComrehensiveZmanimCalendar`. +* Move "legacy" classes to `java.time` equivelants + * All zmanim now return `Instant`s insead of `Date` objects. + * Replace `SimpledateFormat` with `DateTimeFormatter` + * `Calendar` and `GregorianCalendar` were replaced with `LocalDate` or `ZonedDateTime`. + * `TimeZone` was replace with `ZoneId` + * `GeoLocation.getLocalMeanTimeOffset()` and `getAntimeridianAdjustment()` now takes in `Instant` parameter. + * Remove the no longer necessary `NOAACalculator.adjustHourForTimeZone(Calendar)` * `getSofZman*Chametz*` times will retun null if it is not _Erev Pesach_. -* Possibly increase the minimum supported JRE version from version 8 (the code currently almost certainly works on 6 today). -* ... - -## [2.6.0](https://github.com/KosherJava/zmanim/compare/2.5.0...master) (future) - +* Increase the minimum supported JRE version from version 8 (the code currently almost certainly works on 6 today) to Java 11 or higher. +* `JewishCalendar` now has plus and minus methods (matching the `java.time.LocalDate` class) for years, months and days. +* Tweaked logic in `AstronomicalCalendar.getInstantFromTime()` to address issues near the dateline. +* Improve null handling in `ComplexZmanimCalendar.getMoladBasedTime()` +* Add `ComplexZmanimCalendar.getMisheyakir12Point85Degrees()` +* `ComprehensiveZmanimcalendar.getMinchaGedolaGreaterThan30()` was moved to the parent `ZmanimCalendar.getMinchaGedolaGreaterThan30(Instant)` that allows it to work with any mincha gedola claculation. +* Change `ComprehensiveZmanimcalendar.getTzaisGeonim4Point61Degrees()` to `getTzaisGeonim4Point65Degrees()` - was too early. * `ZmanimCalendar` [Astronomical Chatzos based changes](https://github.com/KosherJava/zmanim/commit/c523424b327f173d70f024bdf207ccae0413d487): * Add setting `useAstronomicalChatzos` (defaulted to true) to keep the mistaken compat break introduced in the v2.5.0 release. * Add setting `useAstronomicalChatzosForOtherZmanim` (defaulted to false). @@ -16,7 +76,7 @@ * Use `useAstronomicalChatzos` to control if `getChatzos()` returns `getSunTransit()` (astronomical chatzos) or getChatzosAsHalfDay(). * Add `getHalfDayBasedZman(Date startOfHalfDay, Date endOfHalfDay, double hours)` to allow other zmanim to be impacted by chatzos. * Use `useAstronomicalChatzosForOtherZmanim`. - * `ZmanimCalendar` - add utility method [getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset)`](https://github.com/KosherJava/zmanim/commit/60d1f09322835835035afa507ac2dc852f1cb033) to simplify zmaniyos time calculations. This allows calculations of various percentage of the day zmanim calculations. + * `ZmanimCalendar` - add utility method `[getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset)`](https://github.com/KosherJava/zmanim/commit/60d1f09322835835035afa507ac2dc852f1cb033) to simplify zmaniyos time calculations. This allows calculations of various percentage of the day zmanim calculations. * Use Astronomical Chatzos Halayla (as opposed as halfway between sunset and sunrise or 12 hours after chatzos hayom) * `AstronomicalCalculator` - [add `getSunLowerTransit()`](https://github.com/KosherJava/zmanim/commit/a76a3b65aeb45912bfdb02ce354f74bb97a9d9b2) * `AstronomicalCalculator` - [add abstract method `getUTCMidnight()`](https://github.com/KosherJava/zmanim/commit/f1904b12393c48b069d1333a7397fce66804958d) From c8aa19b9dba3d8fe7b23c56c12a7e905e2864721 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Fri, 24 Apr 2026 15:21:37 -0400 Subject: [PATCH 02/12] CHANGELOG update for 3.0.0 --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e466db8..dc103971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,7 +68,10 @@ * Improve null handling in `ComplexZmanimCalendar.getMoladBasedTime()` * Add `ComplexZmanimCalendar.getMisheyakir12Point85Degrees()` * `ComprehensiveZmanimcalendar.getMinchaGedolaGreaterThan30()` was moved to the parent `ZmanimCalendar.getMinchaGedolaGreaterThan30(Instant)` that allows it to work with any mincha gedola claculation. -* Change `ComprehensiveZmanimcalendar.getTzaisGeonim4Point61Degrees()` to `getTzaisGeonim4Point65Degrees()` - was too early. +* Change `ComprehensiveZmanimcalendar` zmanim that were too early. + * `getTzaisGeonim4Point37Degrees()` -> `getTzaisGeonim4Point42Degrees()`. + * `getTzaisGeonim4Point61Degrees()` -> `getTzaisGeonim4Point65Degrees()` + * `getTzaisGeonim4Point65Degrees()` -> `getTzaisGeonim4Point66Degrees()` * `ZmanimCalendar` [Astronomical Chatzos based changes](https://github.com/KosherJava/zmanim/commit/c523424b327f173d70f024bdf207ccae0413d487): * Add setting `useAstronomicalChatzos` (defaulted to true) to keep the mistaken compat break introduced in the v2.5.0 release. * Add setting `useAstronomicalChatzosForOtherZmanim` (defaulted to false). From 04fb03278b88cd5313b48166938c796561a580a9 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Fri, 24 Apr 2026 15:40:31 -0400 Subject: [PATCH 03/12] Update CHANGELOG --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc103971..9fdcebc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,9 +86,8 @@ * `NOAACalculator` - [implement `getUTCMidnight()`](https://github.com/KosherJava/zmanim/commit/b93eea3388bfdcc2dd526bbcb1be37ddb88fee08) * `AstronomicalCalculator` - [add abstract method `getUTCMidnight()`](https://github.com/KosherJava/zmanim/commit/1223dd0b6ad2b492818aacc5eb478747989e0ace) * `ComplexZmanimCalendar` - [significant updates](https://github.com/KosherJava/zmanim/commit/46800aa750ac56c2da9bc55fbf976ea1a092221d) - * Deprecate `getTzaisGeonim3Point65Degrees()` and `getTzaisGeonim3Point676Degrees()`, very early tzais geonim time that are earlier than 13.5 minutes in Yerushalayim at the equinox / equilux. * Started coding some zmanim to use the half-day zmanim config. - * Deprecate `getFixedLocalChatzosBasedZmanim()` in favor of `getHalfDayBasedZman()` in the parent ZmanimCalendar class. + * Change `getFixedLocalChatzosBasedZmanim()` in favor of `getHalfDayBasedZman()` in the parent `ZmanimCalendar class. * `getFixedLocalChatzos()` now just calls the new getLocalMeanTime(12.0) in the grandparent AstronomicalCalendar class. * Remove `getSolarMidnight()` that was added to the AstronomicalCalendar grandparent class. * Undeprecate `getPlagAlosToSunset()` since it is not a zman that can be too late. From 76eaf40ea527bf5518a0b8a1a75dc7172eb7e242 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Sat, 25 Apr 2026 22:55:26 -0400 Subject: [PATCH 04/12] Add getChatzos(Instant begin, Instant end) as a wrapper for getSunTransit(Instant, Instant) - Also some JavaDoc cleanup --- .../com/kosherjava/zmanim/ZmanimCalendar.java | 1025 +++++++++++------ 1 file changed, 641 insertions(+), 384 deletions(-) diff --git a/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java b/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java index be75d52e..3c721c1a 100644 --- a/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java +++ b/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java @@ -15,40 +15,39 @@ */ package com.kosherjava.zmanim; -import java.util.Calendar; -import java.util.Date; +import java.time.Instant; +import java.time.LocalDate; +import java.util.Objects; import com.kosherjava.zmanim.hebrewcalendar.JewishCalendar; import com.kosherjava.zmanim.util.AstronomicalCalculator; import com.kosherjava.zmanim.util.GeoLocation; /** - * The ZmanimCalendar is a specialized calendar that can calculate sunrise, sunset and Jewish zmanim - * (religious times) for prayers and other Jewish religious duties. This class contains the main functionality of the - * Zmanim library. For a much more extensive list of zmanim, use the {@link ComprehensiveZmanimCalendar} that - * extends this class. See documentation for the {@link ComprehensiveZmanimCalendar} and {@link AstronomicalCalendar} for - * simple examples on using the API. + * The ZmanimCalendar is a specialized calendar that can calculate sunrise, sunset and Jewish zmanim (religious times) + * for prayers and other Jewish religious duties. This class contains the main functionality of the Zmanim library. For + * a much more extensive list of zmanim, use the {@link ComprehensiveZmanimCalendar} that extends this class. See + * documentation for the {@link ComprehensiveZmanimCalendar} and {@link AstronomicalCalendar} for simple examples on using the API. * Elevation based zmanim (even sunrise and sunset) should not be used lekula without the guidance - * of a posek. According to Rabbi Dovid Yehudah Bursztyn in his - * Zmanim Kehilchasam, 7th edition chapter 2, section 7 (pages 181-182) - * and section 9 (pages 186-187), no zmanim besides sunrise and sunset should use elevation. However, Rabbi Yechiel - * Avrahom Zilber in the Birur Halacha Vol. 6 Ch. 58 Pages - * 34 and - * 42 is of the opinion that elevation should be - * accounted for in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons should - * be factored into zmanim calculations. The setting defaults to false (elevation will not be used for - * zmanim calculations besides sunrise and sunset), unless the setting is changed to true in {@link - * #setUseElevation(boolean)}. This will impact sunrise and sunset-based zmanim such as {@link #getSunrise()}, - * {@link #getSunset()}, {@link #getSofZmanShmaGRA()}, alos-based zmanim such as {@link #getSofZmanShmaMGA()} - * that are based on a fixed offset of sunrise or sunset and zmanim based on a percentage of the day such as - * {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on sunrise and sunset. Even when set to - * true it will not impact zmanim that are a degree-based offset of sunrise and sunset, such as {@link - * ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()} since - * these zmanim are not linked to sunrise or sunset times (the calculations are based on the astronomical definition of - * sunrise and sunset calculated in a vacuum with the solar radius above the horizon), and are therefore not impacted by the use - * of elevation. - * For additional information on the halachic impact of elevation on zmanim see: + * of a posek. According to Rabbi Dovid Yehudah Bursztyn in his Zmanim Kehilchasam, 7th edition chapter 2, section 7 (pages 181-182) and section 9 (pages 186-187), no zmanim + * besides sunrise and sunset should use elevation. However, Rabbi Yechiel Avrahom Zilber in the Birur Halacha Vol. 6 Ch. 58 Pages 34 and 42 is of the opinion that elevation should be accounted for + * in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons should be factored into zmanim calculations. The + * setting defaults to false (elevation will not be used for zmanim calculations besides sunrise and sunset), unless the + * setting is changed to true in {@link setUseElevation(boolean)}. This will impact sunrise and sunset-based zmanim such as + * {@link getSunriseWithElevation()}, {@link getSunsetWithElevation()}, {@link getSofZmanShmaGRA()}, alos-based + * zmanim such as {@link getSofZmanShmaMGA72Minutes()} that are based on a fixed offset of sunrise or sunset and + * zmanim based on a percentage of the day such as {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} + * that are based on sunrise and sunset. Even when set to true it will not impact zmanim that are a degree-based offset of + * sunrise and sunset, such as {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link + * ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()} since these zmanim are not linked to sunrise or sunset times + * (the calculations are based on the astronomical definition of sunrise and sunset calculated in a vacuum with the solar radius + * above the horizon), and are therefore not impacted by the use of elevation. For additional information on the halachic + * impact of elevation on zmanim see: *
    *
  • Zmanei Halacha Lema'aseh 4th edition by Rabbi Yedidya Manat. @@ -71,33 +70,33 @@ public class ZmanimCalendar extends AstronomicalCalendar { /** - * Is elevation factored in for some zmanim (see {@link #isUseElevation()} for additional information). - * @see #isUseElevation() - * @see #setUseElevation(boolean) + * Is elevation factored in for some zmanim (see {@link isUseElevation()} for additional information). + * @see isUseElevation() + * @see setUseElevation(boolean) */ private boolean useElevation; /** - * Is elevation above sea level calculated for times besides sunrise and sunset. According to Rabbi Dovid Yehuda - * Bursztyn in his Zmanim Kehilchasam (second edition published - * in 2007) chapter 2 (pages 186-187) no zmanim besides sunrise and sunset should use elevation. However, - * Rabbi Yechiel Avrahom Zilber in the Birur Halacha Vol. 6 Ch. 58 Pages - * 34 and 42 is of the opinion that elevation should be - * accounted for in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons - * should be factored into zmanim calculations.The setting defaults to false (elevation will not be used for - * zmanim calculations), unless the setting is changed to true in {@link #setUseElevation(boolean)}. This will - * impact sunrise and sunset based zmanim such as {@link #getSunrise()}, {@link #getSunset()}, - * {@link #getSofZmanShmaGRA()}, alos based zmanim such as {@link #getSofZmanShmaMGA()} that are based on a - * fixed offset of sunrise or sunset and zmanim based on a percentage of the day such as {@link - * ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on sunrise and sunset. It will not impact - * zmanim that are a degree based offset of sunrise and sunset, such as - * {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()}. + * Is elevation above sea level calculated for times besides sunrise and sunset. According to Rabbi Dovid Yehuda Bursztyn in + * his Zmanim Kehilchasam (second edition published in 2007) chapter 2 + * (pages 186-187) no zmanim besides sunrise and sunset should use elevation. However, Rabbi Yechiel Avrahom Zilber + * in the Birur Halacha Vol. 6 Ch. 58 Pages 34 and 42 is of the opinion that elevation should be accounted + * for in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons should be + * factored into zmanim calculations.The setting defaults to false (elevation will not be used for zmanim + * calculations), unless the setting is changed to true in {@link setUseElevation(boolean)}. This will impact sunrise and + * sunset based zmanim such as {@link getSofZmanShmaGRA()}, alos based zmanim such as {@link + * getSofZmanShmaMGA72Minutes()} that are based on a fixed offset of sunrise or sunset and zmanim based on a + * percentage of the day such as {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on + * sunrise and sunset. It will not impact zmanim that are a degree based offset of sunrise and sunset, such as {@link + * ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link + * ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()}. * * @return if the use of elevation is active * - * @see #setUseElevation(boolean) + * @see setUseElevation(boolean) */ public boolean isUseElevation() { return useElevation; @@ -105,8 +104,8 @@ public boolean isUseElevation() { /** * Sets whether elevation above sea level is factored into zmanim calculations for times besides sunrise and sunset. - * See {@link #isUseElevation()} for more details. - * @see #isUseElevation() + * See {@link isUseElevation()} for more details. + * @see isUseElevation() * * @param useElevation set to true to use elevation in zmanim calculations */ @@ -118,36 +117,36 @@ public void setUseElevation(boolean useElevation) { * Is astronomical chatzos used for zmanim calculations. The default value of true will * keep the standard astronomical chatzos calculation, while setting it to false will use half of * a solar day calculation for chatzos. - * @see #isUseAstronomicalChatzos() - * @see #setUseAstronomicalChatzos(boolean) - * @see #getChatzos() - * @see #getSunTransit() - * @see #getChatzosAsHalfDay() - * @see #useAstronomicalChatzosForOtherZmanim + * @see isUseAstronomicalChatzos() + * @see setUseAstronomicalChatzos(boolean) + * @see getChatzos() + * @see getSunTransit() + * @see getChatzosAsHalfDay() + * @see useAstronomicalChatzosForOtherZmanim */ private boolean useAstronomicalChatzos = true; /** - * Is {@link #getSunTransit() astronomical chatzos} used for {@link #getChatzos()} for enhanced accuracy. For + * Is {@link getSunTransit() astronomical chatzos} used for {@link getChatzos()} for enhanced accuracy. For * example as the day lengthens, the second half of the day is longer than the first and astronomical chatzos * would be a drop earlier than half of the time between sunrise and sunset. * - * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link #getSofZmanShmaGRA() + * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link getSofZmanShmaGRA() * Sof zman Shma GRA} would be calculated as 3 shaos zmaniyos after sunrise, but the shaos * zmaniyos would be calculated a a 6th of the time between sunrise and chatzos, as opposed to a 12th of the - * time between sunrise and sunset. {@link #getMinchaGedola() mincha gedola} will be calculated as half a + * time between sunrise and sunset. {@link getMinchaGedolaGRA() mincha gedola} will be calculated as half a * shaah zmanis of afternoon hours (a 6th of the time between chatzos and sunset after astronomical - * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link #getPlagHamincha() Plag + * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link getPlagHaminchaGRA() Plag * hamincha} would be calculated as 4.75 shaos zmaniyos after astronomical chatzos as opposed to 10.75 * shaos zmaniyos after sunrise. Etc. * * @return if the use of astronomical chatzos is active. - * @see #useAstronomicalChatzos - * @see #setUseAstronomicalChatzos(boolean) - * @see #getChatzos() - * @see #getSunTransit() - * @see #getChatzosAsHalfDay() - * @see #isUseAstronomicalChatzosForOtherZmanim() + * @see useAstronomicalChatzos + * @see setUseAstronomicalChatzos(boolean) + * @see getChatzos() + * @see getSunTransit() + * @see getChatzosAsHalfDay() + * @see isUseAstronomicalChatzosForOtherZmanim() */ public boolean isUseAstronomicalChatzos() { return useAstronomicalChatzos; @@ -156,12 +155,12 @@ public boolean isUseAstronomicalChatzos() { /** * Sets if astronomical chatzos should be used in calculations of other zmanim for enhanced accuracy. * @param useAstronomicalChatzos set to true to use astronomical in chatzos in zmanim calculations. - * @see #useAstronomicalChatzos - * @see #isUseAstronomicalChatzos() - * @see #getChatzos() - * @see #getSunTransit() - * @see #getChatzosAsHalfDay() - * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) + * @see useAstronomicalChatzos + * @see isUseAstronomicalChatzos() + * @see getChatzos() + * @see getSunTransit() + * @see getChatzosAsHalfDay() + * @see setUseAstronomicalChatzosForOtherZmanim(boolean) */ public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) { this.useAstronomicalChatzos = useAstronomicalChatzos; @@ -171,11 +170,11 @@ public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) { * Is astronomical chatzos used for zmanim calculations besides chatzos itself for enhanced * accuracy. The default value of false will keep the standard start to end of day calculations, while setting * it to true will use half of a solar day calculation for zmanim. - * @see #isUseAstronomicalChatzosForOtherZmanim() - * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) - * @see #isUseAstronomicalChatzos() - * @see #setUseAstronomicalChatzos(boolean) - * @see #getChatzos() + * @see isUseAstronomicalChatzosForOtherZmanim() + * @see setUseAstronomicalChatzosForOtherZmanim(boolean) + * @see isUseAstronomicalChatzos() + * @see setUseAstronomicalChatzos(boolean) + * @see getChatzos() */ private boolean useAstronomicalChatzosForOtherZmanim = false; @@ -185,20 +184,20 @@ public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) { * the first and astronomical chatzos would be a drop earlier than half of the time between sunrise and sunset. * Conversely, the second half of the day would be shorter in the autumn as the days start getting shorter. * - * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link #getSofZmanShmaGRA() + * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link getSofZmanShmaGRA() * Sof zman Shma GRA} would be calculated as 3 shaos zmaniyos after sunrise, but the shaos * zmaniyos would be calculated a a 6th of the time between sunrise and chatzos, as opposed to a 12th of the - * time between sunrise and sunset. {@link #getMinchaGedola() mincha gedola} will be calculated as half a + * time between sunrise and sunset. {@link getMinchaGedolaGRA() mincha gedola GRA} will be calculated as half a * shaah zmanis of afternoon hours (a 6th of the time between chatzos and sunset after astronomical - * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link #getPlagHamincha() Plag + * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link getPlagHaminchaGRA() Plag * hamincha} would be calculated as 4.75 shaos zmaniyos after astronomical chatzos as opposed to 10.75 * shaos zmaniyos after sunrise. Etc. * * @return if the use of astronomical chatzos is active. - * @see #useAstronomicalChatzosForOtherZmanim - * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) - * @see #useAstronomicalChatzos - * @see #setUseAstronomicalChatzos(boolean) + * @see useAstronomicalChatzosForOtherZmanim + * @see setUseAstronomicalChatzosForOtherZmanim(boolean) + * @see useAstronomicalChatzos + * @see setUseAstronomicalChatzos(boolean) */ public boolean isUseAstronomicalChatzosForOtherZmanim() { return useAstronomicalChatzosForOtherZmanim; @@ -207,25 +206,16 @@ public boolean isUseAstronomicalChatzosForOtherZmanim() { /** * Sets if astronomical chatzos should be used in calculations of other zmanim for enhanced accuracy. * @param useAstronomicalChatzosForOtherZmanim set to true to use astronomical in chatzos in zmanim calculations. - * @see #useAstronomicalChatzos - * @see #isUseAstronomicalChatzos() + * @see useAstronomicalChatzos + * @see isUseAstronomicalChatzos() */ public void setUseAstronomicalChatzosForOtherZmanim(boolean useAstronomicalChatzosForOtherZmanim) { this.useAstronomicalChatzosForOtherZmanim = useAstronomicalChatzosForOtherZmanim; } /** - * The zenith of 16.1° below geometric zenith (90°). This calculation is used for determining alos - * (dawn) and tzais (nightfall) in some opinions. It is based on the calculation that the time between dawn - * and sunrise (and sunset to nightfall) is 72 minutes, the time that is takes to walk 4 mil at 18 minutes a mil (Rambam and others). The sun's position below the horizon 72 minutes - * before {@link #getSunrise() sunrise} in Jerusalem around the equinox / equilux is - * 16.1° below {@link #GEOMETRIC_ZENITH geometric zenith}. - * - * @see #getAlosHashachar() - * @see ComprehensiveZmanimCalendar#getAlos16Point1Degrees() + * The zenith of 16.1° below geometric zenith (90°). + * @see getAlos16Point1Degrees() * @see ComprehensiveZmanimCalendar#getTzais16Point1Degrees() * @see ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees() * @see ComprehensiveZmanimCalendar#getSofZmanTfilaMGA16Point1Degrees() @@ -238,145 +228,143 @@ public void setUseAstronomicalChatzosForOtherZmanim(boolean useAstronomicalChatz protected static final double ZENITH_16_POINT_1 = GEOMETRIC_ZENITH + 16.1; /** - * The zenith of 8.5° below geometric zenith (90°). This calculation is used for calculating alos - * (dawn) and tzais (nightfall) in some opinions. This calculation is based on the sun's position below the - * horizon 36 minutes after {@link #getSunset() sunset} in Jerusalem around the equinox / equilux, which - * is 8.5° below {@link #GEOMETRIC_ZENITH geometric zenith}. The Ohr Meir considers this the time that 3 small stars are visible, - * which is later than the required 3 medium stars. - * - * @see #getTzais() - * @see ComprehensiveZmanimCalendar#getTzaisGeonim8Point5Degrees() + * The zenith of 8.5° below geometric zenith (90°). + * @see getTzaisGeonim8Point5Degrees() */ protected static final double ZENITH_8_POINT_5 = GEOMETRIC_ZENITH + 8.5; + + /** + * The zenith of 1.583° below {@link GEOMETRIC_ZENITH geometric zenith} (90°). + * @see getSunriseBaalHatanya() + * @see getSunsetBaalHatanya() + */ + protected static final double ZENITH_1_POINT_583 = GEOMETRIC_ZENITH + 1.583; /** * The default Shabbos candle lighting offset is 18 minutes. This can be changed via the - * {@link #setCandleLightingOffset(double)} and retrieved by the {@link #getCandleLightingOffset()}. + * {@link setCandleLightingOffset(double)} and retrieved by the {@link getCandleLightingOffset()}. */ private double candleLightingOffset = 18; /** - * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the - * default), or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant zmanim - * in this and extending classes (such as the {@link ComprehensiveZmanimCalendar}) to automatically adjust to the elevation setting. + * This method will return {@link getSeaLevelSunrise() sea level sunrise} if {@link isUseElevation()} is false (the default), + * or elevation adjusted {@link getSunriseWithElevation()} if it is true. This allows relevant zmanim in this and + * extending classes (such as the {@link ComprehensiveZmanimCalendar}) to automatically adjust to the elevation setting. * - * @return {@link #getSeaLevelSunrise()} if {@link #isUseElevation()} is false (the default), or elevation adjusted - * {@link AstronomicalCalendar#getSunrise()} if it is true. - * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunrise() + * @return {@link getSeaLevelSunrise()} if {@link isUseElevation()} is false (the default), or elevation adjusted + * {@link getSunriseWithElevation()} if it is true. + * @see getSunriseWithElevation() */ - protected Date getElevationAdjustedSunrise() { + protected Instant getSunriseBasedOnElevationSetting() { if (isUseElevation()) { - return super.getSunrise(); + return super.getSunriseWithElevation(); } return getSeaLevelSunrise(); } /** - * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the default), - * or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant zmanim + * This method will return {@link getSeaLevelSunrise() sea level sunrise} if {@link isUseElevation()} is false (the default), + * or elevation adjusted {@link getSunriseWithElevation()} if it is true. This allows relevant zmanim * in this and extending classes (such as the {@link ComprehensiveZmanimCalendar}) to automatically adjust to the elevation setting. * - * @return {@link #getSeaLevelSunset()} if {@link #isUseElevation()} is false (the default), or elevation adjusted - * {@link AstronomicalCalendar#getSunset()} if it is true. - * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunset() + * @return {@link getSeaLevelSunset()} if {@link isUseElevation()} is false (the default), or elevation adjusted + * {@link getSunsetWithElevation()} if it is true. + * @see getSunsetWithElevation() */ - protected Date getElevationAdjustedSunset() { + protected Instant getSunsetBasedOnElevationSetting() { if (isUseElevation()) { - return super.getSunset(); + return super.getSunsetWithElevation(); } return getSeaLevelSunset(); } /** - * A method that returns tzais (nightfall) when the sun is {@link #ZENITH_8_POINT_5 8.5°} below the - * {@link #GEOMETRIC_ZENITH geometric horizon} (90°) after {@link #getSunset() sunset}, a time that Rabbi Meir - * Posen in his the Ohr Meir calculated that 3 small - * stars are visible, which is later than the required 3 medium stars. See the {@link #ZENITH_8_POINT_5} constant. - * - * @see #ZENITH_8_POINT_5 + * A method that returns tzais (nightfall) when the sun is {@link ZENITH_8_POINT_5 8.5°} below the + * {@link GEOMETRIC_ZENITH geometric horizon} (90°) after {@link getSunsetWithElevation() sunset}, a time that Rabbi + * Meir Posen in his the Ohr Meir calculated that 3 small + * stars are visible, which is later than the required 3 medium stars. This calculation is based on the sun's position below + * the horizon 36 minutes after {@link getSeaLevelSunrise() sunset} in Jerusalem around the equinox / equilux, which + * is 8.5° below {@link GEOMETRIC_ZENITH geometric zenith}. * - * @return The Date of nightfall. If the calculation can't be computed such as northern and southern + * @return The Instant of nightfall. If the calculation can't be computed such as northern and southern * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach * low enough below the horizon for this calculation, a null will be returned. See detailed * explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #ZENITH_8_POINT_5 * ComprehensiveZmanimCalendar#getTzaisGeonim8Point5Degrees() that returns an identical time to this generic tzais */ - public Date getTzais() { + public Instant getTzaisGeonim8Point5Degrees() { return getSunsetOffsetByDegrees(ZENITH_8_POINT_5); } /** - * Returns alos (dawn) based on the time when the sun is {@link #ZENITH_16_POINT_1 16.1°} below the - * eastern {@link #GEOMETRIC_ZENITH geometric horizon} before {@link #getSunrise() sunrise}. This is based on the + * Returns alos (dawn) based on the time when the sun is {@link ZENITH_16_POINT_1 16.1°} below the + * eastern {@link GEOMETRIC_ZENITH geometric horizon} before {@link getSunriseWithElevation() sunrise}. This is based on the * calculation that the time between dawn and sunrise (and sunset to nightfall) is 72 minutes, the time that is * takes to walk 4 mil at * 18 minutes a mil (Rambam and others). The sun's position - * below the horizon 72 minutes before {@link #getSunrise() sunrise} in Jerusalem on the around the equinox / equilux is - * 16.1° below {@link #GEOMETRIC_ZENITH}. + * 16.1° below {@link GEOMETRIC_ZENITH}. * - * @see #ZENITH_16_POINT_1 - * @see ComprehensiveZmanimCalendar#getAlos16Point1Degrees() + * @see ComprehensiveZmanimCalendar#getTzais16Point1Degrees() * - * @return The Date of dawn. If the calculation can't be computed such as northern and southern + * @return The Instant of dawn. If the calculation can't be computed such as northern and southern * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach * low enough below the horizon for this calculation, a null will be returned. See detailed * explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Date getAlosHashachar() { + public Instant getAlos16Point1Degrees() { return getSunriseOffsetByDegrees(ZENITH_16_POINT_1); } /** - * Method to return alos (dawn) calculated as 72 minutes before {@link #getSunrise() sunrise} or - * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting). This time + * Method to return alos (dawn) calculated as 72 minutes before {@link getSunriseWithElevation() sunrise} or + * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting). This time * is based on the time to walk the distance of 4 mil at 18 minutes a mil. The * 72-minute time (but not the concept of fixed minutes) is based on the opinion that the time of the Neshef * (twilight between dawn and sunrise) does not vary by the time of year or location but depends on the time it takes * to walk the distance of 4 mil. * - * @return the Date representing the time. If the calculation can't be computed such as in the Arctic + * @return the Instant representing the time. If the calculation can't be computed such as in the Arctic * Circle where there is at least one day a year where the sun does not rise, and one where it does not set, * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} * documentation. */ - public Date getAlos72() { - return getTimeOffset(getElevationAdjustedSunrise(), -72 * MINUTE_MILLIS); + public Instant getAlos72Minutes() { + return getTimeOffset(getSunriseBasedOnElevationSetting(), -72 * MINUTE_MILLIS); } /** - * This method returns {@link #getSunTransit() Astronomical chatzos} if the + * This method returns {@link getSunTransit() Astronomical chatzos} if the * {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculator} class used supports it and - * {@link #isUseAstronomicalChatzos() isUseAstronomicalChatzos()} is set to true or the {@link #getChatzosAsHalfDay() + * {@link isUseAstronomicalChatzos() isUseAstronomicalChatzos()} is set to true or the {@link getChatzosAsHalfDay() * halfway point between sunrise and sunset} if it does not support it, or it is not configured to use it. There are currently * two {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculators} available in the API, the default {@link * com.kosherjava.zmanim.util.NOAACalculator NOAA calculator} and the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO * calculator}. The USNO calculator calculates chatzos as halfway between sunrise and sunset (identical to six shaos - * zmaniyos after sunrise), while the NOAACalculator calculates it more accurately as {@link #getSunTransit() astronomical + * zmaniyos after sunrise), while the NOAACalculator calculates it more accurately as {@link getSunTransit() astronomical * chatzos}. See The Definition of Chatzos * for a detailed explanation of the ways to calculate Chatzos. Since half-day chatzos can be null in * the Arctic on a day when either sunrise or sunset did not happen and astronomical chatzos can be calculated even in the * Arctic, if half-day chatzos calculates as null and astronomical chatzos is supported by the * calculator, astronomical chatzos will be returned to avoid returning a null. * - * @see AstronomicalCalendar#getSunTransit() - * @see #getChatzosAsHalfDay() - * @see #isUseAstronomicalChatzos() - * @see #setUseAstronomicalChatzos(boolean) - * @return the Date of chatzos. If the calculation can't be computed such as in the Arctic Circle + * @see getSunTransit() + * @see getChatzosAsHalfDay() + * @see isUseAstronomicalChatzos() + * @see setUseAstronomicalChatzos(boolean) + * @return the Instant of chatzos. If the calculation can't be computed such as in the Arctic Circle * where there is at least one day where the sun does not rise, and one where it does not set, and the calculator does not * support astronomical calculations (that will never report a null) a null will be returned. * See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Date getChatzos() { - if (useAstronomicalChatzos) { + public Instant getChatzos() { + if (isUseAstronomicalChatzos()) { return getSunTransit(); // can be null of the calculator does not support astronomical chatzos } else { - Date halfDayChatzos = getChatzosAsHalfDay(); + Instant halfDayChatzos = getChatzosAsHalfDay(); if (halfDayChatzos == null) { return getSunTransit(); // can be null if the calculator does not support astronomical chatzos } else { @@ -385,10 +373,46 @@ public Date getChatzos() { } } + /** + * A method that returns chatzos (hayom or layla) calculated as halfway between the begin + * and end times passed in. If sunrise and sunset (or sunset and the following sunrise for chatzos halayla) + * are passed in, it will be close to, but not exactly occur when the Sun is transiting the celestial meridian due to changes in declination (the + * lengthening or shortening day). A practical example of using this would be calculating chatzos halayla for + * the night of Pesach, where Rav Shlomo Zalman + * Auerbach in the Halichos Shlomo considered chatzos halayla for the end of zman achilas afikoman + * to be halfway between an early tzais that is earlier (degree-wise) than alos the next morning, thus + * making this time earlier than astronomical chatzos. See The Definition of Chatzos for a detailed + * explanation of the ways to calculate Chatzos. This method is a convenience method that calls the parent class's + * {@link getSunTransit(Instant, Instant)}. + * + * @param begin + * the beginning of day or night for calculating chatzos. For chatzos hayom, this can be + * sea level sunrise, or any arbitrary sunrise or alos used as the beginning of the day, and for + * chatzos halayla this can be sea level sunset, or any arbitrary sunset or tzais used as + * the beginning of the night. + * @param end + * the end of day or night for calculating chatzos. For chatzos hayom, this can be sea level + * sunset, or any arbitrary sunset or tzais used as the end of day, and for chatzos halayla + * this can be sea level sunrise, or any arbitrary sunrise or alos used as the end of the night. + * + * @return the Instant representing chatzos. If the calculation can't be computed such as in the + * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does + * not set, null will be returned. See detailed explanation on top of the page. + * @see getSunTransit(Instant, Instant) + * @see getChatzosAsHalfDay() + * @see getChatzos() + */ + public Instant getChatzos(Instant begin, Instant end) { + return getSunTransit(begin, end); + } + /** * Returns chatzos calculated as halfway between sunrise and sunset. Many are of the opinion that - * chatzos is calculated as the midpoint between {@link #getSeaLevelSunrise() sea level sunrise} and - * {@link #getSeaLevelSunset() sea level sunset}, despite it not being the most accurate way to calculate it. A day + * chatzos is calculated as the midpoint between {@link getSeaLevelSunrise() sea level sunrise} and + * {@link getSeaLevelSunset() sea level sunset}, despite it not being the most accurate way to calculate it. A day * starting at alos and ending at tzais using the same time or degree offset will also return * the same time. In reality due to lengthening or shortening of day, this is not necessarily the exact midpoint of * the day, but it is very close. This method allows you to use the NOAACalculator and still calculate chatzos @@ -401,21 +425,22 @@ public Date getChatzos() { * zmaniyos after sunrise. See The Definition * of Chatzos for a detailed explanation of the ways to calculate Chatzos. * - * @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation) - * @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation) - * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation) - * @see AstronomicalCalendar#getSunTransit(Date, Date) - * @see #getChatzos() - * @see #getSunTransit() - * @see #isUseAstronomicalChatzos() + * @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(LocalDate, GeoLocation) + * @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(LocalDate, GeoLocation) + * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(LocalDate, GeoLocation) + * @see getSunTransit(Instant, Instant) + * @see getChatzos() + * @see getChatzos(Instant, Instant) + * @see getSunTransit() + * @see isUseAstronomicalChatzos() * - * @return the Date of the latest chatzos. If the calculation can't be computed such + * @return the Instant of the latest chatzos. If the calculation can't be computed such * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where * it does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Date getChatzosAsHalfDay() { - return getSunTransit(getSeaLevelSunrise(), getSeaLevelSunset()); + public Instant getChatzosAsHalfDay() { + return getChatzos(getSeaLevelSunrise(), getSeaLevelSunset()); } /** @@ -423,15 +448,15 @@ public Date getChatzosAsHalfDay() { * shaos zmaniyos (temporal hours) after the start of the day, calculated using the start and end of the day passed * to this method. The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal * hours), and the latest zman krias shema is calculated as 3 of those shaos zmaniyos after the beginning of - * the day. If {@link #isUseAstronomicalChatzosForOtherZmanim()} is true, the 3 shaos zmaniyos will be - * based on 1/6 of the time between sunrise and {@link #getSunTransit() astronomical chatzos}. As an example, passing - * {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea level sunrise} and {@link - * #getSeaLevelSunset() sea level sunset} to this method (or {@link #getElevationAdjustedSunrise()} and {@link - * #getElevationAdjustedSunset()} that is driven off the {@link #isUseElevation()} setting) will return sof zman krias - * shema according to the opinion of the GRA. In cases - * where the start and end dates are not synchronous such as in {@link ComprehensiveZmanimCalendar + * the day. If {@link isUseAstronomicalChatzosForOtherZmanim()} is true, the 3 shaos zmaniyos will be + * based on 1/6 of the time between sunrise and {@link getSunTransit() astronomical chatzos}. As an example, passing + * {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea level + * sunrise} and {@link getSeaLevelSunset() sea level sunset} to this method (or {@link getSunriseBasedOnElevationSetting()} and + * {@link getSunsetBasedOnElevationSetting()} that is driven off the {@link isUseElevation()} setting) will return sof zman + * krias shema according to the opinion of the GRA. In cases where + * the start and end dates are not synchronous such as in {@link ComprehensiveZmanimCalendar * #getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees()} false should be passed to the synchronous parameter - * to ensure that {@link #isUseAstronomicalChatzosForOtherZmanim()} will not be used. + * to ensure that {@link isUseAstronomicalChatzosForOtherZmanim()} will not be used. * * @param startOfDay * the start of day for calculating zman krias shema. This can be sunrise or any alos passed @@ -441,15 +466,15 @@ public Date getChatzosAsHalfDay() { * this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @see #isUseAstronomicalChatzosForOtherZmanim() - * @return the Date of the latest zman shema based on the start and end of day times passed to this + * @see isUseAstronomicalChatzosForOtherZmanim() + * @return the Instant of the latest zman shema based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Date getSofZmanShma(Date startOfDay, Date endOfDay, boolean synchronous) { + public Instant getSofZmanShma(Instant startOfDay, Instant endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(startOfDay, getChatzos(), 3); } else { @@ -458,7 +483,7 @@ public Date getSofZmanShma(Date startOfDay, Date endOfDay, boolean synchronous) } /** - * A generic method for calculating the latest zman krias shema that calls {@link #getSofZmanShma(Date, Date, boolean)} + * A generic method for calculating the latest zman krias shema that calls {@link getSofZmanShma(Instant, Instant, boolean)} * passing false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -467,57 +492,59 @@ public Date getSofZmanShma(Date startOfDay, Date endOfDay, boolean synchronous) * @param endOfDay * the end of day for calculating zman krias shema. This can be sunset or any tzais passed to * this method. - * @return the Date of the latest zman shema based on the start and end of day times passed to this + * @return the Instant of the latest zman shema based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getSofZmanShma(Date, Date, boolean) + * @see getSofZmanShma(Instant, Instant, boolean) */ - public Date getSofZmanShma(Date startOfDay, Date endOfDay) { + public Instant getSofZmanShma(Instant startOfDay, Instant endOfDay) { return getSofZmanShma(startOfDay, endOfDay, false); } /** * This method returns the latest zman krias shema (time to recite shema in the morning) that is 3 * - * {@link #getShaahZmanisGra() shaos zmaniyos} (solar hours) after {@link #getSunrise() sunrise} or - * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according + * {@link getShaahZmanisGRA() shaos zmaniyos} (solar hours) after {@link getSunriseWithElevation() sunrise} or + * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according * to the GRA. - * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level - * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the - * {@link #isUseElevation()} setting). + * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level + * sunset} or from {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the + * {@link isUseElevation()} setting). * - * @see #getSofZmanShma(Date, Date) - * @see #getShaahZmanisGra() - * @see #isUseElevation() + * @see getSofZmanShma(Instant, Instant) + * @see getShaahZmanisGRA() + * @see isUseElevation() * @see ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya() - * @return the Date of the latest zman shema according to the GRA. If the calculation can't be + * @return the Instant of the latest zman shema according to the GRA. If the calculation can't be * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, * and one where it does not set, a null will be returned. See the detailed explanation on top * of the {@link AstronomicalCalendar} documentation. */ - public Date getSofZmanShmaGRA() { - return getSofZmanShma(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); + public Instant getSofZmanShmaGRA() { + return getSofZmanShma(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); } /** - * This method returns the latest zman krias shema (time to recite shema in the morning) that is 3 * - * {@link #getShaahZmanisMGA() shaos zmaniyos} (solar hours) after {@link #getAlos72()}, according to the - * Magen Avraham (MGA). The day is calculated - * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link - * #getSeaLevelSunset() sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() - * sunset} (depending on the {@link #isUseElevation()} setting). + * This method returns the latest zman krias shema (time to recite Shema in the morning) according to the opinion of + * the Magen Avraham (MGA) based on alos being {@link + * getAlos72Minutes() 72} minutes before {@link getSunriseWithElevation() sunrise}. This time is 3 {@link + * getShaahZmanis72Minutes() shaos zmaniyos} (solar hours) after {@link getAlos72Minutes() dawn} based on the opinion + * of the MGA that the day is calculated from a {@link getAlos72Minutes() dawn} of 72 minutes before sunrise to + * {@link getTzais72Minutes() nightfall} of 72 minutes after sunset. This returns the time of 3 * {@link + * getShaahZmanis72Minutes()} after {@link getAlos72Minutes() dawn}. * - * @return the Date of the latest zman shema. If the calculation can't be computed such as in - * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it - * does not set, a null will be returned. See detailed explanation on top of the + * @return the Instant of the latest zman krias shema. If the calculation can't be computed such + * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where + * it does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. - * @see #getSofZmanShma(Date, Date) - * @see ComprehensiveZmanimCalendar#getShaahZmanis72Minutes() - * @see ComprehensiveZmanimCalendar#getAlos72() - * @see ComprehensiveZmanimCalendar#getSofZmanShmaMGA72Minutes() that + * @see isUseAstronomicalChatzosForOtherZmanim() + * @see getShaahZmanis72Minutes() + * @see getAlos72Minutes() + * @see getSofZmanShmaMGA72Minutes() + * @see getSofZmanShma(Instant, Instant, boolean) */ - public Date getSofZmanShmaMGA() { - return getSofZmanShma(getAlos72(), getTzais72(), true); + public Instant getSofZmanShmaMGA72Minutes() { + return getSofZmanShma(getAlos72Minutes(), getTzais72Minutes(), true); } /** @@ -527,35 +554,35 @@ public Date getSofZmanShmaMGA() { * According to the Machtzis Hashekel in Orach Chaim * 235:3, the Pri Megadim in Orach * Chaim 261:2 (see the Biur Halacha) and others (see Hazmanim Bahalacha 17:3 and 17:5) the 72 minutes are standard - * clock minutes any time of the year in any location. Depending on the {@link #isUseElevation()} setting, a 72-minute - * offset from either {@link #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} is used. + * clock minutes any time of the year in any location. Depending on the {@link isUseElevation()} setting, a 72-minute + * offset from either {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunset() sea level sunset} is used. * * @see ComprehensiveZmanimCalendar#getTzais16Point1Degrees() - * @return the Date representing 72 minutes after sunset. If the calculation can't be + * @return the Instant representing 72 minutes after sunset. If the calculation can't be * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, * and one where it does not set, a null will be returned See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Date getTzais72() { - return getTimeOffset(getElevationAdjustedSunset(), 72 * MINUTE_MILLIS); + public Instant getTzais72Minutes() { + return getTimeOffset(getSunsetBasedOnElevationSetting(), 72 * MINUTE_MILLIS); } /** - * A method to return candle lighting time, calculated as {@link #getCandleLightingOffset()} minutes before - * {@link #getSeaLevelSunset() sea level sunset}. This will return the time for any day of the week, since it can be + * A method to return candle lighting time, calculated as {@link getCandleLightingOffset()} minutes before + * {@link getSeaLevelSunset() sea level sunset}. This will return the time for any day of the week, since it can be * used to calculate candle lighting time for Yom Tov (mid-week holidays) as well. Elevation adjustments * are intentionally not performed by this method, but you can calculate it by passing the elevation adjusted sunset - * to {@link #getTimeOffset(Date, long)}. + * to {@link getTimeOffset(Instant, long)}. * * @return candle lighting time. If the calculation can't be computed such as in the Arctic Circle where there is at * least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. * - * @see #getSeaLevelSunset() - * @see #getCandleLightingOffset() - * @see #setCandleLightingOffset(double) + * @see getSeaLevelSunset() + * @see getCandleLightingOffset() + * @see setCandleLightingOffset(double) */ - public Date getCandleLighting() { + public Instant getCandleLighting() { return getTimeOffset(getSeaLevelSunset(), -getCandleLightingOffset() * MINUTE_MILLIS); } @@ -565,14 +592,14 @@ public Date getCandleLighting() { * end of the day passed to this method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), * and sof zman tfila is calculated as 4 of those shaos zmaniyos after the beginning of the day. - * As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() - * sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} + * As an example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() + * sea level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} * elevation setting) to this method will return zman tfilah according to the opinion of the GRA. This method's synchronous parameter indicates if the start * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. + * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of * the day are not equal, and the halfway point between them is not at chatzos. * @@ -584,14 +611,14 @@ public Date getCandleLighting() { * to this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Date of the latest zman tfilah based on the start and end of day times passed + * @return the Instant of the latest zman tfilah based on the start and end of day times passed * to this method. If the calculation can't be computed such as in the Arctic Circle where there is at least * one day a year where the sun does not rise, and one where it does not set, a null will be * returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Date getSofZmanTfila(Date startOfDay, Date endOfDay, boolean synchronous) { + public Instant getSofZmanTfila(Instant startOfDay, Instant endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(startOfDay, getChatzos(), 4); } else { @@ -599,8 +626,109 @@ public Date getSofZmanTfila(Date startOfDay, Date endOfDay, boolean synchronous) } } + + /** + * This method returns the latest time for burning chametz on Erev Pesach according to the opinion + * of the GRA. This time is 5 hours into the day based on the + * opinion of the GRA that the day is calculated from + * sunrise to sunset. This returns the time 5 * {@link getShaahZmanisGRA()} after {@link getSeaLevelSunrise() sea + * level sunrise}. If it is not erev Pesach, a null will be returned. + * @return the Instant of the latest time for burning chametz on Erev Pesach. If it is not + * erev Pesach or the calculation can't be computed such as in the Arctic Circle where there is at least + * one day a year where the sun does not rise, and one where it does not set, a null will be + * returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. + * @see getShaahZmanisGRA() + * @see getSofZmanBiurChametz(Instant, Instant, boolean) + */ + + /** + * A generic method for calculating sof zman biur chametz or the latest time one is allowed burning + * chametz on Erev Pesach that is 5 * shaos zmaniyos (temporal hours) after the start of the + * day, calculated using the start and end of the day passed to this method. If the date is not erev Pesach, a + * null will be returned. The time from the start of day to the end of day is divided into 12 shaos zmaniyos + * (temporal hours), and sof zman biur chametz is calculated as 5 of those shaos zmaniyos after the + * beginning of the day. As an example, passing {@link getSunrise() sunrise} and {@link getSunset() sunset} to this + * method will return sof zman biur chametz according to the opinion of the GRA. This method's synchronous parameter indicates if the start + * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some + * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, + * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day + * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. + * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of + * the day are not equal, and the halfway point between them is not at chatzos. + * + * @param startOfDay + * the start of day for calculating sof zman biur chametz. This can be sunrise or any alos + * passed to this method. + * @param endOfDay + * the end of day for calculating sof zman biur chametz. This can be sunset or any tzais + * passed to this method. + * @param synchronous + * If the zman has a synchronous start and end of the day. If this is false, using a {@link + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * definition chatzos will not be the middle of the day for the zman. + * @return the Instant of the sof zman biur chametz based on the start and end of day times passed + * to this method. If the date is not Erev Pesach or if the calculation can't be computed such as in the + * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does not set, + * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} + * documentation. + */ + public Instant getSofZmanBiurChametz(Instant startOfDay, Instant endOfDay, boolean synchronous) { + JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate()); + if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) { + if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { + return getHalfDayBasedZman(startOfDay, getChatzos(), 5); + } else { + return getShaahZmanisBasedZman(startOfDay, endOfDay, 5); + } + } else { + return null; + } + } + + /** + * A generic method for calculating sof zman achilas chametz or the latest time one is allowed eating + * chametz on Erev Pesach that is 4 * shaos zmaniyos (temporal hours) after the start of the + * day, calculated using the start and end of the day passed to this method. If the date is not erev Pesach, a + * null will be returned. The time from the start of day to the end of day is divided into 12 shaos zmaniyos + * (temporal hours), and sof zman achilas chametz is calculated as 4 of those shaos zmaniyos after the + * beginning of the day. As an example, passing {@link getSunrise() sunrise} and {@link getSunset() sunset} to this + * method will return sof zman achilas chametz according to the opinion of the GRA. This method's synchronous parameter indicates if the start + * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some + * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, + * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day + * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. + * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of + * the day are not equal, and the halfway point between them is not at chatzos. + * + * @param startOfDay + * the start of day for calculating sof zman achilas chametz. This can be sunrise or any alos + * passed to this method. + * @param endOfDay + * the end of day for calculating sof zman achilas chametz. This can be sunset or any tzais + * passed to this method. + * @param synchronous + * If the zman has a synchronous start and end of the day. If this is false, using a {@link + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * definition chatzos will not be the middle of the day for the zman. + * @return the Instant of the sof zman achilas chametz based on the start and end of day times passed + * to this method. If the date is not Erev Pesach or if the calculation can't be computed such as in the + * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does not set, + * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} + * documentation. + */ + public Instant getSofZmanAchilasChametz(Instant startOfDay, Instant endOfDay, boolean synchronous) { + JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate()); + if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) { + return getSofZmanTfila(startOfDay, endOfDay, synchronous); + } else { + return null; + } + } + /** - * A generic method for calculating the latest zman tfila that calls {@link #getSofZmanTfila(Date, Date, boolean)} + * A generic method for calculating the latest zman tfila that calls {@link getSofZmanTfila(Instant, Instant, boolean)} * passing false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -609,55 +737,55 @@ public Date getSofZmanTfila(Date startOfDay, Date endOfDay, boolean synchronous) * @param endOfDay * the end of day for calculating zman tfilah. This can be sunset or any tzais passed to * this method. - * @return the Date of the latest zman tfilah based on the start and end of day times passed to this + * @return the Instant of the latest zman tfilah based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getSofZmanShma(Date, Date, boolean) + * @see getSofZmanShma(Instant, Instant, boolean) */ - public Date getSofZmanTfila(Date startOfDay, Date endOfDay) { + public Instant getSofZmanTfila(Instant startOfDay, Instant endOfDay) { return getSofZmanTfila(startOfDay, endOfDay, false); } /** * This method returns the latest zman tfila (time to recite shema in the morning) that is 4 * - * {@link #getShaahZmanisGra() shaos zmaniyos }(solar hours) after {@link #getSunrise() sunrise} or - * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according + * {@link getShaahZmanisGRA() shaos zmaniyos }(solar hours) after {@link getSunriseWithElevation() sunrise} or + * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according * to the GRA. - * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level - * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the - * {@link #isUseElevation()} setting). + * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level + * sunset} or from {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the + * {@link isUseElevation()} setting). * - * @see #getSofZmanTfila(Date, Date) - * @see #getShaahZmanisGra() + * @see getSofZmanTfila(Instant, Instant) + * @see getShaahZmanisGRA() * @see ComprehensiveZmanimCalendar#getSofZmanTfilaBaalHatanya() - * @return the Date of the latest zman tfilah. If the calculation can't be computed such as in + * @return the Instant of the latest zman tfilah. If the calculation can't be computed such as in * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it * does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Date getSofZmanTfilaGRA() { - return getSofZmanTfila(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); + public Instant getSofZmanTfilaGRA() { + return getSofZmanTfila(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); } + /** - * This method returns the latest zman tfila (time to recite shema in the morning) that is 4 * - * {@link #getShaahZmanisMGA() shaos zmaniyos} (solar hours) after {@link #getAlos72()}, according to the + * This method returns the latest zman tfila (time to recite shema in the morning) that is 4 * {@link + * getShaahZmanis72Minutes() shaos zmaniyos} (solar hours) after {@link getAlos72Minutes()}, according to the * Magen Avraham (MGA). The day is calculated - * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link - * #getSeaLevelSunset() sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() - * sunset} (depending on the {@link #isUseElevation()} setting). + * from 72 minutes before {@link getSunriseBasedOnElevationSetting()} to 72 minutes after {@link + * getSunsetBasedOnElevationSetting()}. The use of elevation depends on the {@link isUseElevation()} setting). * - * @return the Date of the latest zman tfila. If the calculation can't be computed such as in + * @return the Instant of the latest zman tfila. If the calculation can't be computed such as in * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it * does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. - * @see #getSofZmanTfila(Date, Date) - * @see #getShaahZmanisMGA() - * @see #getAlos72() + * @see getSofZmanTfila(Instant, Instan, boolean) + * @see getShaahZmanis72Minutes() + * @see getAlos72Minutes() */ - public Date getSofZmanTfilaMGA() { - return getSofZmanTfila(getAlos72(), getTzais72(), true); + public Instant getSofZmanTfilaMGA72Minutes() { + return getSofZmanTfila(getAlos72Minutes(), getTzais72Minutes(), true); } /** @@ -665,18 +793,18 @@ public Date getSofZmanTfilaMGA() { * is 6.5 * shaos zmaniyos (temporal hours) after the start of the day, calculated using the start and end of the * day passed to this method. The time from the start of day to the end of day are divided into 12 shaos zmaniyos * (temporal hours), and mincha gedola is calculated as 6.5 of those shaos zmaniyos after the beginning - * of the day. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link - * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link - * #isUseElevation()} elevation setting) to this method will return mincha gedola according to the opinion of the + * of the day. As an example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or + * {@link getSeaLevelSunrise() sea level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link + * isUseElevation()} elevation setting) to this method will return mincha gedola according to the opinion of the * GRA. Alternatively, this method uses {@link - * #isUseAstronomicalChatzosForOtherZmanim()} to control if the time is based on 6.5 shaos zmaniyos into the day + * isUseAstronomicalChatzosForOtherZmanim()} to control if the time is based on 6.5 shaos zmaniyos into the day * mentioned above, or as half an hour zmaniyos based on the second half of the day after chatzos ({@link - * #getSunTransit() astronomical chatzos} if supported by the {@link AstronomicalCalculator calculator} and {@link - * #isUseAstronomicalChatzos() configured} or {@link #getChatzosAsHalfDay() chatzos as half a day} if not. This + * getSunTransit() astronomical chatzos} if supported by the {@link AstronomicalCalculator calculator} and {@link + * isUseAstronomicalChatzos() configured} or {@link getChatzosAsHalfDay() chatzos as half a day} if not. This * method's synchronous parameter indicates if the start and end of day for the calculation are synchronous, having the same * offset. This is typically the case, but some zmanim calculations are based on a start and end at different offsets * from the real start and end of the day, such as starting the day at alos and an ending it at tzais Geonim - * or some other variant. If the day is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based + * or some other variant. If the day is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based * calculations} will be bypassed. It would be illogical to use a half-day based calculation that start/end at chatzos * when the two "halves" of the day are not equal, and the halfway point between them is not at chatzos. * @@ -688,19 +816,19 @@ public Date getSofZmanTfilaMGA() { * to this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Date of the time of Mincha gedola based on the start and end of day times + * @return the Instant of the time of Mincha gedola based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getSunTransit() - * @see #getChatzosAsHalfDay() - * @see #getChatzos() - * @see #isUseAstronomicalChatzos() - * @see #isUseAstronomicalChatzosForOtherZmanim() + * @see getSunTransit() + * @see getChatzosAsHalfDay() + * @see getChatzos() + * @see isUseAstronomicalChatzos() + * @see isUseAstronomicalChatzosForOtherZmanim() */ - public Date getMinchaGedola(Date startOfDay, Date endOfDay, boolean synchronous) { + public Instant getMinchaGedola(Instant startOfDay, Instant endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 0.5); } else { @@ -709,7 +837,7 @@ public Date getMinchaGedola(Date startOfDay, Date endOfDay, boolean synchronous) } /** - * A generic method for calculating mincha gedola that calls {@link #getMinchaGedola(Date, Date, boolean)} passing + * A generic method for calculating mincha gedola that calls {@link getMinchaGedola(Instant, Instant, boolean)} passing * false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more * details. @@ -719,52 +847,52 @@ public Date getMinchaGedola(Date startOfDay, Date endOfDay, boolean synchronous) * @param endOfDay * the end of day for calculating Mincha gedola. This can be sunset or any tzais passed to * this method. - * @return the Date of the latest Mincha gedola based on the start and end of day times passed to this + * @return the Instant of the latest Mincha gedola based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getMinchaGedola(Date, Date, boolean) + * @see getMinchaGedola(Instant, Instant, boolean) */ - public Date getMinchaGedola(Date startOfDay, Date endOfDay) { + public Instant getMinchaGedola(Instant startOfDay, Instant endOfDay) { return getMinchaGedola(startOfDay, endOfDay, false); } /** * This method returns the latest mincha gedola,the earliest time one can pray mincha that is 6.5 * - * {@link #getShaahZmanisGra() shaos zmaniyos} (solar hours) after {@link #getSunrise() sunrise} or - * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according + * {@link getShaahZmanisGRA() shaos zmaniyos} (solar hours) after {@link getSunriseWithElevation() sunrise} or + * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according * to the GRA. Mincha gedola is the earliest * time one can pray mincha. The Ramba"m is of the opinion that it is better to delay mincha until - * {@link #getMinchaKetana() mincha ketana} while the Ra"sh, Tur, GRA and others are of the + * {@link getMinchaKetanaGRA() mincha ketana GRA} while the Ra"sh, Tur, GRA and others are of the * opinion that mincha can be prayed lechatchila starting at mincha gedola. - * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level - * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} + * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level + * sunset} or {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the {@link isUseElevation()} * setting). * @todo Consider adjusting this to calculate the time as half an hour zmaniyos after either {@link - * #getSunTransit() astronomical chatzos} or {@link #getChatzosAsHalfDay() chatzos as half a day} - * for {@link AstronomicalCalculator calculators} that support it, based on {@link #isUseAstronomicalChatzos()}. + * getSunTransit() astronomical chatzos} or {@link getChatzosAsHalfDay() chatzos as half a day} + * for {@link AstronomicalCalculator calculators} that support it, based on {@link isUseAstronomicalChatzos()}. * - * @see #getMinchaGedola(Date, Date) - * @see #getShaahZmanisGra() - * @see #getMinchaKetana() + * @see getMinchaGedola(Instant, Instant) + * @see getShaahZmanisGRA() + * @see getMinchaKetanaGRA() * @see ComprehensiveZmanimCalendar#getMinchaGedolaBaalHatanya() - * @return the Date of the time of mincha gedola. If the calculation can't be computed such as in the + * @return the Instant of the time of mincha gedola. If the calculation can't be computed such as in the * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does * not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Date getMinchaGedola() { - return getMinchaGedola(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); + public Instant getMinchaGedolaGRA() { + return getMinchaGedola(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); } /** * A generic method for calculating samuch lemincha ketana, / near mincha ketana time that is half - * an hour before {@link #getMinchaKetana(Date, Date)} or 9 * shaos zmaniyos (temporal hours) after the + * an hour before {@link getMinchaKetana(Instant, Instant)} or 9 * shaos zmaniyos (temporal hours) after the * start of the day, calculated using the start and end of the day passed to this method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), and * samuch lemincha ketana is calculated as 9 of those shaos zmaniyos after the beginning of the day. - * For example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea - * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation + * For example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea + * level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} elevation * setting) to this method will return samuch lemincha ketana according to the opinion of the * GRA. See the Mechaber and Mishna Berurah 232 and zman has a synchronous start and end of the day. If this is false, using a {@link - * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Date of the time of Mincha ketana based on the start and end of day times + * @return the Instant of the time of Mincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. @@ -789,7 +917,7 @@ public Date getMinchaGedola() { * @see ComprehensiveZmanimCalendar#getSamuchLeMinchaKetana16Point1Degrees() * @see ComprehensiveZmanimCalendar#getSamuchLeMinchaKetana72Minutes() */ - public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { + public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 3); } else { @@ -798,7 +926,7 @@ public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay, boolean sync } /** - * A generic method for calculating samuch lemincha ketana that calls {@link #getSamuchLeMinchaKetana(Date, Date, boolean)} + * A generic method for calculating samuch lemincha ketana that calls {@link getSamuchLeMinchaKetana(Instant, Instant, boolean)} * passing false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -807,13 +935,13 @@ public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay, boolean sync * @param endOfDay * the end of day for calculating samuch lemincha ketana. This can be sunset or any tzais * passed to this method. - * @return the Date of the time of samuch lemincha ketana based on the start and end of day times + * @return the Instant of the time of samuch lemincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getSamuchLeMinchaKetana(Date, Date, boolean) + * @see getSamuchLeMinchaKetana(Instant, Instant, boolean) */ - public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay) { + public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay) { return getSamuchLeMinchaKetana(startOfDay, endOfDay, false); } @@ -824,14 +952,14 @@ public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay) { * of the day passed to this method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), and * mincha ketana is calculated as 9.5 of those shaos zmaniyos after the beginning of the day. As an - * example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea - * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} + * example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea + * level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} * elevation setting) to this method will return mincha ketana according to the opinion of the * GRA. This method's synchronous parameter indicates if the start * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. + * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of * the day are not equal, and the halfway point between them is not at chatzos. * @@ -843,14 +971,14 @@ public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay) { * this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Date of the time of Mincha ketana based on the start and end of day times + * @return the Instant of the time of Mincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Date getMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { + public Instant getMinchaKetana(Instant startOfDay, Instant endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 3.5); } else { @@ -859,7 +987,7 @@ public Date getMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) } /** - * A generic method for calculating mincha ketana that calls {@link #getMinchaKetana(Date, Date, boolean)} passing + * A generic method for calculating mincha ketana that calls {@link getMinchaKetana(Instant, Instant, boolean)} passing * false to the synchronous parameter since there is no way to know if the start and end of the day are synchronous. * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -868,38 +996,38 @@ public Date getMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) * @param endOfDay * the end of day for calculating Mincha ketana. This can be sunset or any tzais passed to * this method. - * @return the Date of the time of Mincha ketana based on the start and end of day times + * @return the Instant of the time of Mincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getMinchaKetana(Date, Date, boolean) + * @see getMinchaKetana(Instant, Instant, boolean) */ - public Date getMinchaKetana(Date startOfDay, Date endOfDay) { + public Instant getMinchaKetana(Instant startOfDay, Instant endOfDay) { return getMinchaKetana(startOfDay, endOfDay, false); } /** * This method returns mincha ketana,the preferred earliest time to pray mincha in the * opinion of the Rambam and others, that is 9.5 - * * {@link #getShaahZmanisGra() shaos zmaniyos} (solar hours) after {@link #getSunrise() sunrise} or - * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according + * * {@link getShaahZmanisGRA() shaos zmaniyos} (solar hours) after {@link getSunriseWithElevation() sunrise} or + * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according * to the GRA. For more information on this see the - * documentation on {@link #getMinchaGedola() mincha gedola}. - * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level - * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} + * documentation on {@link getMinchaGedolaGRA() mincha gedola}. + * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level + * sunset} or from {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the {@link isUseElevation()} * setting. * - * @see #getMinchaKetana(Date, Date) - * @see #getShaahZmanisGra() - * @see #getMinchaGedola() + * @see getMinchaKetana(Instant, Instant) + * @see getShaahZmanisGRA() + * @see getMinchaGedolaGRA() * @see ComprehensiveZmanimCalendar#getMinchaKetanaBaalHatanya() - * @return the Date of the time of mincha ketana. If the calculation can't be computed such as in the + * @return the Instant of the time of mincha ketana. If the calculation can't be computed such as in the * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does * not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Date getMinchaKetana() { - return getMinchaKetana(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); + public Instant getMinchaKetanaGRA() { + return getMinchaKetana(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); } /** @@ -908,14 +1036,14 @@ public Date getMinchaKetana() { * the day passed to the method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), and * plag hamincha is calculated as 10.75 of those shaos zmaniyos after the beginning of the day. As an - * example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea level - * sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation + * example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea level + * sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} elevation * setting) to this method will return plag mincha according to the opinion of the * GRA. This method's synchronous parameter indicates if the start * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. It + * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. It * would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of the * day are not equal, and the halfway point between them is not at chatzos. * @@ -927,14 +1055,14 @@ public Date getMinchaKetana() { * this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Date of the time of plag hamincha based on the start and end of day times + * @return the Instant of the time of plag hamincha based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Date getPlagHamincha(Date startOfDay, Date endOfDay, boolean synchronous) { + public Instant getPlagHamincha(Instant startOfDay, Instant endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 4.75); } else { @@ -943,71 +1071,103 @@ public Date getPlagHamincha(Date startOfDay, Date endOfDay, boolean synchronous) } /** - * A generic method for calculating plag hamincha that calls {@link #getPlagHamincha(Date, Date, boolean)} passing + * A generic method for calculating plag hamincha that calls {@link getPlagHamincha(Instant, Instant, boolean)} passing * false to the synchronous parameter since there is no way to know if the start and end of the day are synchronous. * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay * the start of day for calculating plag hamincha. This can be sunrise or any alos passed to this method. * @param endOfDay * the end of day for calculating plag hamincha. This can be sunset or any tzais passed to this method. - * @return the Date of the time of plag hamincha based on the start and end of day times + * @return the Instant of the time of plag hamincha based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getPlagHamincha(Date, Date, boolean) + * @see getPlagHamincha(Instant, Instant, boolean) */ - public Date getPlagHamincha(Date startOfDay, Date endOfDay) { + public Instant getPlagHamincha(Instant startOfDay, Instant endOfDay) { return getPlagHamincha(startOfDay, endOfDay, false); } /** - * This method returns plag hamincha, that is 10.75 * {@link #getShaahZmanisGra() shaos zmaniyos} - * (solar hours) after {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on - * the {@link #isUseElevation()} setting), according to the plag hamincha, that is 10.75 * {@link getShaahZmanisGRA() shaos zmaniyos} + * (solar hours) after {@link getSunriseWithElevation() sunrise} or {@link getSeaLevelSunrise() sea level sunrise} (depending on + * the {@link isUseElevation()} setting), according to the GRA. Plag hamincha is the earliest time that Shabbos can be started. - * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level - * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} + * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level + * sunset} or {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the {@link isUseElevation()} * - * @see #getPlagHamincha(Date, Date, boolean) - * @see #getPlagHamincha(Date, Date) + * @see getPlagHamincha(Instant, Instant, boolean) + * @see getPlagHamincha(Instant, Instant) * @see ComprehensiveZmanimCalendar#getPlagHaminchaBaalHatanya() - * @return the Date of the time of plag hamincha. If the calculation can't be computed such as + * @return the Instant of the time of plag hamincha. If the calculation can't be computed such as * in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it * does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Date getPlagHamincha() { - return getPlagHamincha(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); + public Instant getPlagHaminchaGRA() { + return getPlagHamincha(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); } /** - * A method that returns a shaah zmanis ({@link #getTemporalHour(Date, Date) temporal hour}) according to + * A method that returns a shaah zmanis ({@link getTemporalHour(Instant, Instant) temporal hour}) according to * the opinion of the GRA. This calculation divides the day - * based on the opinion of the GRA that the day runs from from {@link #getSeaLevelSunrise() sea level - * sunrise} to {@link #getSeaLevelSunset() sea level sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() - * sunset} (depending on the {@link #isUseElevation()} setting). The day is split into 12 equal parts with each one - * being a shaah zmanis. This method is similar to {@link #getTemporalHour()}, but can account for elevation. + * based on the opinion of the GRA that the day runs from from {@link getSeaLevelSunrise() sea level + * sunrise} to {@link getSeaLevelSunset() sea level sunset} or {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() + * sunset} (depending on the {@link isUseElevation()} setting). The day is split into 12 equal parts with each one + * being a shaah zmanis. This method is similar to {@link getTemporalHour()}, but can account for elevation. * * @return the long millisecond length of a shaah zmanis calculated from sunrise to sunset. * If the calculation can't be computed such as in the Arctic Circle where there is at least one day a year * where the sun does not rise, and one where it does not set, {@link Long#MIN_VALUE} will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see #getTemporalHour(Date, Date) - * @see #getSeaLevelSunrise() - * @see #getSeaLevelSunset() + * @see getTemporalHour(Instant, Instant) + * @see getSeaLevelSunrise() + * @see getSeaLevelSunset() * @see ComprehensiveZmanimCalendar#getShaahZmanisBaalHatanya() */ - public long getShaahZmanisGra() { - return getTemporalHour(getElevationAdjustedSunrise(), getElevationAdjustedSunset()); + public long getShaahZmanisGRA() { + return getTemporalHour(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting()); + } + + /** + * A utility method to return alos (dawn) or tzais (dusk) based on a fractional day offset. As an + * example passing 1.5 to this method as done in the {@link ComprehensiveZmanimCalendar#getTzais90Zmanis()} will return + * the time 90 minutes zmaniyos after {@link getSunsetBasedOnElevationSetting()}, a zman known as + * the achtel zman or 1/8th of the length of the day (12 * 60 = 720-minute day / 8 = 90 or 1.5 hours + * zmaniyos) after sunset. + * @param hours the number of shaos zmaniyos (temporal hours) before sunrise or after sunset that defines dawn + * or dusk. If a negative number is passed in, it will return the time of alos (dawn) (subtracting the + * time from sunrise) and if a positive number is passed in, it will return the time of tzais (dusk) + * (adding the time to sunset). If 0 is passed in, a null will be returned (since we can't tell if it + * is sunrise or sunset based). + * @return the Instant representing the time. If the calculation can't be computed such as in the Arctic + * Circle where there is at least one day a year where the sun does not rise, and one where it does not set, + * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} + * documentation. A null will also be returned if 0 is passed in, since we can't tell if it is a + * sunrise or sunset based zman. + * @see ComprehensiveZmanimCalendar...Zmanis() + * based zmanim. + */ + public Instant getZmanisBasedOffset(double hours) { + long shaahZmanis = getShaahZmanisGRA(); + if (shaahZmanis == Long.MIN_VALUE || hours == 0) { + return null; + } + + if (hours > 0) { + return getTimeOffset(getSunsetBasedOnElevationSetting(), (long) (shaahZmanis * hours)); + } else { + return getTimeOffset(getSunriseBasedOnElevationSetting(), (long) (shaahZmanis * hours)); + } } /** * A method that returns a shaah zmanis (temporal hour) according to the opinion of the Magen Avraham (MGA) based on a 72-minute alos * and tzais. This calculation divides the day that runs from dawn to dusk (for sof zman krias shema and - * tfila). Dawn for this calculation is 72 minutes before {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() - * sea level sunrise} (depending on the {@link #isUseElevation()} elevation setting) and dusk is 72 minutes after {@link - * #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation + * tfila). Dawn for this calculation is 72 minutes before {@link getSunriseWithElevation() sunrise} or {@link getSeaLevelSunrise() + * sea level sunrise} (depending on the {@link isUseElevation()} elevation setting) and dusk is 72 minutes after {@link + * getSunsetWithElevation() sunset} or {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} elevation * setting). This day is split into 12 equal parts with each part being a shaah zmanis. Alternate methods of calculating * a shaah zmanis according to the Magen Avraham (MGA) are available in the subclass {@link ComprehensiveZmanimCalendar}. * @@ -1016,8 +1176,8 @@ public long getShaahZmanisGra() { * where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public long getShaahZmanisMGA() { - return getTemporalHour(getAlos72(), getTzais72()); + public long getShaahZmanis72Minutes() { + return getTemporalHour(getAlos72Minutes(), getTzais72Minutes()); } /** @@ -1041,38 +1201,38 @@ public ZmanimCalendar(GeoLocation location) { } /** - * A method to get the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} which + * A method to get the offset in minutes before {@link getSeaLevelSunset() sea level sunset} which * is used in calculating candle lighting time. The default time used is 18 minutes before sea level sunset. Some * calendars use 15 minutes, while the custom in Jerusalem is to use a 40-minute offset. Please check the local custom * for candle lighting time. * * @return Returns the currently set candle lighting offset in minutes. - * @see #getCandleLighting() - * @see #setCandleLightingOffset(double) + * @see getCandleLighting() + * @see setCandleLightingOffset(double) */ public double getCandleLightingOffset() { return candleLightingOffset; } /** - * A method to set the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} that is + * A method to set the offset in minutes before {@link getSeaLevelSunset() sea level sunset} that is * used in calculating candle lighting time. The default time used is 18 minutes before sunset. Some calendars use 15 * minutes, while the custom in Jerusalem is to use a 40-minute offset. * * @param candleLightingOffset * The candle lighting offset to set in minutes. - * @see #getCandleLighting() - * @see #getCandleLightingOffset() + * @see getCandleLighting() + * @see getCandleLightingOffset() */ public void setCandleLightingOffset(double candleLightingOffset) { this.candleLightingOffset = candleLightingOffset; } /** - * This is a utility method to determine if the current Date (date-time) passed in has a melacha (work) prohibition. + * This is a utility method to determine if the current Instant passed in has a melacha (work) prohibition. * Since there are many opinions on the time of tzais, the tzais for the current day has to be passed to this - * class. Sunset is the classes current day's {@link #getElevationAdjustedSunset() elevation adjusted sunset} that observes the - * {@link #isUseElevation()} settings. The {@link JewishCalendar#getInIsrael()} will be set by the inIsrael parameter. + * class. Sunset is the classes current day's {@link getSunsetBasedOnElevationSetting() elevation adjusted sunset} that observes the + * {@link isUseElevation()} settings. The {@link JewishCalendar#getInIsrael()} will be set by the inIsrael parameter. * * @param currentTime the current time * @param tzais the time of tzais @@ -1084,28 +1244,97 @@ public void setCandleLightingOffset(double candleLightingOffset) { * @see JewishCalendar#hasCandleLighting() * @see JewishCalendar#setInIsrael(boolean) */ - public boolean isAssurBemlacha(Date currentTime, Date tzais, boolean inIsrael) { + public boolean isAssurBemlacha(Instant currentTime, Instant tzais, boolean inIsrael) { JewishCalendar jewishCalendar = new JewishCalendar(); - jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH), - getCalendar().get(Calendar.DAY_OF_MONTH)); + jewishCalendar.setGregorianDate(getLocalDate()); + jewishCalendar.setInIsrael(inIsrael); - if (jewishCalendar.hasCandleLighting() && currentTime.compareTo(getElevationAdjustedSunset()) >= 0) { //erev shabbos, YT or YT sheni and after shkiah + if (jewishCalendar.hasCandleLighting() && currentTime.compareTo(getSunsetBasedOnElevationSetting()) >= 0) { //erev shabbos, YT or YT sheni and after shkiah return true; } //is shabbos or YT and it is before tzais return jewishCalendar.isAssurBemelacha() && currentTime.compareTo(tzais) <= 0; } + + /** + * A method that returns the Baal Hatanya's + * netz amiti (sunrise) without {@link AstronomicalCalculator#getElevationAdjustment(double) + * elevation adjustment}. This forms the base for the Baal Hatanya's dawn-based calculations that are + * calculated as a dip below the horizon before sunrise. + * + * According to the Baal Hatanya, netz amiti, or true (halachic) sunrise, is when the top of the sun's + * disk is visible at an elevation similar to the mountains of Eretz Yisrael. The time is calculated as the point at which + * the center of the sun's disk is 1.583° below the horizon. This degree-based calculation can be found in Rabbi Shalom + * DovBer Levine's commentary on The Baal + * Hatanya's Seder Hachnasas Shabbos. From an elevation of 546 meters, the top of Har Hacarmel, the sun disappears when it is 1° 35' or 1.583° + * below the sea level horizon. This in turn is based on the Gemara Shabbos 35a. There are other opinions brought down by + * Rabbi Levine, including Rabbi Yosef Yitzchok Feigelstock who calculates it as the degrees below the horizon 4 minutes after + * sunset in Yerushalayim (on the equinox). That is brought down as 1.583°. This is identical to the 1° 35' zman + * and is probably a typo and should be 1.683°. These calculations are used by most Chabad calendars that use the Baal Hatanya's zmanim. See + * About Our + * Zmanim Calculations @ Chabad.org. + * + * Note: netz amiti is used only for calculating certain zmanim, and is intentionally unpublished. For + * practical purposes, daytime mitzvos like shofar and lulav should not be done until after the + * published time for netz / sunrise. + * + * @return the Instant representing the exact sea level netz amiti (sunrise) time. If the calculation can't be + * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one + * where it does not set, a null will be returned. See detailed explanation on top of the page. + * + * @see getSunriseWithElevation() + * @see getSeaLevelSunrise() + * @see getSunsetBaalHatanya() + * @see ZENITH_1_POINT_583 + */ + protected Instant getSunriseBaalHatanya() { + return getSunriseOffsetByDegrees(ZENITH_1_POINT_583); + } + + /** + * A method that returns the Baal Hatanya's + * shkiah amiti (sunset) without {@link AstronomicalCalculator#getElevationAdjustment(double) + * elevation adjustment}. This forms the base for the Baal Hatanya's dusk-based calculations that are calculated + * as a dip below the horizon after sunset. + * + * According to the Baal Hatanya, shkiah amiti, true (halachic) sunset, is when the top of the + * sun's disk disappears from view at an elevation similar to the mountains of Eretz Yisrael. + * This time is calculated as the point at which the center of the sun's disk is 1.583 degrees below the horizon. + * + * Note: shkiah amiti is used only for calculating certain zmanim, and is intentionally unpublished. For + * practical purposes, all daytime mitzvos should be completed before the published time for shkiah / sunset. + * + * For further explanation of the calculations used for the Baal Hatanya's zmanim in this library, see + * About Our + * Zmanim Calculations @ Chabad.org. + * + * @return the Instant representing the exact sea level shkiah amiti (sunset) time. If the calculation + * can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does not + * rise, and one where it does not set, a null will be returned. See detailed explanation on top of + * the {@link AstronomicalCalendar} documentation. + * + * @see getSunsetWithElevation() + * @see getSeaLevelSunset() + * @see getSunriseBaalHatanya() + * @see ZENITH_1_POINT_583 + */ + protected Instant getSunsetBaalHatanya() { + return getSunsetOffsetByDegrees(ZENITH_1_POINT_583); + } /** - * A generic utility method for calculating any shaah zmanis (temporal hour) based zman with the - * day defined as the start and end of day (or night) and the number of shaos zmaniyos passed to the - * method. This simplifies the code in other methods such as {@link #getPlagHamincha(Date, Date)} and cuts down on - * code replication. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link - * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the - * {@link #isUseElevation()} elevation setting) and 10.75 hours to this method will return plag mincha - * according to the opinion of the GRA. + * A generic utility method for calculating any shaah zmanis (temporal hour) based zman with the day + * defined as the start and end of day (or night) and the number of shaos zmaniyos passed to the method. This + * simplifies the code in other methods such as {@link getPlagHamincha(Instant, Instant)} and cuts down on code replication. + * As an example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link + * getSeaLevelSunrise() sea level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link + * isUseElevation()} elevation setting) and 10.75 hours to this method will return plag mincha according to the + * opinion of the GRA. * * @param startOfDay * the start of day for calculating the zman. This can be sunrise or any alos passed @@ -1115,13 +1344,13 @@ public boolean isAssurBemlacha(Date currentTime, Date tzais, boolean inIsrael) { * this method. * @param hours * the number of shaos zmaniyos (temporal hours) to offset from the start of day - * @return the Date of the time of zman with the shaos zmaniyos (temporal hours) + * @return the Instant of the time of zman with the shaos zmaniyos (temporal hours) * in the day offset from the start of day passed to this method. If the calculation can't be computed such * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one * where it does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Date getShaahZmanisBasedZman(Date startOfDay, Date endOfDay, double hours) { + public Instant getShaahZmanisBasedZman(Instant startOfDay, Instant endOfDay, double hours) { long shaahZmanis = getTemporalHour(startOfDay, endOfDay); return getTimeOffset(startOfDay, shaahZmanis * hours); } @@ -1145,9 +1374,9 @@ public Date getShaahZmanisBasedZman(Date startOfDay, Date endOfDay, double hours * explanation on top of the page. */ public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) { - Date seaLevelSunrise = getSeaLevelSunrise(); - Date seaLevelSunset = getSeaLevelSunset(); - Date twilight = null; + Instant seaLevelSunrise = getSeaLevelSunrise(); + Instant seaLevelSunset = getSeaLevelSunset(); + Instant twilight; if (sunset) { twilight = getSunsetOffsetByDegrees(GEOMETRIC_ZENITH + degrees); } else { @@ -1156,12 +1385,12 @@ public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) if (seaLevelSunrise == null || seaLevelSunset == null || twilight == null) { return Double.MIN_VALUE; } - double shaahZmanis = (seaLevelSunset.getTime() - seaLevelSunrise.getTime()) / 12.0; + double shaahZmanis = (seaLevelSunset.toEpochMilli() - seaLevelSunrise.toEpochMilli()) / 12.0; long riseSetToTwilight; if (sunset) { - riseSetToTwilight = twilight.getTime() - seaLevelSunset.getTime(); + riseSetToTwilight = twilight.toEpochMilli() - seaLevelSunset.toEpochMilli(); } else { - riseSetToTwilight = seaLevelSunrise.getTime() - twilight.getTime(); + riseSetToTwilight = seaLevelSunrise.toEpochMilli() - twilight.toEpochMilli(); } return riseSetToTwilight / shaahZmanis; } @@ -1189,14 +1418,14 @@ public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) * hamincha. If the number of hours is negative, it will subtract the number of shaos zmaniyos from the end * of the day. * - * @return the Date of zman based on calculation of the first or second half of the day. If the + * @return the Instant of zman based on calculation of the first or second half of the day. If the * calculation can't be computed such as in the Arctic Circle where there is at least one day a year where the * sun does not rise, and one where it does not set, a null will be returned. See detailed explanation * on top of the {@link AstronomicalCalendar} documentation. * * @see ComprehensiveZmanimCalendar#getFixedLocalChatzos() */ - public Date getHalfDayBasedZman(Date startOfHalfDay, Date endOfHalfDay, double hours) { + public Instant getHalfDayBasedZman(Instant startOfHalfDay, Instant endOfHalfDay, double hours) { if (startOfHalfDay == null || endOfHalfDay == null) { return null; } @@ -1221,14 +1450,42 @@ public Date getHalfDayBasedZman(Date startOfHalfDay, Date endOfHalfDay, double h * can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, * and one where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. - * @see #getHalfDayBasedZman(Date, Date, double) - * @see #isUseAstronomicalChatzosForOtherZmanim() + * @see getHalfDayBasedZman(Instant, Instant, double) + * @see isUseAstronomicalChatzosForOtherZmanim() * @todo Consider adjusting various shaah zmanis times to use this. */ - public long getHalfDayBasedShaahZmanis(Date startOfHalfDay, Date endOfHalfDay) { + public long getHalfDayBasedShaahZmanis(Instant startOfHalfDay, Instant endOfHalfDay) { if (startOfHalfDay == null || endOfHalfDay == null) { return Long.MIN_VALUE; } - return (endOfHalfDay.getTime() - startOfHalfDay.getTime()) / 6; + return (endOfHalfDay.toEpochMilli() - startOfHalfDay.toEpochMilli()) / 6; + } + + /** + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + if (!super.equals(object)) { + return false; + } + ZmanimCalendar that = (ZmanimCalendar) object; + return useElevation == that.useElevation + && useAstronomicalChatzos == that.useAstronomicalChatzos + && useAstronomicalChatzosForOtherZmanim == that.useAstronomicalChatzosForOtherZmanim + && candleLightingOffset == that.candleLightingOffset; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return Objects.hash(super.hashCode(), useElevation, useAstronomicalChatzos, + useAstronomicalChatzosForOtherZmanim, Double.hashCode(candleLightingOffset)); } } From 3a6ed6aac737931e79b82bfcef788c06e183808c Mon Sep 17 00:00:00 2001 From: KosherJava Date: Sat, 25 Apr 2026 22:58:03 -0400 Subject: [PATCH 05/12] Restore Master version of ZmanimCalendar --- .../com/kosherjava/zmanim/ZmanimCalendar.java | 1025 ++++++----------- 1 file changed, 384 insertions(+), 641 deletions(-) diff --git a/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java b/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java index 3c721c1a..be75d52e 100644 --- a/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java +++ b/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java @@ -15,39 +15,40 @@ */ package com.kosherjava.zmanim; -import java.time.Instant; -import java.time.LocalDate; -import java.util.Objects; +import java.util.Calendar; +import java.util.Date; import com.kosherjava.zmanim.hebrewcalendar.JewishCalendar; import com.kosherjava.zmanim.util.AstronomicalCalculator; import com.kosherjava.zmanim.util.GeoLocation; /** - * The ZmanimCalendar is a specialized calendar that can calculate sunrise, sunset and Jewish zmanim (religious times) - * for prayers and other Jewish religious duties. This class contains the main functionality of the Zmanim library. For - * a much more extensive list of zmanim, use the {@link ComprehensiveZmanimCalendar} that extends this class. See - * documentation for the {@link ComprehensiveZmanimCalendar} and {@link AstronomicalCalendar} for simple examples on using the API. + * The ZmanimCalendar is a specialized calendar that can calculate sunrise, sunset and Jewish zmanim + * (religious times) for prayers and other Jewish religious duties. This class contains the main functionality of the + * Zmanim library. For a much more extensive list of zmanim, use the {@link ComprehensiveZmanimCalendar} that + * extends this class. See documentation for the {@link ComprehensiveZmanimCalendar} and {@link AstronomicalCalendar} for + * simple examples on using the API. * Elevation based zmanim (even sunrise and sunset) should not be used lekula without the guidance - * of a posek. According to Rabbi Dovid Yehudah Bursztyn in his Zmanim Kehilchasam, 7th edition chapter 2, section 7 (pages 181-182) and section 9 (pages 186-187), no zmanim - * besides sunrise and sunset should use elevation. However, Rabbi Yechiel Avrahom Zilber in the Birur Halacha Vol. 6 Ch. 58 Pages 34 and 42 is of the opinion that elevation should be accounted for - * in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons should be factored into zmanim calculations. The - * setting defaults to false (elevation will not be used for zmanim calculations besides sunrise and sunset), unless the - * setting is changed to true in {@link setUseElevation(boolean)}. This will impact sunrise and sunset-based zmanim such as - * {@link getSunriseWithElevation()}, {@link getSunsetWithElevation()}, {@link getSofZmanShmaGRA()}, alos-based - * zmanim such as {@link getSofZmanShmaMGA72Minutes()} that are based on a fixed offset of sunrise or sunset and - * zmanim based on a percentage of the day such as {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} - * that are based on sunrise and sunset. Even when set to true it will not impact zmanim that are a degree-based offset of - * sunrise and sunset, such as {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link - * ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()} since these zmanim are not linked to sunrise or sunset times - * (the calculations are based on the astronomical definition of sunrise and sunset calculated in a vacuum with the solar radius - * above the horizon), and are therefore not impacted by the use of elevation. For additional information on the halachic - * impact of elevation on zmanim see: + * of a posek. According to Rabbi Dovid Yehudah Bursztyn in his + * Zmanim Kehilchasam, 7th edition chapter 2, section 7 (pages 181-182) + * and section 9 (pages 186-187), no zmanim besides sunrise and sunset should use elevation. However, Rabbi Yechiel + * Avrahom Zilber in the Birur Halacha Vol. 6 Ch. 58 Pages + * 34 and + * 42 is of the opinion that elevation should be + * accounted for in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons should + * be factored into zmanim calculations. The setting defaults to false (elevation will not be used for + * zmanim calculations besides sunrise and sunset), unless the setting is changed to true in {@link + * #setUseElevation(boolean)}. This will impact sunrise and sunset-based zmanim such as {@link #getSunrise()}, + * {@link #getSunset()}, {@link #getSofZmanShmaGRA()}, alos-based zmanim such as {@link #getSofZmanShmaMGA()} + * that are based on a fixed offset of sunrise or sunset and zmanim based on a percentage of the day such as + * {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on sunrise and sunset. Even when set to + * true it will not impact zmanim that are a degree-based offset of sunrise and sunset, such as {@link + * ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()} since + * these zmanim are not linked to sunrise or sunset times (the calculations are based on the astronomical definition of + * sunrise and sunset calculated in a vacuum with the solar radius above the horizon), and are therefore not impacted by the use + * of elevation. + * For additional information on the halachic impact of elevation on zmanim see: *
      *
    • Zmanei Halacha Lema'aseh 4th edition by Rabbi Yedidya Manat. @@ -70,33 +71,33 @@ public class ZmanimCalendar extends AstronomicalCalendar { /** - * Is elevation factored in for some zmanim (see {@link isUseElevation()} for additional information). - * @see isUseElevation() - * @see setUseElevation(boolean) + * Is elevation factored in for some zmanim (see {@link #isUseElevation()} for additional information). + * @see #isUseElevation() + * @see #setUseElevation(boolean) */ private boolean useElevation; /** - * Is elevation above sea level calculated for times besides sunrise and sunset. According to Rabbi Dovid Yehuda Bursztyn in - * his Zmanim Kehilchasam (second edition published in 2007) chapter 2 - * (pages 186-187) no zmanim besides sunrise and sunset should use elevation. However, Rabbi Yechiel Avrahom Zilber - * in the Birur Halacha Vol. 6 Ch. 58 Pages 34 and 42 is of the opinion that elevation should be accounted - * for in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons should be - * factored into zmanim calculations.The setting defaults to false (elevation will not be used for zmanim - * calculations), unless the setting is changed to true in {@link setUseElevation(boolean)}. This will impact sunrise and - * sunset based zmanim such as {@link getSofZmanShmaGRA()}, alos based zmanim such as {@link - * getSofZmanShmaMGA72Minutes()} that are based on a fixed offset of sunrise or sunset and zmanim based on a - * percentage of the day such as {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on - * sunrise and sunset. It will not impact zmanim that are a degree based offset of sunrise and sunset, such as {@link - * ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link - * ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()}. + * Is elevation above sea level calculated for times besides sunrise and sunset. According to Rabbi Dovid Yehuda + * Bursztyn in his Zmanim Kehilchasam (second edition published + * in 2007) chapter 2 (pages 186-187) no zmanim besides sunrise and sunset should use elevation. However, + * Rabbi Yechiel Avrahom Zilber in the Birur Halacha Vol. 6 Ch. 58 Pages + * 34 and 42 is of the opinion that elevation should be + * accounted for in zmanim calculations. Related to this, Rabbi Yaakov Karp in Shimush Zekeinim, Ch. 1, page 17 states that obstructing horizons + * should be factored into zmanim calculations.The setting defaults to false (elevation will not be used for + * zmanim calculations), unless the setting is changed to true in {@link #setUseElevation(boolean)}. This will + * impact sunrise and sunset based zmanim such as {@link #getSunrise()}, {@link #getSunset()}, + * {@link #getSofZmanShmaGRA()}, alos based zmanim such as {@link #getSofZmanShmaMGA()} that are based on a + * fixed offset of sunrise or sunset and zmanim based on a percentage of the day such as {@link + * ComprehensiveZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on sunrise and sunset. It will not impact + * zmanim that are a degree based offset of sunrise and sunset, such as + * {@link ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya()}. * * @return if the use of elevation is active * - * @see setUseElevation(boolean) + * @see #setUseElevation(boolean) */ public boolean isUseElevation() { return useElevation; @@ -104,8 +105,8 @@ public boolean isUseElevation() { /** * Sets whether elevation above sea level is factored into zmanim calculations for times besides sunrise and sunset. - * See {@link isUseElevation()} for more details. - * @see isUseElevation() + * See {@link #isUseElevation()} for more details. + * @see #isUseElevation() * * @param useElevation set to true to use elevation in zmanim calculations */ @@ -117,36 +118,36 @@ public void setUseElevation(boolean useElevation) { * Is astronomical chatzos used for zmanim calculations. The default value of true will * keep the standard astronomical chatzos calculation, while setting it to false will use half of * a solar day calculation for chatzos. - * @see isUseAstronomicalChatzos() - * @see setUseAstronomicalChatzos(boolean) - * @see getChatzos() - * @see getSunTransit() - * @see getChatzosAsHalfDay() - * @see useAstronomicalChatzosForOtherZmanim + * @see #isUseAstronomicalChatzos() + * @see #setUseAstronomicalChatzos(boolean) + * @see #getChatzos() + * @see #getSunTransit() + * @see #getChatzosAsHalfDay() + * @see #useAstronomicalChatzosForOtherZmanim */ private boolean useAstronomicalChatzos = true; /** - * Is {@link getSunTransit() astronomical chatzos} used for {@link getChatzos()} for enhanced accuracy. For + * Is {@link #getSunTransit() astronomical chatzos} used for {@link #getChatzos()} for enhanced accuracy. For * example as the day lengthens, the second half of the day is longer than the first and astronomical chatzos * would be a drop earlier than half of the time between sunrise and sunset. * - * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link getSofZmanShmaGRA() + * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link #getSofZmanShmaGRA() * Sof zman Shma GRA} would be calculated as 3 shaos zmaniyos after sunrise, but the shaos * zmaniyos would be calculated a a 6th of the time between sunrise and chatzos, as opposed to a 12th of the - * time between sunrise and sunset. {@link getMinchaGedolaGRA() mincha gedola} will be calculated as half a + * time between sunrise and sunset. {@link #getMinchaGedola() mincha gedola} will be calculated as half a * shaah zmanis of afternoon hours (a 6th of the time between chatzos and sunset after astronomical - * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link getPlagHaminchaGRA() Plag + * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link #getPlagHamincha() Plag * hamincha} would be calculated as 4.75 shaos zmaniyos after astronomical chatzos as opposed to 10.75 * shaos zmaniyos after sunrise. Etc. * * @return if the use of astronomical chatzos is active. - * @see useAstronomicalChatzos - * @see setUseAstronomicalChatzos(boolean) - * @see getChatzos() - * @see getSunTransit() - * @see getChatzosAsHalfDay() - * @see isUseAstronomicalChatzosForOtherZmanim() + * @see #useAstronomicalChatzos + * @see #setUseAstronomicalChatzos(boolean) + * @see #getChatzos() + * @see #getSunTransit() + * @see #getChatzosAsHalfDay() + * @see #isUseAstronomicalChatzosForOtherZmanim() */ public boolean isUseAstronomicalChatzos() { return useAstronomicalChatzos; @@ -155,12 +156,12 @@ public boolean isUseAstronomicalChatzos() { /** * Sets if astronomical chatzos should be used in calculations of other zmanim for enhanced accuracy. * @param useAstronomicalChatzos set to true to use astronomical in chatzos in zmanim calculations. - * @see useAstronomicalChatzos - * @see isUseAstronomicalChatzos() - * @see getChatzos() - * @see getSunTransit() - * @see getChatzosAsHalfDay() - * @see setUseAstronomicalChatzosForOtherZmanim(boolean) + * @see #useAstronomicalChatzos + * @see #isUseAstronomicalChatzos() + * @see #getChatzos() + * @see #getSunTransit() + * @see #getChatzosAsHalfDay() + * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) */ public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) { this.useAstronomicalChatzos = useAstronomicalChatzos; @@ -170,11 +171,11 @@ public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) { * Is astronomical chatzos used for zmanim calculations besides chatzos itself for enhanced * accuracy. The default value of false will keep the standard start to end of day calculations, while setting * it to true will use half of a solar day calculation for zmanim. - * @see isUseAstronomicalChatzosForOtherZmanim() - * @see setUseAstronomicalChatzosForOtherZmanim(boolean) - * @see isUseAstronomicalChatzos() - * @see setUseAstronomicalChatzos(boolean) - * @see getChatzos() + * @see #isUseAstronomicalChatzosForOtherZmanim() + * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) + * @see #isUseAstronomicalChatzos() + * @see #setUseAstronomicalChatzos(boolean) + * @see #getChatzos() */ private boolean useAstronomicalChatzosForOtherZmanim = false; @@ -184,20 +185,20 @@ public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) { * the first and astronomical chatzos would be a drop earlier than half of the time between sunrise and sunset. * Conversely, the second half of the day would be shorter in the autumn as the days start getting shorter. * - * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link getSofZmanShmaGRA() + * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link #getSofZmanShmaGRA() * Sof zman Shma GRA} would be calculated as 3 shaos zmaniyos after sunrise, but the shaos * zmaniyos would be calculated a a 6th of the time between sunrise and chatzos, as opposed to a 12th of the - * time between sunrise and sunset. {@link getMinchaGedolaGRA() mincha gedola GRA} will be calculated as half a + * time between sunrise and sunset. {@link #getMinchaGedola() mincha gedola} will be calculated as half a * shaah zmanis of afternoon hours (a 6th of the time between chatzos and sunset after astronomical - * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link getPlagHaminchaGRA() Plag + * chatzos as opposed to 6.5 shaos zmaniyos after sunrise. {@link #getPlagHamincha() Plag * hamincha} would be calculated as 4.75 shaos zmaniyos after astronomical chatzos as opposed to 10.75 * shaos zmaniyos after sunrise. Etc. * * @return if the use of astronomical chatzos is active. - * @see useAstronomicalChatzosForOtherZmanim - * @see setUseAstronomicalChatzosForOtherZmanim(boolean) - * @see useAstronomicalChatzos - * @see setUseAstronomicalChatzos(boolean) + * @see #useAstronomicalChatzosForOtherZmanim + * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) + * @see #useAstronomicalChatzos + * @see #setUseAstronomicalChatzos(boolean) */ public boolean isUseAstronomicalChatzosForOtherZmanim() { return useAstronomicalChatzosForOtherZmanim; @@ -206,16 +207,25 @@ public boolean isUseAstronomicalChatzosForOtherZmanim() { /** * Sets if astronomical chatzos should be used in calculations of other zmanim for enhanced accuracy. * @param useAstronomicalChatzosForOtherZmanim set to true to use astronomical in chatzos in zmanim calculations. - * @see useAstronomicalChatzos - * @see isUseAstronomicalChatzos() + * @see #useAstronomicalChatzos + * @see #isUseAstronomicalChatzos() */ public void setUseAstronomicalChatzosForOtherZmanim(boolean useAstronomicalChatzosForOtherZmanim) { this.useAstronomicalChatzosForOtherZmanim = useAstronomicalChatzosForOtherZmanim; } /** - * The zenith of 16.1° below geometric zenith (90°). - * @see getAlos16Point1Degrees() + * The zenith of 16.1° below geometric zenith (90°). This calculation is used for determining alos + * (dawn) and tzais (nightfall) in some opinions. It is based on the calculation that the time between dawn + * and sunrise (and sunset to nightfall) is 72 minutes, the time that is takes to walk 4 mil at 18 minutes a mil (Rambam and others). The sun's position below the horizon 72 minutes + * before {@link #getSunrise() sunrise} in Jerusalem around the equinox / equilux is + * 16.1° below {@link #GEOMETRIC_ZENITH geometric zenith}. + * + * @see #getAlosHashachar() + * @see ComprehensiveZmanimCalendar#getAlos16Point1Degrees() * @see ComprehensiveZmanimCalendar#getTzais16Point1Degrees() * @see ComprehensiveZmanimCalendar#getSofZmanShmaMGA16Point1Degrees() * @see ComprehensiveZmanimCalendar#getSofZmanTfilaMGA16Point1Degrees() @@ -228,143 +238,145 @@ public void setUseAstronomicalChatzosForOtherZmanim(boolean useAstronomicalChatz protected static final double ZENITH_16_POINT_1 = GEOMETRIC_ZENITH + 16.1; /** - * The zenith of 8.5° below geometric zenith (90°). - * @see getTzaisGeonim8Point5Degrees() + * The zenith of 8.5° below geometric zenith (90°). This calculation is used for calculating alos + * (dawn) and tzais (nightfall) in some opinions. This calculation is based on the sun's position below the + * horizon 36 minutes after {@link #getSunset() sunset} in Jerusalem around the equinox / equilux, which + * is 8.5° below {@link #GEOMETRIC_ZENITH geometric zenith}. The Ohr Meir considers this the time that 3 small stars are visible, + * which is later than the required 3 medium stars. + * + * @see #getTzais() + * @see ComprehensiveZmanimCalendar#getTzaisGeonim8Point5Degrees() */ protected static final double ZENITH_8_POINT_5 = GEOMETRIC_ZENITH + 8.5; - - /** - * The zenith of 1.583° below {@link GEOMETRIC_ZENITH geometric zenith} (90°). - * @see getSunriseBaalHatanya() - * @see getSunsetBaalHatanya() - */ - protected static final double ZENITH_1_POINT_583 = GEOMETRIC_ZENITH + 1.583; /** * The default Shabbos candle lighting offset is 18 minutes. This can be changed via the - * {@link setCandleLightingOffset(double)} and retrieved by the {@link getCandleLightingOffset()}. + * {@link #setCandleLightingOffset(double)} and retrieved by the {@link #getCandleLightingOffset()}. */ private double candleLightingOffset = 18; /** - * This method will return {@link getSeaLevelSunrise() sea level sunrise} if {@link isUseElevation()} is false (the default), - * or elevation adjusted {@link getSunriseWithElevation()} if it is true. This allows relevant zmanim in this and - * extending classes (such as the {@link ComprehensiveZmanimCalendar}) to automatically adjust to the elevation setting. + * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the + * default), or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant zmanim + * in this and extending classes (such as the {@link ComprehensiveZmanimCalendar}) to automatically adjust to the elevation setting. * - * @return {@link getSeaLevelSunrise()} if {@link isUseElevation()} is false (the default), or elevation adjusted - * {@link getSunriseWithElevation()} if it is true. - * @see getSunriseWithElevation() + * @return {@link #getSeaLevelSunrise()} if {@link #isUseElevation()} is false (the default), or elevation adjusted + * {@link AstronomicalCalendar#getSunrise()} if it is true. + * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunrise() */ - protected Instant getSunriseBasedOnElevationSetting() { + protected Date getElevationAdjustedSunrise() { if (isUseElevation()) { - return super.getSunriseWithElevation(); + return super.getSunrise(); } return getSeaLevelSunrise(); } /** - * This method will return {@link getSeaLevelSunrise() sea level sunrise} if {@link isUseElevation()} is false (the default), - * or elevation adjusted {@link getSunriseWithElevation()} if it is true. This allows relevant zmanim + * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the default), + * or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant zmanim * in this and extending classes (such as the {@link ComprehensiveZmanimCalendar}) to automatically adjust to the elevation setting. * - * @return {@link getSeaLevelSunset()} if {@link isUseElevation()} is false (the default), or elevation adjusted - * {@link getSunsetWithElevation()} if it is true. - * @see getSunsetWithElevation() + * @return {@link #getSeaLevelSunset()} if {@link #isUseElevation()} is false (the default), or elevation adjusted + * {@link AstronomicalCalendar#getSunset()} if it is true. + * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunset() */ - protected Instant getSunsetBasedOnElevationSetting() { + protected Date getElevationAdjustedSunset() { if (isUseElevation()) { - return super.getSunsetWithElevation(); + return super.getSunset(); } return getSeaLevelSunset(); } /** - * A method that returns tzais (nightfall) when the sun is {@link ZENITH_8_POINT_5 8.5°} below the - * {@link GEOMETRIC_ZENITH geometric horizon} (90°) after {@link getSunsetWithElevation() sunset}, a time that Rabbi - * Meir Posen in his the Ohr Meir calculated that 3 small - * stars are visible, which is later than the required 3 medium stars. This calculation is based on the sun's position below - * the horizon 36 minutes after {@link getSeaLevelSunrise() sunset} in Jerusalem around the equinox / equilux, which - * is 8.5° below {@link GEOMETRIC_ZENITH geometric zenith}. + * A method that returns tzais (nightfall) when the sun is {@link #ZENITH_8_POINT_5 8.5°} below the + * {@link #GEOMETRIC_ZENITH geometric horizon} (90°) after {@link #getSunset() sunset}, a time that Rabbi Meir + * Posen in his the Ohr Meir calculated that 3 small + * stars are visible, which is later than the required 3 medium stars. See the {@link #ZENITH_8_POINT_5} constant. + * + * @see #ZENITH_8_POINT_5 * - * @return The Instant of nightfall. If the calculation can't be computed such as northern and southern + * @return The Date of nightfall. If the calculation can't be computed such as northern and southern * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach * low enough below the horizon for this calculation, a null will be returned. See detailed * explanation on top of the {@link AstronomicalCalendar} documentation. + * @see #ZENITH_8_POINT_5 * ComprehensiveZmanimCalendar#getTzaisGeonim8Point5Degrees() that returns an identical time to this generic tzais */ - public Instant getTzaisGeonim8Point5Degrees() { + public Date getTzais() { return getSunsetOffsetByDegrees(ZENITH_8_POINT_5); } /** - * Returns alos (dawn) based on the time when the sun is {@link ZENITH_16_POINT_1 16.1°} below the - * eastern {@link GEOMETRIC_ZENITH geometric horizon} before {@link getSunriseWithElevation() sunrise}. This is based on the + * Returns alos (dawn) based on the time when the sun is {@link #ZENITH_16_POINT_1 16.1°} below the + * eastern {@link #GEOMETRIC_ZENITH geometric horizon} before {@link #getSunrise() sunrise}. This is based on the * calculation that the time between dawn and sunrise (and sunset to nightfall) is 72 minutes, the time that is * takes to walk 4 mil at * 18 minutes a mil (Rambam and others). The sun's position - * below the horizon 72 minutes before {@link getSunriseWithElevation() sunrise} in Jerusalem on the around the equinox / equilux is - * 16.1° below {@link GEOMETRIC_ZENITH}. + * 16.1° below {@link #GEOMETRIC_ZENITH}. * - * @see ComprehensiveZmanimCalendar#getTzais16Point1Degrees() + * @see #ZENITH_16_POINT_1 + * @see ComprehensiveZmanimCalendar#getAlos16Point1Degrees() * - * @return The Instant of dawn. If the calculation can't be computed such as northern and southern + * @return The Date of dawn. If the calculation can't be computed such as northern and southern * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach * low enough below the horizon for this calculation, a null will be returned. See detailed * explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Instant getAlos16Point1Degrees() { + public Date getAlosHashachar() { return getSunriseOffsetByDegrees(ZENITH_16_POINT_1); } /** - * Method to return alos (dawn) calculated as 72 minutes before {@link getSunriseWithElevation() sunrise} or - * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting). This time + * Method to return alos (dawn) calculated as 72 minutes before {@link #getSunrise() sunrise} or + * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting). This time * is based on the time to walk the distance of 4 mil at 18 minutes a mil. The * 72-minute time (but not the concept of fixed minutes) is based on the opinion that the time of the Neshef * (twilight between dawn and sunrise) does not vary by the time of year or location but depends on the time it takes * to walk the distance of 4 mil. * - * @return the Instant representing the time. If the calculation can't be computed such as in the Arctic + * @return the Date representing the time. If the calculation can't be computed such as in the Arctic * Circle where there is at least one day a year where the sun does not rise, and one where it does not set, * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} * documentation. */ - public Instant getAlos72Minutes() { - return getTimeOffset(getSunriseBasedOnElevationSetting(), -72 * MINUTE_MILLIS); + public Date getAlos72() { + return getTimeOffset(getElevationAdjustedSunrise(), -72 * MINUTE_MILLIS); } /** - * This method returns {@link getSunTransit() Astronomical chatzos} if the + * This method returns {@link #getSunTransit() Astronomical chatzos} if the * {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculator} class used supports it and - * {@link isUseAstronomicalChatzos() isUseAstronomicalChatzos()} is set to true or the {@link getChatzosAsHalfDay() + * {@link #isUseAstronomicalChatzos() isUseAstronomicalChatzos()} is set to true or the {@link #getChatzosAsHalfDay() * halfway point between sunrise and sunset} if it does not support it, or it is not configured to use it. There are currently * two {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculators} available in the API, the default {@link * com.kosherjava.zmanim.util.NOAACalculator NOAA calculator} and the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO * calculator}. The USNO calculator calculates chatzos as halfway between sunrise and sunset (identical to six shaos - * zmaniyos after sunrise), while the NOAACalculator calculates it more accurately as {@link getSunTransit() astronomical + * zmaniyos after sunrise), while the NOAACalculator calculates it more accurately as {@link #getSunTransit() astronomical * chatzos}. See The Definition of Chatzos * for a detailed explanation of the ways to calculate Chatzos. Since half-day chatzos can be null in * the Arctic on a day when either sunrise or sunset did not happen and astronomical chatzos can be calculated even in the * Arctic, if half-day chatzos calculates as null and astronomical chatzos is supported by the * calculator, astronomical chatzos will be returned to avoid returning a null. * - * @see getSunTransit() - * @see getChatzosAsHalfDay() - * @see isUseAstronomicalChatzos() - * @see setUseAstronomicalChatzos(boolean) - * @return the Instant of chatzos. If the calculation can't be computed such as in the Arctic Circle + * @see AstronomicalCalendar#getSunTransit() + * @see #getChatzosAsHalfDay() + * @see #isUseAstronomicalChatzos() + * @see #setUseAstronomicalChatzos(boolean) + * @return the Date of chatzos. If the calculation can't be computed such as in the Arctic Circle * where there is at least one day where the sun does not rise, and one where it does not set, and the calculator does not * support astronomical calculations (that will never report a null) a null will be returned. * See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Instant getChatzos() { - if (isUseAstronomicalChatzos()) { + public Date getChatzos() { + if (useAstronomicalChatzos) { return getSunTransit(); // can be null of the calculator does not support astronomical chatzos } else { - Instant halfDayChatzos = getChatzosAsHalfDay(); + Date halfDayChatzos = getChatzosAsHalfDay(); if (halfDayChatzos == null) { return getSunTransit(); // can be null if the calculator does not support astronomical chatzos } else { @@ -373,46 +385,10 @@ public Instant getChatzos() { } } - /** - * A method that returns chatzos (hayom or layla) calculated as halfway between the begin - * and end times passed in. If sunrise and sunset (or sunset and the following sunrise for chatzos halayla) - * are passed in, it will be close to, but not exactly occur when the Sun is transiting the celestial meridian due to changes in declination (the - * lengthening or shortening day). A practical example of using this would be calculating chatzos halayla for - * the night of Pesach, where Rav Shlomo Zalman - * Auerbach in the Halichos Shlomo considered chatzos halayla for the end of zman achilas afikoman - * to be halfway between an early tzais that is earlier (degree-wise) than alos the next morning, thus - * making this time earlier than astronomical chatzos. See The Definition of Chatzos for a detailed - * explanation of the ways to calculate Chatzos. This method is a convenience method that calls the parent class's - * {@link getSunTransit(Instant, Instant)}. - * - * @param begin - * the beginning of day or night for calculating chatzos. For chatzos hayom, this can be - * sea level sunrise, or any arbitrary sunrise or alos used as the beginning of the day, and for - * chatzos halayla this can be sea level sunset, or any arbitrary sunset or tzais used as - * the beginning of the night. - * @param end - * the end of day or night for calculating chatzos. For chatzos hayom, this can be sea level - * sunset, or any arbitrary sunset or tzais used as the end of day, and for chatzos halayla - * this can be sea level sunrise, or any arbitrary sunrise or alos used as the end of the night. - * - * @return the Instant representing chatzos. If the calculation can't be computed such as in the - * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does - * not set, null will be returned. See detailed explanation on top of the page. - * @see getSunTransit(Instant, Instant) - * @see getChatzosAsHalfDay() - * @see getChatzos() - */ - public Instant getChatzos(Instant begin, Instant end) { - return getSunTransit(begin, end); - } - /** * Returns chatzos calculated as halfway between sunrise and sunset. Many are of the opinion that - * chatzos is calculated as the midpoint between {@link getSeaLevelSunrise() sea level sunrise} and - * {@link getSeaLevelSunset() sea level sunset}, despite it not being the most accurate way to calculate it. A day + * chatzos is calculated as the midpoint between {@link #getSeaLevelSunrise() sea level sunrise} and + * {@link #getSeaLevelSunset() sea level sunset}, despite it not being the most accurate way to calculate it. A day * starting at alos and ending at tzais using the same time or degree offset will also return * the same time. In reality due to lengthening or shortening of day, this is not necessarily the exact midpoint of * the day, but it is very close. This method allows you to use the NOAACalculator and still calculate chatzos @@ -425,22 +401,21 @@ public Instant getChatzos(Instant begin, Instant end) { * zmaniyos after sunrise. See The Definition * of Chatzos for a detailed explanation of the ways to calculate Chatzos. * - * @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(LocalDate, GeoLocation) - * @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(LocalDate, GeoLocation) - * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(LocalDate, GeoLocation) - * @see getSunTransit(Instant, Instant) - * @see getChatzos() - * @see getChatzos(Instant, Instant) - * @see getSunTransit() - * @see isUseAstronomicalChatzos() + * @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation) + * @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation) + * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation) + * @see AstronomicalCalendar#getSunTransit(Date, Date) + * @see #getChatzos() + * @see #getSunTransit() + * @see #isUseAstronomicalChatzos() * - * @return the Instant of the latest chatzos. If the calculation can't be computed such + * @return the Date of the latest chatzos. If the calculation can't be computed such * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where * it does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Instant getChatzosAsHalfDay() { - return getChatzos(getSeaLevelSunrise(), getSeaLevelSunset()); + public Date getChatzosAsHalfDay() { + return getSunTransit(getSeaLevelSunrise(), getSeaLevelSunset()); } /** @@ -448,15 +423,15 @@ public Instant getChatzosAsHalfDay() { * shaos zmaniyos (temporal hours) after the start of the day, calculated using the start and end of the day passed * to this method. The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal * hours), and the latest zman krias shema is calculated as 3 of those shaos zmaniyos after the beginning of - * the day. If {@link isUseAstronomicalChatzosForOtherZmanim()} is true, the 3 shaos zmaniyos will be - * based on 1/6 of the time between sunrise and {@link getSunTransit() astronomical chatzos}. As an example, passing - * {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea level - * sunrise} and {@link getSeaLevelSunset() sea level sunset} to this method (or {@link getSunriseBasedOnElevationSetting()} and - * {@link getSunsetBasedOnElevationSetting()} that is driven off the {@link isUseElevation()} setting) will return sof zman - * krias shema according to the opinion of the GRA. In cases where - * the start and end dates are not synchronous such as in {@link ComprehensiveZmanimCalendar + * the day. If {@link #isUseAstronomicalChatzosForOtherZmanim()} is true, the 3 shaos zmaniyos will be + * based on 1/6 of the time between sunrise and {@link #getSunTransit() astronomical chatzos}. As an example, passing + * {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea level sunrise} and {@link + * #getSeaLevelSunset() sea level sunset} to this method (or {@link #getElevationAdjustedSunrise()} and {@link + * #getElevationAdjustedSunset()} that is driven off the {@link #isUseElevation()} setting) will return sof zman krias + * shema according to the opinion of the GRA. In cases + * where the start and end dates are not synchronous such as in {@link ComprehensiveZmanimCalendar * #getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees()} false should be passed to the synchronous parameter - * to ensure that {@link isUseAstronomicalChatzosForOtherZmanim()} will not be used. + * to ensure that {@link #isUseAstronomicalChatzosForOtherZmanim()} will not be used. * * @param startOfDay * the start of day for calculating zman krias shema. This can be sunrise or any alos passed @@ -466,15 +441,15 @@ public Instant getChatzosAsHalfDay() { * this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @see isUseAstronomicalChatzosForOtherZmanim() - * @return the Instant of the latest zman shema based on the start and end of day times passed to this + * @see #isUseAstronomicalChatzosForOtherZmanim() + * @return the Date of the latest zman shema based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Instant getSofZmanShma(Instant startOfDay, Instant endOfDay, boolean synchronous) { + public Date getSofZmanShma(Date startOfDay, Date endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(startOfDay, getChatzos(), 3); } else { @@ -483,7 +458,7 @@ public Instant getSofZmanShma(Instant startOfDay, Instant endOfDay, boolean sync } /** - * A generic method for calculating the latest zman krias shema that calls {@link getSofZmanShma(Instant, Instant, boolean)} + * A generic method for calculating the latest zman krias shema that calls {@link #getSofZmanShma(Date, Date, boolean)} * passing false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -492,59 +467,57 @@ public Instant getSofZmanShma(Instant startOfDay, Instant endOfDay, boolean sync * @param endOfDay * the end of day for calculating zman krias shema. This can be sunset or any tzais passed to * this method. - * @return the Instant of the latest zman shema based on the start and end of day times passed to this + * @return the Date of the latest zman shema based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getSofZmanShma(Instant, Instant, boolean) + * @see #getSofZmanShma(Date, Date, boolean) */ - public Instant getSofZmanShma(Instant startOfDay, Instant endOfDay) { + public Date getSofZmanShma(Date startOfDay, Date endOfDay) { return getSofZmanShma(startOfDay, endOfDay, false); } /** * This method returns the latest zman krias shema (time to recite shema in the morning) that is 3 * - * {@link getShaahZmanisGRA() shaos zmaniyos} (solar hours) after {@link getSunriseWithElevation() sunrise} or - * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according + * {@link #getShaahZmanisGra() shaos zmaniyos} (solar hours) after {@link #getSunrise() sunrise} or + * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according * to the GRA. - * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level - * sunset} or from {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the - * {@link isUseElevation()} setting). + * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level + * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the + * {@link #isUseElevation()} setting). * - * @see getSofZmanShma(Instant, Instant) - * @see getShaahZmanisGRA() - * @see isUseElevation() + * @see #getSofZmanShma(Date, Date) + * @see #getShaahZmanisGra() + * @see #isUseElevation() * @see ComprehensiveZmanimCalendar#getSofZmanShmaBaalHatanya() - * @return the Instant of the latest zman shema according to the GRA. If the calculation can't be + * @return the Date of the latest zman shema according to the GRA. If the calculation can't be * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, * and one where it does not set, a null will be returned. See the detailed explanation on top * of the {@link AstronomicalCalendar} documentation. */ - public Instant getSofZmanShmaGRA() { - return getSofZmanShma(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); + public Date getSofZmanShmaGRA() { + return getSofZmanShma(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); } /** - * This method returns the latest zman krias shema (time to recite Shema in the morning) according to the opinion of - * the Magen Avraham (MGA) based on alos being {@link - * getAlos72Minutes() 72} minutes before {@link getSunriseWithElevation() sunrise}. This time is 3 {@link - * getShaahZmanis72Minutes() shaos zmaniyos} (solar hours) after {@link getAlos72Minutes() dawn} based on the opinion - * of the MGA that the day is calculated from a {@link getAlos72Minutes() dawn} of 72 minutes before sunrise to - * {@link getTzais72Minutes() nightfall} of 72 minutes after sunset. This returns the time of 3 * {@link - * getShaahZmanis72Minutes()} after {@link getAlos72Minutes() dawn}. + * This method returns the latest zman krias shema (time to recite shema in the morning) that is 3 * + * {@link #getShaahZmanisMGA() shaos zmaniyos} (solar hours) after {@link #getAlos72()}, according to the + * Magen Avraham (MGA). The day is calculated + * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link + * #getSeaLevelSunset() sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() + * sunset} (depending on the {@link #isUseElevation()} setting). * - * @return the Instant of the latest zman krias shema. If the calculation can't be computed such - * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where - * it does not set, a null will be returned. See detailed explanation on top of the + * @return the Date of the latest zman shema. If the calculation can't be computed such as in + * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it + * does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. - * @see isUseAstronomicalChatzosForOtherZmanim() - * @see getShaahZmanis72Minutes() - * @see getAlos72Minutes() - * @see getSofZmanShmaMGA72Minutes() - * @see getSofZmanShma(Instant, Instant, boolean) + * @see #getSofZmanShma(Date, Date) + * @see ComprehensiveZmanimCalendar#getShaahZmanis72Minutes() + * @see ComprehensiveZmanimCalendar#getAlos72() + * @see ComprehensiveZmanimCalendar#getSofZmanShmaMGA72Minutes() that */ - public Instant getSofZmanShmaMGA72Minutes() { - return getSofZmanShma(getAlos72Minutes(), getTzais72Minutes(), true); + public Date getSofZmanShmaMGA() { + return getSofZmanShma(getAlos72(), getTzais72(), true); } /** @@ -554,35 +527,35 @@ public Instant getSofZmanShmaMGA72Minutes() { * According to the Machtzis Hashekel in Orach Chaim * 235:3, the Pri Megadim in Orach * Chaim 261:2 (see the Biur Halacha) and others (see Hazmanim Bahalacha 17:3 and 17:5) the 72 minutes are standard - * clock minutes any time of the year in any location. Depending on the {@link isUseElevation()} setting, a 72-minute - * offset from either {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunset() sea level sunset} is used. + * clock minutes any time of the year in any location. Depending on the {@link #isUseElevation()} setting, a 72-minute + * offset from either {@link #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} is used. * * @see ComprehensiveZmanimCalendar#getTzais16Point1Degrees() - * @return the Instant representing 72 minutes after sunset. If the calculation can't be + * @return the Date representing 72 minutes after sunset. If the calculation can't be * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, * and one where it does not set, a null will be returned See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Instant getTzais72Minutes() { - return getTimeOffset(getSunsetBasedOnElevationSetting(), 72 * MINUTE_MILLIS); + public Date getTzais72() { + return getTimeOffset(getElevationAdjustedSunset(), 72 * MINUTE_MILLIS); } /** - * A method to return candle lighting time, calculated as {@link getCandleLightingOffset()} minutes before - * {@link getSeaLevelSunset() sea level sunset}. This will return the time for any day of the week, since it can be + * A method to return candle lighting time, calculated as {@link #getCandleLightingOffset()} minutes before + * {@link #getSeaLevelSunset() sea level sunset}. This will return the time for any day of the week, since it can be * used to calculate candle lighting time for Yom Tov (mid-week holidays) as well. Elevation adjustments * are intentionally not performed by this method, but you can calculate it by passing the elevation adjusted sunset - * to {@link getTimeOffset(Instant, long)}. + * to {@link #getTimeOffset(Date, long)}. * * @return candle lighting time. If the calculation can't be computed such as in the Arctic Circle where there is at * least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. * - * @see getSeaLevelSunset() - * @see getCandleLightingOffset() - * @see setCandleLightingOffset(double) + * @see #getSeaLevelSunset() + * @see #getCandleLightingOffset() + * @see #setCandleLightingOffset(double) */ - public Instant getCandleLighting() { + public Date getCandleLighting() { return getTimeOffset(getSeaLevelSunset(), -getCandleLightingOffset() * MINUTE_MILLIS); } @@ -592,14 +565,14 @@ public Instant getCandleLighting() { * end of the day passed to this method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), * and sof zman tfila is calculated as 4 of those shaos zmaniyos after the beginning of the day. - * As an example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() - * sea level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} + * As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() + * sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} * elevation setting) to this method will return zman tfilah according to the opinion of the GRA. This method's synchronous parameter indicates if the start * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. + * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of * the day are not equal, and the halfway point between them is not at chatzos. * @@ -611,14 +584,14 @@ public Instant getCandleLighting() { * to this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Instant of the latest zman tfilah based on the start and end of day times passed + * @return the Date of the latest zman tfilah based on the start and end of day times passed * to this method. If the calculation can't be computed such as in the Arctic Circle where there is at least * one day a year where the sun does not rise, and one where it does not set, a null will be * returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Instant getSofZmanTfila(Instant startOfDay, Instant endOfDay, boolean synchronous) { + public Date getSofZmanTfila(Date startOfDay, Date endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(startOfDay, getChatzos(), 4); } else { @@ -626,109 +599,8 @@ public Instant getSofZmanTfila(Instant startOfDay, Instant endOfDay, boolean syn } } - - /** - * This method returns the latest time for burning chametz on Erev Pesach according to the opinion - * of the GRA. This time is 5 hours into the day based on the - * opinion of the GRA that the day is calculated from - * sunrise to sunset. This returns the time 5 * {@link getShaahZmanisGRA()} after {@link getSeaLevelSunrise() sea - * level sunrise}. If it is not erev Pesach, a null will be returned. - * @return the Instant of the latest time for burning chametz on Erev Pesach. If it is not - * erev Pesach or the calculation can't be computed such as in the Arctic Circle where there is at least - * one day a year where the sun does not rise, and one where it does not set, a null will be - * returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getShaahZmanisGRA() - * @see getSofZmanBiurChametz(Instant, Instant, boolean) - */ - - /** - * A generic method for calculating sof zman biur chametz or the latest time one is allowed burning - * chametz on Erev Pesach that is 5 * shaos zmaniyos (temporal hours) after the start of the - * day, calculated using the start and end of the day passed to this method. If the date is not erev Pesach, a - * null will be returned. The time from the start of day to the end of day is divided into 12 shaos zmaniyos - * (temporal hours), and sof zman biur chametz is calculated as 5 of those shaos zmaniyos after the - * beginning of the day. As an example, passing {@link getSunrise() sunrise} and {@link getSunset() sunset} to this - * method will return sof zman biur chametz according to the opinion of the GRA. This method's synchronous parameter indicates if the start - * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some - * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, - * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. - * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of - * the day are not equal, and the halfway point between them is not at chatzos. - * - * @param startOfDay - * the start of day for calculating sof zman biur chametz. This can be sunrise or any alos - * passed to this method. - * @param endOfDay - * the end of day for calculating sof zman biur chametz. This can be sunset or any tzais - * passed to this method. - * @param synchronous - * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by - * definition chatzos will not be the middle of the day for the zman. - * @return the Instant of the sof zman biur chametz based on the start and end of day times passed - * to this method. If the date is not Erev Pesach or if the calculation can't be computed such as in the - * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does not set, - * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} - * documentation. - */ - public Instant getSofZmanBiurChametz(Instant startOfDay, Instant endOfDay, boolean synchronous) { - JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate()); - if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) { - if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { - return getHalfDayBasedZman(startOfDay, getChatzos(), 5); - } else { - return getShaahZmanisBasedZman(startOfDay, endOfDay, 5); - } - } else { - return null; - } - } - - /** - * A generic method for calculating sof zman achilas chametz or the latest time one is allowed eating - * chametz on Erev Pesach that is 4 * shaos zmaniyos (temporal hours) after the start of the - * day, calculated using the start and end of the day passed to this method. If the date is not erev Pesach, a - * null will be returned. The time from the start of day to the end of day is divided into 12 shaos zmaniyos - * (temporal hours), and sof zman achilas chametz is calculated as 4 of those shaos zmaniyos after the - * beginning of the day. As an example, passing {@link getSunrise() sunrise} and {@link getSunset() sunset} to this - * method will return sof zman achilas chametz according to the opinion of the GRA. This method's synchronous parameter indicates if the start - * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some - * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, - * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. - * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of - * the day are not equal, and the halfway point between them is not at chatzos. - * - * @param startOfDay - * the start of day for calculating sof zman achilas chametz. This can be sunrise or any alos - * passed to this method. - * @param endOfDay - * the end of day for calculating sof zman achilas chametz. This can be sunset or any tzais - * passed to this method. - * @param synchronous - * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by - * definition chatzos will not be the middle of the day for the zman. - * @return the Instant of the sof zman achilas chametz based on the start and end of day times passed - * to this method. If the date is not Erev Pesach or if the calculation can't be computed such as in the - * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does not set, - * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} - * documentation. - */ - public Instant getSofZmanAchilasChametz(Instant startOfDay, Instant endOfDay, boolean synchronous) { - JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate()); - if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) { - return getSofZmanTfila(startOfDay, endOfDay, synchronous); - } else { - return null; - } - } - /** - * A generic method for calculating the latest zman tfila that calls {@link getSofZmanTfila(Instant, Instant, boolean)} + * A generic method for calculating the latest zman tfila that calls {@link #getSofZmanTfila(Date, Date, boolean)} * passing false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -737,55 +609,55 @@ public Instant getSofZmanAchilasChametz(Instant startOfDay, Instant endOfDay, bo * @param endOfDay * the end of day for calculating zman tfilah. This can be sunset or any tzais passed to * this method. - * @return the Instant of the latest zman tfilah based on the start and end of day times passed to this + * @return the Date of the latest zman tfilah based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getSofZmanShma(Instant, Instant, boolean) + * @see #getSofZmanShma(Date, Date, boolean) */ - public Instant getSofZmanTfila(Instant startOfDay, Instant endOfDay) { + public Date getSofZmanTfila(Date startOfDay, Date endOfDay) { return getSofZmanTfila(startOfDay, endOfDay, false); } /** * This method returns the latest zman tfila (time to recite shema in the morning) that is 4 * - * {@link getShaahZmanisGRA() shaos zmaniyos }(solar hours) after {@link getSunriseWithElevation() sunrise} or - * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according + * {@link #getShaahZmanisGra() shaos zmaniyos }(solar hours) after {@link #getSunrise() sunrise} or + * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according * to the GRA. - * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level - * sunset} or from {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the - * {@link isUseElevation()} setting). + * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level + * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the + * {@link #isUseElevation()} setting). * - * @see getSofZmanTfila(Instant, Instant) - * @see getShaahZmanisGRA() + * @see #getSofZmanTfila(Date, Date) + * @see #getShaahZmanisGra() * @see ComprehensiveZmanimCalendar#getSofZmanTfilaBaalHatanya() - * @return the Instant of the latest zman tfilah. If the calculation can't be computed such as in + * @return the Date of the latest zman tfilah. If the calculation can't be computed such as in * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it * does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Instant getSofZmanTfilaGRA() { - return getSofZmanTfila(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); + public Date getSofZmanTfilaGRA() { + return getSofZmanTfila(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); } - /** - * This method returns the latest zman tfila (time to recite shema in the morning) that is 4 * {@link - * getShaahZmanis72Minutes() shaos zmaniyos} (solar hours) after {@link getAlos72Minutes()}, according to the + * This method returns the latest zman tfila (time to recite shema in the morning) that is 4 * + * {@link #getShaahZmanisMGA() shaos zmaniyos} (solar hours) after {@link #getAlos72()}, according to the * Magen Avraham (MGA). The day is calculated - * from 72 minutes before {@link getSunriseBasedOnElevationSetting()} to 72 minutes after {@link - * getSunsetBasedOnElevationSetting()}. The use of elevation depends on the {@link isUseElevation()} setting). + * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link + * #getSeaLevelSunset() sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() + * sunset} (depending on the {@link #isUseElevation()} setting). * - * @return the Instant of the latest zman tfila. If the calculation can't be computed such as in + * @return the Date of the latest zman tfila. If the calculation can't be computed such as in * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it * does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. - * @see getSofZmanTfila(Instant, Instan, boolean) - * @see getShaahZmanis72Minutes() - * @see getAlos72Minutes() + * @see #getSofZmanTfila(Date, Date) + * @see #getShaahZmanisMGA() + * @see #getAlos72() */ - public Instant getSofZmanTfilaMGA72Minutes() { - return getSofZmanTfila(getAlos72Minutes(), getTzais72Minutes(), true); + public Date getSofZmanTfilaMGA() { + return getSofZmanTfila(getAlos72(), getTzais72(), true); } /** @@ -793,18 +665,18 @@ public Instant getSofZmanTfilaMGA72Minutes() { * is 6.5 * shaos zmaniyos (temporal hours) after the start of the day, calculated using the start and end of the * day passed to this method. The time from the start of day to the end of day are divided into 12 shaos zmaniyos * (temporal hours), and mincha gedola is calculated as 6.5 of those shaos zmaniyos after the beginning - * of the day. As an example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or - * {@link getSeaLevelSunrise() sea level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link - * isUseElevation()} elevation setting) to this method will return mincha gedola according to the opinion of the + * of the day. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link + * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link + * #isUseElevation()} elevation setting) to this method will return mincha gedola according to the opinion of the * GRA. Alternatively, this method uses {@link - * isUseAstronomicalChatzosForOtherZmanim()} to control if the time is based on 6.5 shaos zmaniyos into the day + * #isUseAstronomicalChatzosForOtherZmanim()} to control if the time is based on 6.5 shaos zmaniyos into the day * mentioned above, or as half an hour zmaniyos based on the second half of the day after chatzos ({@link - * getSunTransit() astronomical chatzos} if supported by the {@link AstronomicalCalculator calculator} and {@link - * isUseAstronomicalChatzos() configured} or {@link getChatzosAsHalfDay() chatzos as half a day} if not. This + * #getSunTransit() astronomical chatzos} if supported by the {@link AstronomicalCalculator calculator} and {@link + * #isUseAstronomicalChatzos() configured} or {@link #getChatzosAsHalfDay() chatzos as half a day} if not. This * method's synchronous parameter indicates if the start and end of day for the calculation are synchronous, having the same * offset. This is typically the case, but some zmanim calculations are based on a start and end at different offsets * from the real start and end of the day, such as starting the day at alos and an ending it at tzais Geonim - * or some other variant. If the day is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based + * or some other variant. If the day is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based * calculations} will be bypassed. It would be illogical to use a half-day based calculation that start/end at chatzos * when the two "halves" of the day are not equal, and the halfway point between them is not at chatzos. * @@ -816,19 +688,19 @@ public Instant getSofZmanTfilaMGA72Minutes() { * to this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Instant of the time of Mincha gedola based on the start and end of day times + * @return the Date of the time of Mincha gedola based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getSunTransit() - * @see getChatzosAsHalfDay() - * @see getChatzos() - * @see isUseAstronomicalChatzos() - * @see isUseAstronomicalChatzosForOtherZmanim() + * @see #getSunTransit() + * @see #getChatzosAsHalfDay() + * @see #getChatzos() + * @see #isUseAstronomicalChatzos() + * @see #isUseAstronomicalChatzosForOtherZmanim() */ - public Instant getMinchaGedola(Instant startOfDay, Instant endOfDay, boolean synchronous) { + public Date getMinchaGedola(Date startOfDay, Date endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 0.5); } else { @@ -837,7 +709,7 @@ public Instant getMinchaGedola(Instant startOfDay, Instant endOfDay, boolean syn } /** - * A generic method for calculating mincha gedola that calls {@link getMinchaGedola(Instant, Instant, boolean)} passing + * A generic method for calculating mincha gedola that calls {@link #getMinchaGedola(Date, Date, boolean)} passing * false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more * details. @@ -847,52 +719,52 @@ public Instant getMinchaGedola(Instant startOfDay, Instant endOfDay, boolean syn * @param endOfDay * the end of day for calculating Mincha gedola. This can be sunset or any tzais passed to * this method. - * @return the Instant of the latest Mincha gedola based on the start and end of day times passed to this + * @return the Date of the latest Mincha gedola based on the start and end of day times passed to this * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day * a year where the sun does not rise, and one where it does not set, a null will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getMinchaGedola(Instant, Instant, boolean) + * @see #getMinchaGedola(Date, Date, boolean) */ - public Instant getMinchaGedola(Instant startOfDay, Instant endOfDay) { + public Date getMinchaGedola(Date startOfDay, Date endOfDay) { return getMinchaGedola(startOfDay, endOfDay, false); } /** * This method returns the latest mincha gedola,the earliest time one can pray mincha that is 6.5 * - * {@link getShaahZmanisGRA() shaos zmaniyos} (solar hours) after {@link getSunriseWithElevation() sunrise} or - * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according + * {@link #getShaahZmanisGra() shaos zmaniyos} (solar hours) after {@link #getSunrise() sunrise} or + * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according * to the GRA. Mincha gedola is the earliest * time one can pray mincha. The Ramba"m is of the opinion that it is better to delay mincha until - * {@link getMinchaKetanaGRA() mincha ketana GRA} while the Ra"sh, Tur, GRA and others are of the + * {@link #getMinchaKetana() mincha ketana} while the Ra"sh, Tur, GRA and others are of the * opinion that mincha can be prayed lechatchila starting at mincha gedola. - * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level - * sunset} or {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the {@link isUseElevation()} + * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level + * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} * setting). * @todo Consider adjusting this to calculate the time as half an hour zmaniyos after either {@link - * getSunTransit() astronomical chatzos} or {@link getChatzosAsHalfDay() chatzos as half a day} - * for {@link AstronomicalCalculator calculators} that support it, based on {@link isUseAstronomicalChatzos()}. + * #getSunTransit() astronomical chatzos} or {@link #getChatzosAsHalfDay() chatzos as half a day} + * for {@link AstronomicalCalculator calculators} that support it, based on {@link #isUseAstronomicalChatzos()}. * - * @see getMinchaGedola(Instant, Instant) - * @see getShaahZmanisGRA() - * @see getMinchaKetanaGRA() + * @see #getMinchaGedola(Date, Date) + * @see #getShaahZmanisGra() + * @see #getMinchaKetana() * @see ComprehensiveZmanimCalendar#getMinchaGedolaBaalHatanya() - * @return the Instant of the time of mincha gedola. If the calculation can't be computed such as in the + * @return the Date of the time of mincha gedola. If the calculation can't be computed such as in the * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does * not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Instant getMinchaGedolaGRA() { - return getMinchaGedola(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); + public Date getMinchaGedola() { + return getMinchaGedola(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); } /** * A generic method for calculating samuch lemincha ketana, / near mincha ketana time that is half - * an hour before {@link getMinchaKetana(Instant, Instant)} or 9 * shaos zmaniyos (temporal hours) after the + * an hour before {@link #getMinchaKetana(Date, Date)} or 9 * shaos zmaniyos (temporal hours) after the * start of the day, calculated using the start and end of the day passed to this method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), and * samuch lemincha ketana is calculated as 9 of those shaos zmaniyos after the beginning of the day. - * For example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea - * level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} elevation + * For example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea + * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation * setting) to this method will return samuch lemincha ketana according to the opinion of the * GRA. See the Mechaber and Mishna Berurah 232 and zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Instant of the time of Mincha ketana based on the start and end of day times + * @return the Date of the time of Mincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. @@ -917,7 +789,7 @@ public Instant getMinchaGedolaGRA() { * @see ComprehensiveZmanimCalendar#getSamuchLeMinchaKetana16Point1Degrees() * @see ComprehensiveZmanimCalendar#getSamuchLeMinchaKetana72Minutes() */ - public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay, boolean synchronous) { + public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 3); } else { @@ -926,7 +798,7 @@ public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay, boo } /** - * A generic method for calculating samuch lemincha ketana that calls {@link getSamuchLeMinchaKetana(Instant, Instant, boolean)} + * A generic method for calculating samuch lemincha ketana that calls {@link #getSamuchLeMinchaKetana(Date, Date, boolean)} * passing false to the synchronous parameter since there is no way to know if the start and end of the day are * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -935,13 +807,13 @@ public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay, boo * @param endOfDay * the end of day for calculating samuch lemincha ketana. This can be sunset or any tzais * passed to this method. - * @return the Instant of the time of samuch lemincha ketana based on the start and end of day times + * @return the Date of the time of samuch lemincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getSamuchLeMinchaKetana(Instant, Instant, boolean) + * @see #getSamuchLeMinchaKetana(Date, Date, boolean) */ - public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay) { + public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay) { return getSamuchLeMinchaKetana(startOfDay, endOfDay, false); } @@ -952,14 +824,14 @@ public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay) { * of the day passed to this method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), and * mincha ketana is calculated as 9.5 of those shaos zmaniyos after the beginning of the day. As an - * example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea - * level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} + * example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea + * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} * elevation setting) to this method will return mincha ketana according to the opinion of the * GRA. This method's synchronous parameter indicates if the start * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. + * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. * It would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of * the day are not equal, and the halfway point between them is not at chatzos. * @@ -971,14 +843,14 @@ public Instant getSamuchLeMinchaKetana(Instant startOfDay, Instant endOfDay) { * this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Instant of the time of Mincha ketana based on the start and end of day times + * @return the Date of the time of Mincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Instant getMinchaKetana(Instant startOfDay, Instant endOfDay, boolean synchronous) { + public Date getMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 3.5); } else { @@ -987,7 +859,7 @@ public Instant getMinchaKetana(Instant startOfDay, Instant endOfDay, boolean syn } /** - * A generic method for calculating mincha ketana that calls {@link getMinchaKetana(Instant, Instant, boolean)} passing + * A generic method for calculating mincha ketana that calls {@link #getMinchaKetana(Date, Date, boolean)} passing * false to the synchronous parameter since there is no way to know if the start and end of the day are synchronous. * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay @@ -996,38 +868,38 @@ public Instant getMinchaKetana(Instant startOfDay, Instant endOfDay, boolean syn * @param endOfDay * the end of day for calculating Mincha ketana. This can be sunset or any tzais passed to * this method. - * @return the Instant of the time of Mincha ketana based on the start and end of day times + * @return the Date of the time of Mincha ketana based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null will * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getMinchaKetana(Instant, Instant, boolean) + * @see #getMinchaKetana(Date, Date, boolean) */ - public Instant getMinchaKetana(Instant startOfDay, Instant endOfDay) { + public Date getMinchaKetana(Date startOfDay, Date endOfDay) { return getMinchaKetana(startOfDay, endOfDay, false); } /** * This method returns mincha ketana,the preferred earliest time to pray mincha in the * opinion of the Rambam and others, that is 9.5 - * * {@link getShaahZmanisGRA() shaos zmaniyos} (solar hours) after {@link getSunriseWithElevation() sunrise} or - * {@link getSeaLevelSunrise() sea level sunrise} (depending on the {@link isUseElevation()} setting), according + * * {@link #getShaahZmanisGra() shaos zmaniyos} (solar hours) after {@link #getSunrise() sunrise} or + * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according * to the GRA. For more information on this see the - * documentation on {@link getMinchaGedolaGRA() mincha gedola}. - * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level - * sunset} or from {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the {@link isUseElevation()} + * documentation on {@link #getMinchaGedola() mincha gedola}. + * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level + * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} * setting. * - * @see getMinchaKetana(Instant, Instant) - * @see getShaahZmanisGRA() - * @see getMinchaGedolaGRA() + * @see #getMinchaKetana(Date, Date) + * @see #getShaahZmanisGra() + * @see #getMinchaGedola() * @see ComprehensiveZmanimCalendar#getMinchaKetanaBaalHatanya() - * @return the Instant of the time of mincha ketana. If the calculation can't be computed such as in the + * @return the Date of the time of mincha ketana. If the calculation can't be computed such as in the * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does * not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Instant getMinchaKetanaGRA() { - return getMinchaKetana(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); + public Date getMinchaKetana() { + return getMinchaKetana(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); } /** @@ -1036,14 +908,14 @@ public Instant getMinchaKetanaGRA() { * the day passed to the method. * The time from the start of day to the end of day are divided into 12 shaos zmaniyos (temporal hours), and * plag hamincha is calculated as 10.75 of those shaos zmaniyos after the beginning of the day. As an - * example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link getSeaLevelSunrise() sea level - * sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} elevation + * example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea level + * sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation * setting) to this method will return plag mincha according to the opinion of the * GRA. This method's synchronous parameter indicates if the start * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some * zmanim calculations are based on a start and end at different offsets from the real start and end of the day, * such as starting the day at alos and an ending it at tzais Geonim or some other variant. If the day - * is not synchronous a {@link getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed. It + * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. It * would be illogical to use a half-day based calculation that start/end at chatzos when the two "halves" of the * day are not equal, and the halfway point between them is not at chatzos. * @@ -1055,14 +927,14 @@ public Instant getMinchaKetanaGRA() { * this method. * @param synchronous * If the zman has a synchronous start and end of the day. If this is false, using a {@link - * isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by + * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by * definition chatzos will not be the middle of the day for the zman. - * @return the Instant of the time of plag hamincha based on the start and end of day times + * @return the Date of the time of plag hamincha based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. */ - public Instant getPlagHamincha(Instant startOfDay, Instant endOfDay, boolean synchronous) { + public Date getPlagHamincha(Date startOfDay, Date endOfDay, boolean synchronous) { if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { return getHalfDayBasedZman(getChatzos(), endOfDay, 4.75); } else { @@ -1071,103 +943,71 @@ public Instant getPlagHamincha(Instant startOfDay, Instant endOfDay, boolean syn } /** - * A generic method for calculating plag hamincha that calls {@link getPlagHamincha(Instant, Instant, boolean)} passing + * A generic method for calculating plag hamincha that calls {@link #getPlagHamincha(Date, Date, boolean)} passing * false to the synchronous parameter since there is no way to know if the start and end of the day are synchronous. * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. * @param startOfDay * the start of day for calculating plag hamincha. This can be sunrise or any alos passed to this method. * @param endOfDay * the end of day for calculating plag hamincha. This can be sunset or any tzais passed to this method. - * @return the Instant of the time of plag hamincha based on the start and end of day times + * @return the Date of the time of plag hamincha based on the start and end of day times * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is * at least one day a year where the sun does not rise, and one where it does not set, a null * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getPlagHamincha(Instant, Instant, boolean) + * @see #getPlagHamincha(Date, Date, boolean) */ - public Instant getPlagHamincha(Instant startOfDay, Instant endOfDay) { + public Date getPlagHamincha(Date startOfDay, Date endOfDay) { return getPlagHamincha(startOfDay, endOfDay, false); } /** - * This method returns plag hamincha, that is 10.75 * {@link getShaahZmanisGRA() shaos zmaniyos} - * (solar hours) after {@link getSunriseWithElevation() sunrise} or {@link getSeaLevelSunrise() sea level sunrise} (depending on - * the {@link isUseElevation()} setting), according to the plag hamincha, that is 10.75 * {@link #getShaahZmanisGra() shaos zmaniyos} + * (solar hours) after {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on + * the {@link #isUseElevation()} setting), according to the GRA. Plag hamincha is the earliest time that Shabbos can be started. - * The day is calculated from {@link getSeaLevelSunrise() sea level sunrise} to {@link getSeaLevelSunset() sea level - * sunset} or {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() sunset} (depending on the {@link isUseElevation()} + * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level + * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} * - * @see getPlagHamincha(Instant, Instant, boolean) - * @see getPlagHamincha(Instant, Instant) + * @see #getPlagHamincha(Date, Date, boolean) + * @see #getPlagHamincha(Date, Date) * @see ComprehensiveZmanimCalendar#getPlagHaminchaBaalHatanya() - * @return the Instant of the time of plag hamincha. If the calculation can't be computed such as + * @return the Date of the time of plag hamincha. If the calculation can't be computed such as * in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it * does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Instant getPlagHaminchaGRA() { - return getPlagHamincha(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true); + public Date getPlagHamincha() { + return getPlagHamincha(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); } /** - * A method that returns a shaah zmanis ({@link getTemporalHour(Instant, Instant) temporal hour}) according to + * A method that returns a shaah zmanis ({@link #getTemporalHour(Date, Date) temporal hour}) according to * the opinion of the GRA. This calculation divides the day - * based on the opinion of the GRA that the day runs from from {@link getSeaLevelSunrise() sea level - * sunrise} to {@link getSeaLevelSunset() sea level sunset} or {@link getSunriseWithElevation() sunrise} to {@link getSunsetWithElevation() - * sunset} (depending on the {@link isUseElevation()} setting). The day is split into 12 equal parts with each one - * being a shaah zmanis. This method is similar to {@link getTemporalHour()}, but can account for elevation. + * based on the opinion of the GRA that the day runs from from {@link #getSeaLevelSunrise() sea level + * sunrise} to {@link #getSeaLevelSunset() sea level sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() + * sunset} (depending on the {@link #isUseElevation()} setting). The day is split into 12 equal parts with each one + * being a shaah zmanis. This method is similar to {@link #getTemporalHour()}, but can account for elevation. * * @return the long millisecond length of a shaah zmanis calculated from sunrise to sunset. * If the calculation can't be computed such as in the Arctic Circle where there is at least one day a year * where the sun does not rise, and one where it does not set, {@link Long#MIN_VALUE} will be returned. See * detailed explanation on top of the {@link AstronomicalCalendar} documentation. - * @see getTemporalHour(Instant, Instant) - * @see getSeaLevelSunrise() - * @see getSeaLevelSunset() + * @see #getTemporalHour(Date, Date) + * @see #getSeaLevelSunrise() + * @see #getSeaLevelSunset() * @see ComprehensiveZmanimCalendar#getShaahZmanisBaalHatanya() */ - public long getShaahZmanisGRA() { - return getTemporalHour(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting()); - } - - /** - * A utility method to return alos (dawn) or tzais (dusk) based on a fractional day offset. As an - * example passing 1.5 to this method as done in the {@link ComprehensiveZmanimCalendar#getTzais90Zmanis()} will return - * the time 90 minutes zmaniyos after {@link getSunsetBasedOnElevationSetting()}, a zman known as - * the achtel zman or 1/8th of the length of the day (12 * 60 = 720-minute day / 8 = 90 or 1.5 hours - * zmaniyos) after sunset. - * @param hours the number of shaos zmaniyos (temporal hours) before sunrise or after sunset that defines dawn - * or dusk. If a negative number is passed in, it will return the time of alos (dawn) (subtracting the - * time from sunrise) and if a positive number is passed in, it will return the time of tzais (dusk) - * (adding the time to sunset). If 0 is passed in, a null will be returned (since we can't tell if it - * is sunrise or sunset based). - * @return the Instant representing the time. If the calculation can't be computed such as in the Arctic - * Circle where there is at least one day a year where the sun does not rise, and one where it does not set, - * a null will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} - * documentation. A null will also be returned if 0 is passed in, since we can't tell if it is a - * sunrise or sunset based zman. - * @see ComprehensiveZmanimCalendar...Zmanis() - * based zmanim. - */ - public Instant getZmanisBasedOffset(double hours) { - long shaahZmanis = getShaahZmanisGRA(); - if (shaahZmanis == Long.MIN_VALUE || hours == 0) { - return null; - } - - if (hours > 0) { - return getTimeOffset(getSunsetBasedOnElevationSetting(), (long) (shaahZmanis * hours)); - } else { - return getTimeOffset(getSunriseBasedOnElevationSetting(), (long) (shaahZmanis * hours)); - } + public long getShaahZmanisGra() { + return getTemporalHour(getElevationAdjustedSunrise(), getElevationAdjustedSunset()); } /** * A method that returns a shaah zmanis (temporal hour) according to the opinion of the Magen Avraham (MGA) based on a 72-minute alos * and tzais. This calculation divides the day that runs from dawn to dusk (for sof zman krias shema and - * tfila). Dawn for this calculation is 72 minutes before {@link getSunriseWithElevation() sunrise} or {@link getSeaLevelSunrise() - * sea level sunrise} (depending on the {@link isUseElevation()} elevation setting) and dusk is 72 minutes after {@link - * getSunsetWithElevation() sunset} or {@link getSeaLevelSunset() sea level sunset} (depending on the {@link isUseElevation()} elevation + * tfila). Dawn for this calculation is 72 minutes before {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() + * sea level sunrise} (depending on the {@link #isUseElevation()} elevation setting) and dusk is 72 minutes after {@link + * #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation * setting). This day is split into 12 equal parts with each part being a shaah zmanis. Alternate methods of calculating * a shaah zmanis according to the Magen Avraham (MGA) are available in the subclass {@link ComprehensiveZmanimCalendar}. * @@ -1176,8 +1016,8 @@ public Instant getZmanisBasedOffset(double hours) { * where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public long getShaahZmanis72Minutes() { - return getTemporalHour(getAlos72Minutes(), getTzais72Minutes()); + public long getShaahZmanisMGA() { + return getTemporalHour(getAlos72(), getTzais72()); } /** @@ -1201,38 +1041,38 @@ public ZmanimCalendar(GeoLocation location) { } /** - * A method to get the offset in minutes before {@link getSeaLevelSunset() sea level sunset} which + * A method to get the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} which * is used in calculating candle lighting time. The default time used is 18 minutes before sea level sunset. Some * calendars use 15 minutes, while the custom in Jerusalem is to use a 40-minute offset. Please check the local custom * for candle lighting time. * * @return Returns the currently set candle lighting offset in minutes. - * @see getCandleLighting() - * @see setCandleLightingOffset(double) + * @see #getCandleLighting() + * @see #setCandleLightingOffset(double) */ public double getCandleLightingOffset() { return candleLightingOffset; } /** - * A method to set the offset in minutes before {@link getSeaLevelSunset() sea level sunset} that is + * A method to set the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} that is * used in calculating candle lighting time. The default time used is 18 minutes before sunset. Some calendars use 15 * minutes, while the custom in Jerusalem is to use a 40-minute offset. * * @param candleLightingOffset * The candle lighting offset to set in minutes. - * @see getCandleLighting() - * @see getCandleLightingOffset() + * @see #getCandleLighting() + * @see #getCandleLightingOffset() */ public void setCandleLightingOffset(double candleLightingOffset) { this.candleLightingOffset = candleLightingOffset; } /** - * This is a utility method to determine if the current Instant passed in has a melacha (work) prohibition. + * This is a utility method to determine if the current Date (date-time) passed in has a melacha (work) prohibition. * Since there are many opinions on the time of tzais, the tzais for the current day has to be passed to this - * class. Sunset is the classes current day's {@link getSunsetBasedOnElevationSetting() elevation adjusted sunset} that observes the - * {@link isUseElevation()} settings. The {@link JewishCalendar#getInIsrael()} will be set by the inIsrael parameter. + * class. Sunset is the classes current day's {@link #getElevationAdjustedSunset() elevation adjusted sunset} that observes the + * {@link #isUseElevation()} settings. The {@link JewishCalendar#getInIsrael()} will be set by the inIsrael parameter. * * @param currentTime the current time * @param tzais the time of tzais @@ -1244,97 +1084,28 @@ public void setCandleLightingOffset(double candleLightingOffset) { * @see JewishCalendar#hasCandleLighting() * @see JewishCalendar#setInIsrael(boolean) */ - public boolean isAssurBemlacha(Instant currentTime, Instant tzais, boolean inIsrael) { + public boolean isAssurBemlacha(Date currentTime, Date tzais, boolean inIsrael) { JewishCalendar jewishCalendar = new JewishCalendar(); - jewishCalendar.setGregorianDate(getLocalDate()); - + jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH), + getCalendar().get(Calendar.DAY_OF_MONTH)); jewishCalendar.setInIsrael(inIsrael); - if (jewishCalendar.hasCandleLighting() && currentTime.compareTo(getSunsetBasedOnElevationSetting()) >= 0) { //erev shabbos, YT or YT sheni and after shkiah + if (jewishCalendar.hasCandleLighting() && currentTime.compareTo(getElevationAdjustedSunset()) >= 0) { //erev shabbos, YT or YT sheni and after shkiah return true; } //is shabbos or YT and it is before tzais return jewishCalendar.isAssurBemelacha() && currentTime.compareTo(tzais) <= 0; } - - /** - * A method that returns the Baal Hatanya's - * netz amiti (sunrise) without {@link AstronomicalCalculator#getElevationAdjustment(double) - * elevation adjustment}. This forms the base for the Baal Hatanya's dawn-based calculations that are - * calculated as a dip below the horizon before sunrise. - * - * According to the Baal Hatanya, netz amiti, or true (halachic) sunrise, is when the top of the sun's - * disk is visible at an elevation similar to the mountains of Eretz Yisrael. The time is calculated as the point at which - * the center of the sun's disk is 1.583° below the horizon. This degree-based calculation can be found in Rabbi Shalom - * DovBer Levine's commentary on The Baal - * Hatanya's Seder Hachnasas Shabbos. From an elevation of 546 meters, the top of Har Hacarmel, the sun disappears when it is 1° 35' or 1.583° - * below the sea level horizon. This in turn is based on the Gemara Shabbos 35a. There are other opinions brought down by - * Rabbi Levine, including Rabbi Yosef Yitzchok Feigelstock who calculates it as the degrees below the horizon 4 minutes after - * sunset in Yerushalayim (on the equinox). That is brought down as 1.583°. This is identical to the 1° 35' zman - * and is probably a typo and should be 1.683°. These calculations are used by most Chabad calendars that use the Baal Hatanya's zmanim. See - * About Our - * Zmanim Calculations @ Chabad.org. - * - * Note: netz amiti is used only for calculating certain zmanim, and is intentionally unpublished. For - * practical purposes, daytime mitzvos like shofar and lulav should not be done until after the - * published time for netz / sunrise. - * - * @return the Instant representing the exact sea level netz amiti (sunrise) time. If the calculation can't be - * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one - * where it does not set, a null will be returned. See detailed explanation on top of the page. - * - * @see getSunriseWithElevation() - * @see getSeaLevelSunrise() - * @see getSunsetBaalHatanya() - * @see ZENITH_1_POINT_583 - */ - protected Instant getSunriseBaalHatanya() { - return getSunriseOffsetByDegrees(ZENITH_1_POINT_583); - } - - /** - * A method that returns the Baal Hatanya's - * shkiah amiti (sunset) without {@link AstronomicalCalculator#getElevationAdjustment(double) - * elevation adjustment}. This forms the base for the Baal Hatanya's dusk-based calculations that are calculated - * as a dip below the horizon after sunset. - * - * According to the Baal Hatanya, shkiah amiti, true (halachic) sunset, is when the top of the - * sun's disk disappears from view at an elevation similar to the mountains of Eretz Yisrael. - * This time is calculated as the point at which the center of the sun's disk is 1.583 degrees below the horizon. - * - * Note: shkiah amiti is used only for calculating certain zmanim, and is intentionally unpublished. For - * practical purposes, all daytime mitzvos should be completed before the published time for shkiah / sunset. - * - * For further explanation of the calculations used for the Baal Hatanya's zmanim in this library, see - * About Our - * Zmanim Calculations @ Chabad.org. - * - * @return the Instant representing the exact sea level shkiah amiti (sunset) time. If the calculation - * can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does not - * rise, and one where it does not set, a null will be returned. See detailed explanation on top of - * the {@link AstronomicalCalendar} documentation. - * - * @see getSunsetWithElevation() - * @see getSeaLevelSunset() - * @see getSunriseBaalHatanya() - * @see ZENITH_1_POINT_583 - */ - protected Instant getSunsetBaalHatanya() { - return getSunsetOffsetByDegrees(ZENITH_1_POINT_583); - } /** - * A generic utility method for calculating any shaah zmanis (temporal hour) based zman with the day - * defined as the start and end of day (or night) and the number of shaos zmaniyos passed to the method. This - * simplifies the code in other methods such as {@link getPlagHamincha(Instant, Instant)} and cuts down on code replication. - * As an example, passing {@link getSunriseWithElevation() sunrise} and {@link getSunsetWithElevation() sunset} or {@link - * getSeaLevelSunrise() sea level sunrise} and {@link getSeaLevelSunset() sea level sunset} (depending on the {@link - * isUseElevation()} elevation setting) and 10.75 hours to this method will return plag mincha according to the - * opinion of the GRA. + * A generic utility method for calculating any shaah zmanis (temporal hour) based zman with the + * day defined as the start and end of day (or night) and the number of shaos zmaniyos passed to the + * method. This simplifies the code in other methods such as {@link #getPlagHamincha(Date, Date)} and cuts down on + * code replication. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link + * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the + * {@link #isUseElevation()} elevation setting) and 10.75 hours to this method will return plag mincha + * according to the opinion of the GRA. * * @param startOfDay * the start of day for calculating the zman. This can be sunrise or any alos passed @@ -1344,13 +1115,13 @@ protected Instant getSunsetBaalHatanya() { * this method. * @param hours * the number of shaos zmaniyos (temporal hours) to offset from the start of day - * @return the Instant of the time of zman with the shaos zmaniyos (temporal hours) + * @return the Date of the time of zman with the shaos zmaniyos (temporal hours) * in the day offset from the start of day passed to this method. If the calculation can't be computed such * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one * where it does not set, a null will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. */ - public Instant getShaahZmanisBasedZman(Instant startOfDay, Instant endOfDay, double hours) { + public Date getShaahZmanisBasedZman(Date startOfDay, Date endOfDay, double hours) { long shaahZmanis = getTemporalHour(startOfDay, endOfDay); return getTimeOffset(startOfDay, shaahZmanis * hours); } @@ -1374,9 +1145,9 @@ public Instant getShaahZmanisBasedZman(Instant startOfDay, Instant endOfDay, dou * explanation on top of the page. */ public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) { - Instant seaLevelSunrise = getSeaLevelSunrise(); - Instant seaLevelSunset = getSeaLevelSunset(); - Instant twilight; + Date seaLevelSunrise = getSeaLevelSunrise(); + Date seaLevelSunset = getSeaLevelSunset(); + Date twilight = null; if (sunset) { twilight = getSunsetOffsetByDegrees(GEOMETRIC_ZENITH + degrees); } else { @@ -1385,12 +1156,12 @@ public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) if (seaLevelSunrise == null || seaLevelSunset == null || twilight == null) { return Double.MIN_VALUE; } - double shaahZmanis = (seaLevelSunset.toEpochMilli() - seaLevelSunrise.toEpochMilli()) / 12.0; + double shaahZmanis = (seaLevelSunset.getTime() - seaLevelSunrise.getTime()) / 12.0; long riseSetToTwilight; if (sunset) { - riseSetToTwilight = twilight.toEpochMilli() - seaLevelSunset.toEpochMilli(); + riseSetToTwilight = twilight.getTime() - seaLevelSunset.getTime(); } else { - riseSetToTwilight = seaLevelSunrise.toEpochMilli() - twilight.toEpochMilli(); + riseSetToTwilight = seaLevelSunrise.getTime() - twilight.getTime(); } return riseSetToTwilight / shaahZmanis; } @@ -1418,14 +1189,14 @@ public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) * hamincha. If the number of hours is negative, it will subtract the number of shaos zmaniyos from the end * of the day. * - * @return the Instant of zman based on calculation of the first or second half of the day. If the + * @return the Date of zman based on calculation of the first or second half of the day. If the * calculation can't be computed such as in the Arctic Circle where there is at least one day a year where the * sun does not rise, and one where it does not set, a null will be returned. See detailed explanation * on top of the {@link AstronomicalCalendar} documentation. * * @see ComprehensiveZmanimCalendar#getFixedLocalChatzos() */ - public Instant getHalfDayBasedZman(Instant startOfHalfDay, Instant endOfHalfDay, double hours) { + public Date getHalfDayBasedZman(Date startOfHalfDay, Date endOfHalfDay, double hours) { if (startOfHalfDay == null || endOfHalfDay == null) { return null; } @@ -1450,42 +1221,14 @@ public Instant getHalfDayBasedZman(Instant startOfHalfDay, Instant endOfHalfDay, * can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, * and one where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the * {@link AstronomicalCalendar} documentation. - * @see getHalfDayBasedZman(Instant, Instant, double) - * @see isUseAstronomicalChatzosForOtherZmanim() + * @see #getHalfDayBasedZman(Date, Date, double) + * @see #isUseAstronomicalChatzosForOtherZmanim() * @todo Consider adjusting various shaah zmanis times to use this. */ - public long getHalfDayBasedShaahZmanis(Instant startOfHalfDay, Instant endOfHalfDay) { + public long getHalfDayBasedShaahZmanis(Date startOfHalfDay, Date endOfHalfDay) { if (startOfHalfDay == null || endOfHalfDay == null) { return Long.MIN_VALUE; } - return (endOfHalfDay.toEpochMilli() - startOfHalfDay.toEpochMilli()) / 6; - } - - /** - * @see java.lang.Object#equals(Object) - */ - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object == null || getClass() != object.getClass()) { - return false; - } - if (!super.equals(object)) { - return false; - } - ZmanimCalendar that = (ZmanimCalendar) object; - return useElevation == that.useElevation - && useAstronomicalChatzos == that.useAstronomicalChatzos - && useAstronomicalChatzosForOtherZmanim == that.useAstronomicalChatzosForOtherZmanim - && candleLightingOffset == that.candleLightingOffset; - } - - /** - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return Objects.hash(super.hashCode(), useElevation, useAstronomicalChatzos, - useAstronomicalChatzosForOtherZmanim, Double.hashCode(candleLightingOffset)); + return (endOfHalfDay.getTime() - startOfHalfDay.getTime()) / 6; } } From 4607540efc8cd5bb56ad551ffe0ec56857eb1016 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Mon, 27 Apr 2026 16:23:16 -0400 Subject: [PATCH 06/12] CHANGELOG - remove 4.65 --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fdcebc8..7ab7ab2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,8 +70,7 @@ * `ComprehensiveZmanimcalendar.getMinchaGedolaGreaterThan30()` was moved to the parent `ZmanimCalendar.getMinchaGedolaGreaterThan30(Instant)` that allows it to work with any mincha gedola claculation. * Change `ComprehensiveZmanimcalendar` zmanim that were too early. * `getTzaisGeonim4Point37Degrees()` -> `getTzaisGeonim4Point42Degrees()`. - * `getTzaisGeonim4Point61Degrees()` -> `getTzaisGeonim4Point65Degrees()` - * `getTzaisGeonim4Point65Degrees()` -> `getTzaisGeonim4Point66Degrees()` + * `getTzaisGeonim4Point61Degrees()` -> `getTzaisGeonim4Point66Degrees()` * `ZmanimCalendar` [Astronomical Chatzos based changes](https://github.com/KosherJava/zmanim/commit/c523424b327f173d70f024bdf207ccae0413d487): * Add setting `useAstronomicalChatzos` (defaulted to true) to keep the mistaken compat break introduced in the v2.5.0 release. * Add setting `useAstronomicalChatzosForOtherZmanim` (defaulted to false). From 7d229dc64eaad296127e323b0e711d0e5b18c4d0 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Mon, 27 Apr 2026 21:30:22 -0400 Subject: [PATCH 07/12] CHANGELOG - Remove getTzaisGeonim5Point88Degrees() it is a drop too early. --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab7ab2e..8407320b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,9 +68,10 @@ * Improve null handling in `ComplexZmanimCalendar.getMoladBasedTime()` * Add `ComplexZmanimCalendar.getMisheyakir12Point85Degrees()` * `ComprehensiveZmanimcalendar.getMinchaGedolaGreaterThan30()` was moved to the parent `ZmanimCalendar.getMinchaGedolaGreaterThan30(Instant)` that allows it to work with any mincha gedola claculation. -* Change `ComprehensiveZmanimcalendar` zmanim that were too early. +* Change / remove `ComprehensiveZmanimcalendar` zmanim that were too early. * `getTzaisGeonim4Point37Degrees()` -> `getTzaisGeonim4Point42Degrees()`. * `getTzaisGeonim4Point61Degrees()` -> `getTzaisGeonim4Point66Degrees()` + * Remove `getTzaisGeonim5Point88Degrees()` since it is a drop too early * `ZmanimCalendar` [Astronomical Chatzos based changes](https://github.com/KosherJava/zmanim/commit/c523424b327f173d70f024bdf207ccae0413d487): * Add setting `useAstronomicalChatzos` (defaulted to true) to keep the mistaken compat break introduced in the v2.5.0 release. * Add setting `useAstronomicalChatzosForOtherZmanim` (defaulted to false). From 64a7eb7193d55fcc22dfab775a465f1ecc801f09 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Thu, 30 Apr 2026 09:33:57 -0400 Subject: [PATCH 08/12] Delete lib directory delete obsolete dir and content --- lib/readme.md | 1 - lib/zmanim-1.4.0alpha.jar | Bin 65435 -> 0 bytes lib/zmanimAstronomical-1.4.0alpha.jar | Bin 32437 -> 0 bytes 3 files changed, 1 deletion(-) delete mode 100644 lib/readme.md delete mode 100644 lib/zmanim-1.4.0alpha.jar delete mode 100644 lib/zmanimAstronomical-1.4.0alpha.jar diff --git a/lib/readme.md b/lib/readme.md deleted file mode 100644 index c36754cd..00000000 --- a/lib/readme.md +++ /dev/null @@ -1 +0,0 @@ -The latest Jar files can be downloaded from [Maven Central's KosherJava zmanim project](https://search.maven.org/artifact/com.kosherjava/zmanim). Click on the latest version and direct download of the Jar is available on the top right corner. The Jars available here are old legacy versions that need to be updated. diff --git a/lib/zmanim-1.4.0alpha.jar b/lib/zmanim-1.4.0alpha.jar deleted file mode 100644 index 09af979a6b3b0ae8fe2d7a85c16be597a51892a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65435 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 diff --git a/lib/zmanimAstronomical-1.4.0alpha.jar b/lib/zmanimAstronomical-1.4.0alpha.jar deleted file mode 100644 index f463bee048604a30c476efe69043709aa3e2f035..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32437 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

      ow8FX{y>G?mK9Y%l2RuVOt3NLM&058or9L_ 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 TDA+Fu#P=7`d(X|~*Qfsh7x-an From 17372cd71eab3a41ad9d9ef724a472694f580f02 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Thu, 30 Apr 2026 12:55:20 -0400 Subject: [PATCH 09/12] Update codeql-analysis.yml to use v4 --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 92f186bf..5c855466 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -49,7 +49,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@v4 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl From e50d06a75d9789c18ba712db20feff87d2808723 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Thu, 30 Apr 2026 15:15:00 -0400 Subject: [PATCH 10/12] rever codeql-analysis.yml to @v3 --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5c855466..92f186bf 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -49,7 +49,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v4 + uses: github/codeql-action/autobuild@v3 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl From 1232e933935ab71c2a10c9da2bb5c9446a9d2e78 Mon Sep 17 00:00:00 2001 From: KosherJava Date: Thu, 30 Apr 2026 15:53:18 -0400 Subject: [PATCH 11/12] Update CHANGELOG to match the 3-0 branch --- CHANGELOG.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8407320b..8fcf1729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,8 @@ * `getTzais90()` -> `getTzais90Minutes()` * `getTzais96()` -> `getTzais96Minutes()` * `getTzais120()` -> `getTzais120Minutes()` + * `getChatzos()` -> `getChatzosHayom()` + * `getChatzosAsHalfDay()` -> `getChatzosHayomAsHalfDay()` * Rename some classes the confusingly named `ComplexZmanimCalendar` to `ComrehensiveZmanimCalendar`. * Move "legacy" classes to `java.time` equivelants * All zmanim now return `Instant`s insead of `Date` objects. @@ -65,14 +67,15 @@ * Increase the minimum supported JRE version from version 8 (the code currently almost certainly works on 6 today) to Java 11 or higher. * `JewishCalendar` now has plus and minus methods (matching the `java.time.LocalDate` class) for years, months and days. * Tweaked logic in `AstronomicalCalendar.getInstantFromTime()` to address issues near the dateline. -* Improve null handling in `ComplexZmanimCalendar.getMoladBasedTime()` -* Add `ComplexZmanimCalendar.getMisheyakir12Point85Degrees()` +* Improve null handling in `ComprehensiveZmanimCalendar.getMoladBasedTime()` +* Add `ComprehensiveZmanimCalendar.getMisheyakir12Point85Degrees()` * `ComprehensiveZmanimcalendar.getMinchaGedolaGreaterThan30()` was moved to the parent `ZmanimCalendar.getMinchaGedolaGreaterThan30(Instant)` that allows it to work with any mincha gedola claculation. * Change / remove `ComprehensiveZmanimcalendar` zmanim that were too early. * `getTzaisGeonim4Point37Degrees()` -> `getTzaisGeonim4Point42Degrees()`. * `getTzaisGeonim4Point61Degrees()` -> `getTzaisGeonim4Point66Degrees()` * Remove `getTzaisGeonim5Point88Degrees()` since it is a drop too early * `ZmanimCalendar` [Astronomical Chatzos based changes](https://github.com/KosherJava/zmanim/commit/c523424b327f173d70f024bdf207ccae0413d487): + * Add `getChatzosHalayla()` * Add setting `useAstronomicalChatzos` (defaulted to true) to keep the mistaken compat break introduced in the v2.5.0 release. * Add setting `useAstronomicalChatzosForOtherZmanim` (defaulted to false). * Add `getChatzosAsHalfDay()` to retain the old behavior of chatzos being halfway between sunrise and sunset. @@ -80,12 +83,13 @@ * Add `getHalfDayBasedZman(Date startOfHalfDay, Date endOfHalfDay, double hours)` to allow other zmanim to be impacted by chatzos. * Use `useAstronomicalChatzosForOtherZmanim`. * `ZmanimCalendar` - add utility method `[getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset)`](https://github.com/KosherJava/zmanim/commit/60d1f09322835835035afa507ac2dc852f1cb033) to simplify zmaniyos time calculations. This allows calculations of various percentage of the day zmanim calculations. +* Remove code duplication in `NOAACalculator.getUTCSunrise()` and `.getUTCSunset()` * Use Astronomical Chatzos Halayla (as opposed as halfway between sunset and sunrise or 12 hours after chatzos hayom) * `AstronomicalCalculator` - [add `getSunLowerTransit()`](https://github.com/KosherJava/zmanim/commit/a76a3b65aeb45912bfdb02ce354f74bb97a9d9b2) * `AstronomicalCalculator` - [add abstract method `getUTCMidnight()`](https://github.com/KosherJava/zmanim/commit/f1904b12393c48b069d1333a7397fce66804958d) * `NOAACalculator` - [implement `getUTCMidnight()`](https://github.com/KosherJava/zmanim/commit/b93eea3388bfdcc2dd526bbcb1be37ddb88fee08) * `AstronomicalCalculator` - [add abstract method `getUTCMidnight()`](https://github.com/KosherJava/zmanim/commit/1223dd0b6ad2b492818aacc5eb478747989e0ace) -* `ComplexZmanimCalendar` - [significant updates](https://github.com/KosherJava/zmanim/commit/46800aa750ac56c2da9bc55fbf976ea1a092221d) +* `ComprehensiveZmanimCalendar` - [significant updates](https://github.com/KosherJava/zmanim/commit/46800aa750ac56c2da9bc55fbf976ea1a092221d) * Started coding some zmanim to use the half-day zmanim config. * Change `getFixedLocalChatzosBasedZmanim()` in favor of `getHalfDayBasedZman()` in the parent `ZmanimCalendar class. * `getFixedLocalChatzos()` now just calls the new getLocalMeanTime(12.0) in the grandparent AstronomicalCalendar class. @@ -97,6 +101,9 @@ * Update Tefila method to Use [Consistent Spelling](https://github.com/KosherJava/zmanim/commit/bca6ddb85542683f229d905636a06fbfc66fbe03). * `HebrewdateFormatter` * add method [`formatParsha(JewishCalendar.Parsha parsha)`](https://github.com/KosherJava/zmanim/commit/ee3347b04bf0f4221bc8aa71af59437cd7533f72) to allow formatting of a parsha retrieved from `JewishCalendar.getUpcomingParshah()`. + * Add `getHebrewMonthList()` and `setHebrewMonthList(String[])`. This allows overriding the default month of Chesvan to Marcheshvan etc. + * Throw an `IllegalArgumentException` if the array length of months != 14 + * Remove the experimental and private `formatMolad(long moladChalakim)` * [Fix NullPointer in HebrewDateFormatter week formatting](https://github.com/KosherJava/zmanim/commit/6cef302f4ac815941c1f61765f2749d698f86042) * `TefilaRules` * [add `isMizmorLesodaRecited()`](https://github.com/KosherJava/zmanim/commit/2cde42644dc72a49b3e4228244bc79cc276e138e) From ed4556ec4fd0acda23d5132e680437e93f807fdf Mon Sep 17 00:00:00 2001 From: Ely Date: Tue, 5 May 2026 23:59:54 -0400 Subject: [PATCH 12/12] add synchronize --- .../kosherjava/zmanim/hebrewcalendar/JewishCalendar.java | 6 +++--- .../com/kosherjava/zmanim/hebrewcalendar/JewishDate.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java index 533013d5..8d8e7c92 100644 --- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java +++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java @@ -482,7 +482,7 @@ private int getParshaYearType() { * * @return the current parsha. */ - public Parsha getParshah() { + public synchronized Parsha getParshah() { if (getDayOfWeek() != Calendar.SATURDAY) { return Parsha.NONE; } @@ -532,7 +532,7 @@ public Parsha getUpcomingParshah() { * {@link Parsha#SHUVA Shuva}, {@link Parsha#SHIRA Shira}, or {@link Parsha#NONE Parsha.NONE} for a regular * Shabbos (or any weekday). */ - public Parsha getSpecialShabbos() { + public synchronized Parsha getSpecialShabbos() { if (getDayOfWeek() == Calendar.SATURDAY) { if ((getJewishMonth() == SHEVAT && !isJewishLeapYear()) || (getJewishMonth() == ADAR && isJewishLeapYear())) { if (getJewishDayOfMonth() == 25 || getJewishDayOfMonth() == 27 || getJewishDayOfMonth() == 29) { @@ -593,7 +593,7 @@ public Parsha getSpecialShabbos() { * * @see HebrewDateFormatter#formatYomTov(JewishCalendar) */ - public int getYomTovIndex() { + public synchronized int getYomTovIndex() { final int day = getJewishDayOfMonth(); final int dayOfWeek = getDayOfWeek(); diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java index 0e8a55dd..d3d0df44 100644 --- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java +++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java @@ -701,7 +701,7 @@ public int getDaysInJewishMonth() { * Computes and sets the Jewish date fields based on the provided absolute (Gregorian) date. * @param gregorianAbsDate the Gregorian absolute date. */ - private void setAbsDate(int gregorianAbsDate) { + private synchronized void setAbsDate(int gregorianAbsDate) { if (gregorianAbsDate <= 0) { throw new IllegalArgumentException("Dates in the BC era are not supported"); } @@ -952,7 +952,7 @@ public void setJewishDate(int year, int month, int dayOfMonth) { * larger a larger number of chalakim such as 793 (TaShTzaG) break the chalakim into minutes (18 * chalakim per minutes, so it would be 44 minutes and 1 chelek in the case of 793 (TaShTzaG). */ - public void setJewishDate(int year, int month, int dayOfMonth, int hours, int minutes, int chalakim) { + public synchronized void setJewishDate(int year, int month, int dayOfMonth, int hours, int minutes, int chalakim) { validateJewishDate(year, month, dayOfMonth, hours, minutes, chalakim);