diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 92f186bf..b36e3c0f 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -7,10 +7,10 @@ name: "CodeQL"
on:
push:
- branches: [master]
+ branches: [3-0-mdernization]
pull_request:
# The branches below must be a subset of the branches above
- branches: [master]
+ branches: [3-0-mdernization]
schedule:
- cron: '0 5 * * 1'
@@ -63,4 +63,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@v4
diff --git a/.gitignore b/.gitignore
index e82f6727..28c4c146 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,6 @@ target/
.idea/
zmanim.iml
.gradle
-build
\ No newline at end of file
+build
+local.properties
+*.class
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8fcf1729..ca38b6ff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -55,6 +55,7 @@
* `getTzais120()` -> `getTzais120Minutes()`
* `getChatzos()` -> `getChatzosHayom()`
* `getChatzosAsHalfDay()` -> `getChatzosHayomAsHalfDay()`
+ * `isAssurBemlacha()` -> `isAssurBemelacha()`
* 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.
@@ -69,7 +70,8 @@
* Tweaked logic in `AstronomicalCalendar.getInstantFromTime()` to address issues near the dateline.
* 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.
+* Add `getMinchaGedolaGreaterThan30(Instant)` that allows it to work with any mincha gedola claculation.
+* `ComprehensiveZmanimcalendar.getMinchaGedolaGreaterThan30()` was renamed `getMinchaGedolaGRAGreaterThan30()` for clarity.
* Change / remove `ComprehensiveZmanimcalendar` zmanim that were too early.
* `getTzaisGeonim4Point37Degrees()` -> `getTzaisGeonim4Point42Degrees()`.
* `getTzaisGeonim4Point61Degrees()` -> `getTzaisGeonim4Point66Degrees()`
@@ -99,6 +101,7 @@
* [Add null checks in `getMinchaGedolaAhavatShalom()`](https://github.com/KosherJava/zmanim/commit/93f441f1ff87d4669c91b596eed157c9cf448bca)
* [Fix `getAlos60()` to use `getElevationAdjustedSunrise()`](https://github.com/KosherJava/zmanim/commit/f5a5b2c68e1f0e2f9f4fbdd2cc585085f2914b74)
* Update Tefila method to Use [Consistent Spelling](https://github.com/KosherJava/zmanim/commit/bca6ddb85542683f229d905636a06fbfc66fbe03).
+ * Add [`getSunsetOrWesternmostSolarAzimuth()` and `getSunriseOrEasternmostSolarAzimuth()`](https://github.com/KosherJava/zmanim/commit/ab9a903e94c33d31f1ce006a6102cdfa259786ad) methods.
* `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.
@@ -113,7 +116,10 @@
* [add missing brace to `isYomTov()` and simplify logic](https://github.com/KosherJava/zmanim/commit/e34fc879313b045f35e70b5947e2c2e20a4364c5)
* `GeoLocation` - [add NaN validation to `setLatitude` and `setLongitude`](https://github.com/KosherJava/zmanim/commit/d064715ebeaead29a01ec673f3885ee9bd9c78b4)
* `NOAACalculator` - [fix Solar Azimuth and Elevation](https://github.com/KosherJava/zmanim/commit/860f1939c25b38dd4d23adb1772b12ccbc71fc76)
-* `AstronomicalCalculator` - [add `getSolarAzimuth()` and `getSolarElevation()`](https://github.com/KosherJava/zmanim/commit/feecf7ad2d9ce527cfe0314ae01710d68c6c3c2e)
+* `AstronomicalCalculator` Add some methods
+ * `getSolarAzimuth()`
+ * `getSolarElevation()`
+ * `getTimeAtAzimuth()`
* `AstronomicalCalendar`
* [Fix null handling in `getSunTransit(Date,Date)`](https://github.com/KosherJava/zmanim/commit/8221e2895cbab62b037c16de1711f9faacd78a7b)
* [Deprecate `getSunriseSolarDipFromOffset` and `getSunsetSolarDipFromOffset`](https://github.com/KosherJava/zmanim/commit/0ce858258bff15c11235b1f1063d2eb0ef22b994)
@@ -121,6 +127,7 @@
* [Add `getLocalMeanTime()`](https://github.com/KosherJava/zmanim/commit/14bcdc085011ccce327f69d6a001772c0581fcc2).
* [Move `getSolarMidnight()`](https://github.com/KosherJava/zmanim/commit/a4535717353eb77da10b6951e4a627b10258ac9e) to the parent class where it belongs.
* [Correct USNO noon calculation](https://github.com/KosherJava/zmanim/commit/3735c92289a66039b24d7e2b470955b5297f0ca5) in some locations where it was sometimes 12 hours off.
+ * [Add `getTimeAtAzimuth(double azimuth)`](https://github.com/KosherJava/zmanim/commit/05a3bc3cdb2dbc88ffca89be0828f50abf62969f)
## [2.5.0](https://github.com/KosherJava/zmanim/compare/2.4.0...2.5.0) (2023-06-09)
diff --git a/src/main/java/com/kosherjava/zmanim/AstronomicalCalendar.java b/src/main/java/com/kosherjava/zmanim/AstronomicalCalendar.java
index 04f829d6..33cbee37 100644
--- a/src/main/java/com/kosherjava/zmanim/AstronomicalCalendar.java
+++ b/src/main/java/com/kosherjava/zmanim/AstronomicalCalendar.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2004-2025 Eliyahu Hershfeld
+ * Copyright (C) 2004-2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -16,29 +16,33 @@
package com.kosherjava.zmanim;
import java.math.BigDecimal;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.Objects;
import com.kosherjava.zmanim.util.AstronomicalCalculator;
import com.kosherjava.zmanim.util.GeoLocation;
import com.kosherjava.zmanim.util.ZmanimFormatter;
/**
- * A Java calendar that calculates astronomical times such as {@link #getSunrise() sunrise}, {@link #getSunset()
- * sunset} and twilight times. This class contains a {@link #getCalendar() Calendar} and can therefore use the standard
- * Calendar functionality to change dates etc. The calculation engine used to calculate the astronomical times can be
- * changed to a different implementation by implementing the abstract {@link AstronomicalCalculator} and setting it with
- * the {@link #setAstronomicalCalculator(AstronomicalCalculator)}. A number of different calculation engine
- * implementations are included in the util package.
- * Note: There are times when the algorithms can't calculate proper values for sunrise, sunset and twilight. This
- * is usually caused by trying to calculate times for areas either very far North or South, where sunrise / sunset never
- * happen on that date. This is common when calculating twilight with a deep dip below the horizon for locations as far
- * south of the North Pole as London, in the northern hemisphere. The sun never reaches this dip at certain times of the
- * year. When the calculations encounter this condition a null will be returned when a
- * {@link java.util.Date} is expected and {@link Long#MIN_VALUE} when a long is expected. The
- * reason that Exceptions are not thrown in these cases is because the lack of a rise/set or twilight is
- * not an exception, but an expected condition in many parts of the world.
+ * A Java calendar that calculates astronomical times such as {@link getSunrise() sunrise}, {@link
+ * getSunset() sunset} and twilight times. This class contains a {@link getLocalDate() LocalDate} and can therefore
+ * use the standard Calendar functionality to change dates etc. The calculation engine used to calculate the astronomical times can
+ * be changed to a different implementation by implementing the abstract {@link AstronomicalCalculator} and setting it withthe {@link
+ * setAstronomicalCalculator(AstronomicalCalculator)}. A number of different calculation engine implementations are included in the
+ * util package.
+ * Note: There are times when the algorithms can't calculate proper values for sunrise, sunset and twilight. This is usually
+ * caused by trying to calculate times for areas either very far North or South, where sunrise / sunset never happen on that date.
+ * This is common when calculating twilight with a deep dip below the horizon for locations as far south of the North Pole as London,
+ * in the northern hemisphere. The sun never reaches this dip at certain times of the year. When the calculations encounter this
+ * condition a null will be returned when a {@link java.time.Instant} is expected and {@link Long#MIN_VALUE}
+ * when a long is expected. The reason that Exceptions are not thrown in these cases is because the lack of
+ * a rise/set or twilight is not an exception, but an expected condition in many parts of the world.
*
* Here is a simple example of how to use the API to calculate sunrise. * First create the Calendar for the location you would like to calculate sunrise or sunset times for: @@ -48,31 +52,30 @@ * double latitude = 40.0828; // Lakewood, NJ * double longitude = -74.2094; // Lakewood, NJ * double elevation = 20; // optional elevation correction in Meters - * // the String parameter in getTimeZone() has to be a valid timezone listed in - * // {@link java.util.TimeZone#getAvailableIDs()} - * TimeZone timeZone = TimeZone.getTimeZone("America/New_York"); - * GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone); + * // the String parameter in getZoneId() has to be a valid ZoneId listed in {@link java.time.ZoneId#getAvailableZoneIds()} + * ZoneId zoneId = ZoneId.of("America/New_York"); + * GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, zoneId); * AstronomicalCalendar ac = new AstronomicalCalendar(location); * * * To get the time of sunrise, first set the date you want (if not set, the date will default to today): * *
- * ac.getCalendar().set(Calendar.MONTH, Calendar.FEBRUARY); - * ac.getCalendar().set(Calendar.DAY_OF_MONTH, 8); - * Date sunrise = ac.getSunrise(); + * LocalDate localDate = LocalDate.of(1969, Month.FEBRUARY, 8); + * ac.setLocalDate(localDate); + * Instant sunrise = ac.getSunrise(); ** - * @author © Eliyahu Hershfeld 2004 - 2025 + * @author © Eliyahu Hershfeld 2004 - 2026 */ public class AstronomicalCalendar implements Cloneable { /** - * 90° below the vertical. Used as a basis for most calculations since the location of the sun is 90° below - * the horizon at sunrise and sunset. - * Note : it is important to note that for sunrise and sunset the {@link AstronomicalCalculator#adjustZenith - * adjusted zenith} is required to account for the radius of the sun and refraction. The adjusted zenith should not - * be used for calculations above or below 90° since they are usually calculated as an offset to 90°. + * 90° below the vertical. Used as a basis for most calculations since the location of the sun is 90° below the horizon + * at sunrise and sunset. + * Note : it is important to note that for sunrise and sunset the {@link AstronomicalCalculator#adjustZenith(double, + * double) adjusted zenith} is required to account for the radius of the sun and refraction. The adjusted zenith should not be + * used for calculations above or below 90° since they are usually calculated as an offset to 90°. */ public static final double GEOMETRIC_ZENITH = 90; @@ -90,11 +93,11 @@ public class AstronomicalCalendar implements Cloneable { /** constant for milliseconds in an hour (3,600,000) */ public static final long HOUR_MILLIS = MINUTE_MILLIS * 60; - + /** - * The Java Calendar encapsulated by this class to track the current date used by the class + * The
LocalDate encapsulated by this class to track the current date used by the class
*/
- private Calendar calendar;
+ private LocalDate localDate;
/**
* the {@link GeoLocation} used for calculations.
@@ -107,27 +110,26 @@ public class AstronomicalCalendar implements Cloneable {
private AstronomicalCalculator astronomicalCalculator;
/**
- * The getSunrise method returns a Date representing the
- * {@link AstronomicalCalculator#getElevationAdjustment(double) elevation adjusted} sunrise time. The zenith used
- * for the calculation uses {@link #GEOMETRIC_ZENITH geometric zenith} of 90° plus
- * {@link AstronomicalCalculator#getElevationAdjustment(double)}. This is adjusted by the
- * {@link AstronomicalCalculator} to add approximately 50/60 of a degree to account for 34 archminutes of refraction
- * and 16 archminutes for the sun's radius for a total of {@link AstronomicalCalculator#adjustZenith 90.83333°}.
+ * The getSunrise method returns a Instant representing the {@link AstronomicalCalculator
+ * #getElevationAdjustment(double) elevation adjusted} sunrise time. The zenith used for the calculation uses {@link
+ * GEOMETRIC_ZENITH geometric zenith} of 90° plus {@link AstronomicalCalculator#getElevationAdjustment(double)}. This is
+ * adjusted by the {@link AstronomicalCalculator} to add approximately 50/60 of a degree to account for 34 archminutes of
+ * refraction and 16 archminutes for the sun's radius for a total of {@link AstronomicalCalculator#adjustZenith 90.83333°}.
* See documentation for the specific implementation of the {@link AstronomicalCalculator} that you are using.
*
- * @return the Date representing the exact 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 AstronomicalCalculator#adjustZenith
- * @see #getSeaLevelSunrise()
- * @see AstronomicalCalendar#getUTCSunrise
+ * @return the Instant representing the exact 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 AstronomicalCalculator#adjustZenith(double, double)
+ * @see getSeaLevelSunrise()
+ * @see getUTCSunrise(double)
*/
- public Date getSunrise() {
+ public Instant getSunrise() {
double sunrise = getUTCSunrise(GEOMETRIC_ZENITH);
if (Double.isNaN(sunrise)) {
return null;
} else {
- return getDateFromTime(sunrise, SolarEvent.SUNRISE);
+ return getInstantFromTime(sunrise, SolarEvent.SUNRISE);
}
}
@@ -137,253 +139,236 @@ public Date getSunrise() {
* something that is not affected by elevation. This method returns sunrise calculated at sea level. This forms the
* base for dawn calculations that are calculated as a dip below the horizon before sunrise.
*
- * @return the Date representing the exact sea-level sunrise time. If the calculation can't be computed
+ * @return the Instant representing the exact sea-level 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 AstronomicalCalendar#getSunrise
- * @see AstronomicalCalendar#getUTCSeaLevelSunrise
- * @see #getSeaLevelSunset()
+ * @see getSunrise()
+ * @see getUTCSeaLevelSunrise(double)
+ * @see getSeaLevelSunset()
*/
- public Date getSeaLevelSunrise() {
+ public Instant getSeaLevelSunrise() {
double sunrise = getUTCSeaLevelSunrise(GEOMETRIC_ZENITH);
if (Double.isNaN(sunrise)) {
return null;
} else {
- return getDateFromTime(sunrise, SolarEvent.SUNRISE);
+ return getInstantFromTime(sunrise, SolarEvent.SUNRISE);
}
}
/**
* A method that returns the beginning of civil twilight
- * (dawn) using a zenith of {@link #CIVIL_ZENITH 96°}.
+ * (dawn) using a zenith of {@link CIVIL_ZENITH 96°}.
*
- * @return The Date of the beginning of civil twilight using a zenith of 96°. If the calculation
+ * @return The Instant of the beginning of civil twilight using a zenith of 96°. If the calculation
* can't be computed, null will be returned. See detailed explanation on top of the page.
- * @see #CIVIL_ZENITH
*/
- public Date getBeginCivilTwilight() {
+ public Instant getBeginCivilTwilight() {
return getSunriseOffsetByDegrees(CIVIL_ZENITH);
}
/**
- * A method that returns the beginning of nautical twilight using a zenith of {@link
- * #NAUTICAL_ZENITH 102°}.
+ * A method that returns the beginning of nautical twilight
+ * using a zenith of {@link NAUTICAL_ZENITH 102°}.
*
- * @return The Date of the beginning of nautical twilight using a zenith of 102°. If the calculation
+ * @return The Instant of the beginning of nautical twilight using a zenith of 102°. If the calculation
* can't be computed null will be returned. See detailed explanation on top of the page.
- * @see #NAUTICAL_ZENITH
*/
- public Date getBeginNauticalTwilight() {
+ public Instant getBeginNauticalTwilight() {
return getSunriseOffsetByDegrees(NAUTICAL_ZENITH);
}
/**
- * A method that returns the beginning of astronomical twilight using a zenith of
- * {@link #ASTRONOMICAL_ZENITH 108°}.
+ * A method that returns the beginning of astronomical
+ * twilight using a zenith of {@link ASTRONOMICAL_ZENITH 108°}.
*
- * @return The Date of the beginning of astronomical twilight using a zenith of 108°. If the calculation
+ * @return The Instant of the beginning of astronomical twilight using a zenith of 108°. If the calculation
* can't be computed, null will be returned. See detailed explanation on top of the page.
- * @see #ASTRONOMICAL_ZENITH
*/
- public Date getBeginAstronomicalTwilight() {
+ public Instant getBeginAstronomicalTwilight() {
return getSunriseOffsetByDegrees(ASTRONOMICAL_ZENITH);
}
- /**
- * The getSunset method returns a Date representing the
- * {@link AstronomicalCalculator#getElevationAdjustment(double) elevation adjusted} sunset time. The zenith used for
- * the calculation uses {@link #GEOMETRIC_ZENITH geometric zenith} of 90° plus
- * {@link AstronomicalCalculator#getElevationAdjustment(double)}. This is adjusted by the
- * {@link AstronomicalCalculator} to add approximately 50/60 of a degree to account for 34 archminutes of refraction
- * and 16 archminutes for the sun's radius for a total of {@link AstronomicalCalculator#adjustZenith 90.83333°}.
- * See documentation for the specific implementation of the {@link AstronomicalCalculator} that you are using. Note:
- * In certain cases the calculates sunset will occur before sunrise. This will typically happen when a timezone
- * other than the local timezone is used (calculating Los Angeles sunset using a GMT timezone for example). In this
- * case the sunset date will be incremented to the following date.
- *
- * @return the Date representing the exact 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 page.
- * @see AstronomicalCalculator#adjustZenith
- * @see #getSeaLevelSunset()
- * @see AstronomicalCalendar#getUTCSunset
- */
- public Date getSunset() {
- double sunset = getUTCSunset(GEOMETRIC_ZENITH);
- if (Double.isNaN(sunset)) {
- return null;
- } else {
- return getDateFromTime(sunset, SolarEvent.SUNSET);
- }
- }
-
- /**
- * A method that returns the sunset without {@link AstronomicalCalculator#getElevationAdjustment(double) elevation
- * adjustment}. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
- * something that is not affected by elevation. This method returns sunset calculated at sea level. This forms the
- * base for dusk calculations that are calculated as a dip below the horizon after sunset.
- *
- * @return the Date representing the exact sea-level sunset time. If the calculation can't be computed
+ /**
+ * The getSunset method returns an Instant representing the
+ * {@link AstronomicalCalculator#getElevationAdjustment(double) elevation adjusted} sunset time. The zenith used for the
+ * calculation uses {@link GEOMETRIC_ZENITH geometric zenith} of 90° plus {@link AstronomicalCalculator
+ * #getElevationAdjustment(double)}. This is adjusted by the {@link AstronomicalCalculator} to add approximately 50/60 of a
+ * degree to account for 34 archminutes of refraction and 16 archminutes for the sun's radius for a total of {@link
+ * AstronomicalCalculator#adjustZenith(double, double) 90.83333°}. See documentation for the specific implementation of the
+ * {@link AstronomicalCalculator} that you are using.
+ * Note: In certain cases the calculates sunset will occur before sunrise. This will typically happen when a time zone other than
+ * the local timezone is used (calculating Los Angeles sunset using a GMT time zone for example). In this case the sunset date
+ * will be incremented to the following date.
+ *
+ * @return the Instant representing the exact 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 page.
+ * @see AstronomicalCalculator#adjustZenith(double, double)
+ * @see getSeaLevelSunset()
+ * @see getUTCSunset(double)
+ */
+ public Instant getSunset() {
+ double sunset = getUTCSunset(GEOMETRIC_ZENITH);
+ if (Double.isNaN(sunset)) {
+ return null;
+ } else {
+ return getInstantFromTime(sunset, SolarEvent.SUNSET);
+ }
+ }
+
+ /**
+ * A method that returns the sunset without {@link AstronomicalCalculator#getElevationAdjustment(double) elevation adjustment}.
+ * Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light, something that is not
+ * affected by elevation. This method returns sunset calculated at sea level. This forms the base for dusk calculations that are
+ * calculated as a dip below the horizon after sunset.
+ *
+ * @return the Instant representing the exact sea-level 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 page.
- * @see AstronomicalCalendar#getSunset
- * @see AstronomicalCalendar#getUTCSeaLevelSunset
- * @see #getSunset()
+ * @see getSunset()
+ * @see getUTCSeaLevelSunset(double)
*/
- public Date getSeaLevelSunset() {
+ public Instant getSeaLevelSunset() {
double sunset = getUTCSeaLevelSunset(GEOMETRIC_ZENITH);
if (Double.isNaN(sunset)) {
return null;
} else {
- return getDateFromTime(sunset, SolarEvent.SUNSET);
+ return getInstantFromTime(sunset, SolarEvent.SUNSET);
}
}
/**
* A method that returns the end of civil twilight
- * using a zenith of {@link #CIVIL_ZENITH 96°}.
+ * using a zenith of {@link CIVIL_ZENITH 96°}.
*
- * @return The Date of the end of civil twilight using a zenith of {@link #CIVIL_ZENITH 96°}. If the
+ * @return The Instant of the end of civil twilight using a zenith of {@link CIVIL_ZENITH 96°}. If the
* calculation can't be computed, null will be returned. See detailed explanation on top of the page.
- * @see #CIVIL_ZENITH
*/
- public Date getEndCivilTwilight() {
+ public Instant getEndCivilTwilight() {
return getSunsetOffsetByDegrees(CIVIL_ZENITH);
}
/**
- * A method that returns the end of nautical twilight using a zenith of {@link #NAUTICAL_ZENITH 102°}.
+ * A method that returns the end of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}.
*
- * @return The Date of the end of nautical twilight using a zenith of {@link #NAUTICAL_ZENITH 102°}. If
+ * @return The Instant of the end of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}. If
* the calculation can't be computed, null will be returned. See detailed explanation on top of the
* page.
- * @see #NAUTICAL_ZENITH
*/
- public Date getEndNauticalTwilight() {
+ public Instant getEndNauticalTwilight() {
return getSunsetOffsetByDegrees(NAUTICAL_ZENITH);
}
/**
- * A method that returns the end of astronomical twilight using a zenith of {@link #ASTRONOMICAL_ZENITH 108°}.
+ * A method that returns the end of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH 108°}.
*
- * @return the Date of the end of astronomical twilight using a zenith of {@link #ASTRONOMICAL_ZENITH
+ * @return the Instant of the end of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH
* 108°}. If the calculation can't be computed, null will be returned. See detailed
* explanation on top of the page.
- * @see #ASTRONOMICAL_ZENITH
*/
- public Date getEndAstronomicalTwilight() {
+ public Instant getEndAstronomicalTwilight() {
return getSunsetOffsetByDegrees(ASTRONOMICAL_ZENITH);
}
/**
* A utility method that returns a date offset by the offset time passed in as a parameter. This method casts the
- * offset as a long and calls {@link #getTimeOffset(Date, long)}.
+ * offset as a long and calls {@link getTimeOffset(Instant, long)}.
*
* @param time
* the start time
* @param offset
* the offset in milliseconds to add to the time
- * @return the {@link java.util.Date}with the offset added to it
+ * @return the {@link java.time.Instant} with the offset added to it
*/
- public static Date getTimeOffset(Date time, double offset) {
+ public static Instant getTimeOffset(Instant time, double offset) {
return getTimeOffset(time, (long) offset);
}
-
+
/**
- * A utility method that returns a date offset by the offset time passed in. Please note that the level of light
- * during twilight is not affected by elevation, so if this is being used to calculate an offset before sunrise or
- * after sunset with the intent of getting a rough "level of light" calculation, the sunrise or sunset time passed
- * to this method should be sea level sunrise and sunset.
+ * A utility method that returns an Instant offset by the offset time passed in. Please note that the level of light
+ * during twilight is not affected by elevation, so if this is being used to calculate an offset before sunrise or after sunset
+ * with the intent of getting a rough "level of light" calculation, the sunrise or sunset time passed to this method should be
+ * sea level sunrise and sunset.
*
* @param time
* the start time
- * @param offset
+ * @param offsetMillis
* the offset in milliseconds to add to the time.
- * @return the {@link java.util.Date} with the offset in milliseconds added to it
+ * @return the {@link java.time.Instant} with the offset in milliseconds added to it
*/
- public static Date getTimeOffset(Date time, long offset) {
- if (time == null || offset == Long.MIN_VALUE) {
- return null;
- }
- return new Date(time.getTime() + offset);
+ public static Instant getTimeOffset(Instant time, long offsetMillis) {
+ if (time == null || offsetMillis == Long.MIN_VALUE) {
+ return null;
+ }
+ return time.plusMillis(offsetMillis);
}
-
+
/**
- * A utility method that returns the time of an offset by degrees below or above the horizon of
- * {@link #getSunrise() sunrise}. Note that the degree offset is from the vertical, so for a calculation of 14°
- * before sunrise, an offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
+ * A utility method that returns the time of an offset by degrees below or above the horizon of {@link getSunrise()
+ * sunrise}. Note that the degree offset is from the vertical, so for a calculation of 14° before sunrise, an offset of 14
+ * + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
*
* @param offsetZenith
- * the degrees before {@link #getSunrise()} to use in the calculation. For time after sunrise use
- * negative numbers. Note that the degree offset is from the vertical, so for a calculation of 14°
- * before sunrise, an offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a
- * parameter.
- * @return The {@link java.util.Date} of the offset after (or before) {@link #getSunrise()}. If the calculation
+ * the degrees before {@link getSunrise()} to use in the calculation. For time after sunrise use negative
+ * numbers. Note that the degree offset is from the vertical, so for a calculation of 14° before sunrise, an offset
+ * of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
+ * @return The {@link java.time.Instant} of the offset after (or before) {@link getSunrise()}. 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.
*/
- public Date getSunriseOffsetByDegrees(double offsetZenith) {
- double dawn = getUTCSunrise(offsetZenith);
- if (Double.isNaN(dawn)) {
- return null;
- } else {
- return getDateFromTime(dawn, SolarEvent.SUNRISE);
- }
+ public Instant getSunriseOffsetByDegrees(double offsetZenith) {
+ double dawn = getUTCSunrise(offsetZenith);
+ return Double.isNaN(dawn) ? null
+ : getInstantFromTime(dawn, SolarEvent.SUNRISE);
}
/**
- * A utility method that returns the time of an offset by degrees below or above the horizon of {@link #getSunset()
- * sunset}. Note that the degree offset is from the vertical, so for a calculation of 14° after sunset, an
- * offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
+ * A utility method that returns the time of an offset by degrees below or above the horizon of {@link getSunset()
+ * sunset}. Note that the degree offset is from the vertical, so for a calculation of 14° after sunset, an offset of 14 +
+ * {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
*
* @param offsetZenith
- * the degrees after {@link #getSunset()} to use in the calculation. For time before sunset use negative
- * numbers. Note that the degree offset is from the vertical, so for a calculation of 14° after
- * sunset, an offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
- * @return The {@link java.util.Date}of the offset after (or before) {@link #getSunset()}. 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.
- */
- public Date getSunsetOffsetByDegrees(double offsetZenith) {
- double sunset = getUTCSunset(offsetZenith);
- if (Double.isNaN(sunset)) {
- return null;
- } else {
- return getDateFromTime(sunset, SolarEvent.SUNSET);
- }
+ * the degrees after {@link getSunset()} to use in the calculation. For time before sunset use negative
+ * numbers. Note that the degree offset is from the vertical, so for a calculation of 14° after sunset, an offset
+ * of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
+ * @return The {@link java.time.Instant} of the offset after (or before) {@link getSunset()}. 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
+ * and one where it does not set, a null will be returned. See detailed explanation on top of the page.
+ */
+ public Instant getSunsetOffsetByDegrees(double offsetZenith) {
+ double sunset = getUTCSunset(offsetZenith);
+ return Double.isNaN(sunset) ? null
+ : getInstantFromTime(sunset, SolarEvent.SUNSET);
}
/**
- * Default constructor will set a default {@link GeoLocation#GeoLocation()}, a default
- * {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} and default the calendar to the current date.
+ * Default constructor will set a default {@link GeoLocation#GeoLocation()}, a default {@link AstronomicalCalculator#getDefault()
+ * AstronomicalCalculator} and default the LocalDate to the current date.
*/
public AstronomicalCalendar() {
this(new GeoLocation());
}
/**
- * A constructor that takes in geolocation information as a
- * parameter. The default {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} used for solar
- * calculations is the more accurate {@link com.kosherjava.zmanim.util.NOAACalculator}.
+ * A constructor that takes in geolocation information as a parameter.
+ * The default {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} used for solar calculations is the more
+ * accurate {@link com.kosherjava.zmanim.util.NOAACalculator}.
*
* @param geoLocation
* The location information used for calculating astronomical sun times.
*
- * @see #setAstronomicalCalculator(AstronomicalCalculator) for changing the calculator class.
+ * @see setAstronomicalCalculator(AstronomicalCalculator) for changing the calculator class.
*/
public AstronomicalCalendar(GeoLocation geoLocation) {
- setCalendar(Calendar.getInstance(geoLocation.getTimeZone()));
- setGeoLocation(geoLocation);// duplicate call
+ setLocalDate(LocalDate.now(geoLocation.getZoneId()));
+ setGeoLocation(geoLocation);
setAstronomicalCalculator(AstronomicalCalculator.getDefault());
}
/**
- * A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using
- * daylight savings time.
+ * A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using daylight
+ * savings time.
*
* @param zenith
* the degrees below the horizon. For time after sunrise use negative numbers.
@@ -392,7 +377,7 @@ public AstronomicalCalendar(GeoLocation geoLocation) {
* not set, {@link Double#NaN} will be returned. See detailed explanation on top of the page.
*/
public double getUTCSunrise(double zenith) {
- return getAstronomicalCalculator().getUTCSunrise(getAdjustedCalendar(), getGeoLocation(), zenith, true);
+ return getAstronomicalCalculator().getUTCSunrise(getAdjustedLocalDate(), getGeoLocation(), zenith, true);
}
/**
@@ -406,11 +391,11 @@ public double getUTCSunrise(double zenith) {
* @return The time in the format: 18.75 for 18:45:00 UTC/GMT. 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 Double#NaN} will be returned. See detailed explanation on top of the page.
- * @see AstronomicalCalendar#getUTCSunrise
- * @see AstronomicalCalendar#getUTCSeaLevelSunset
+ * @see getUTCSunrise(double)
+ * @see getUTCSeaLevelSunset(double)
*/
public double getUTCSeaLevelSunrise(double zenith) {
- return getAstronomicalCalculator().getUTCSunrise(getAdjustedCalendar(), getGeoLocation(), zenith, false);
+ return getAstronomicalCalculator().getUTCSunrise(getAdjustedLocalDate(), getGeoLocation(), zenith, false);
}
/**
@@ -422,54 +407,50 @@ public double getUTCSeaLevelSunrise(double zenith) {
* @return The time in the format: 18.75 for 18:45:00 UTC/GMT. 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 Double#NaN} will be returned. See detailed explanation on top of the page.
- * @see AstronomicalCalendar#getUTCSeaLevelSunset
+ * @see getUTCSeaLevelSunset(double)
*/
public double getUTCSunset(double zenith) {
- return getAstronomicalCalculator().getUTCSunset(getAdjustedCalendar(), getGeoLocation(), zenith, true);
+ return getAstronomicalCalculator().getUTCSunset(getAdjustedLocalDate(), getGeoLocation(), zenith, true);
}
/**
- * A method that returns the sunset in UTC time without correction for elevation, time zone offset from GMT and
- * without using daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the
- * amount of visible light, something that is not affected by elevation. This method returns UTC sunset calculated
- * at sea level. This forms the base for dusk calculations that are calculated as a dip below the horizon after
- * sunset.
+ * A method that returns the sunset in UTC time without correction for elevation, time zone offset from GMT and without using
+ * daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
+ * something that is not affected by elevation. This method returns UTC sunset calculated at sea level. This forms the base for
+ * dusk calculations that are calculated as a dip below the horizon after sunset.
*
* @param zenith
* the degrees below the horizon. For time before sunset use negative numbers.
* @return The time in the format: 18.75 for 18:45:00 UTC/GMT. 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 Double#NaN} will be returned. See detailed explanation on top of the page.
- * @see AstronomicalCalendar#getUTCSunset
- * @see AstronomicalCalendar#getUTCSeaLevelSunrise
+ * @see getUTCSunset(double)
+ * @see getUTCSeaLevelSunrise(double)
*/
public double getUTCSeaLevelSunset(double zenith) {
- return getAstronomicalCalculator().getUTCSunset(getAdjustedCalendar(), getGeoLocation(), zenith, false);
+ return getAstronomicalCalculator().getUTCSunset(getAdjustedLocalDate(), getGeoLocation(), zenith, false);
}
/**
- * A method that returns a sea-level based temporal (solar) hour. The day from {@link #getSeaLevelSunrise()
- * sea-level sunrise} to {@link #getSeaLevelSunset() sea-level sunset} is split into 12 equal parts with each
- * one being a temporal hour.
+ * A method that returns a sea-level based temporal (solar) hour. The day from {@link getSeaLevelSunrise() sea-level sunrise} to
+ * {@link getSeaLevelSunset() sea-level sunset} is split into 12 equal parts with each one being a temporal hour.
*
- * @see #getSeaLevelSunrise()
- * @see #getSeaLevelSunset()
- * @see #getTemporalHour(Date, Date)
+ * @see getSeaLevelSunrise()
+ * @see getSeaLevelSunset()
+ * @see getTemporalHour(Instant, Instant)
*
* @return the long millisecond length of a temporal hour. If the calculation can't be computed,
* {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the page.
*
- * @see #getTemporalHour(Date, Date)
*/
public long getTemporalHour() {
return getTemporalHour(getSeaLevelSunrise(), getSeaLevelSunset());
}
/**
- * A utility method that will allow the calculation of a temporal (solar) hour based on the sunrise and sunset
- * passed as parameters to this method. An example of the use of this method would be the calculation of a
- * elevation adjusted temporal hour by passing in {@link #getSunrise() sunrise} and
- * {@link #getSunset() sunset} as parameters.
+ * A utility method that will allow the calculation of a temporal (solar) hour based on the sunrise and sunset passed as
+ * parameters to this method. An example of the use of this method would be the calculation of a elevation adjusted temporal
+ * hour by passing in {@link getSunrise() sunrise} and {@link getSunset() sunset} as parameters.
*
* @param startOfDay
* The start of the day.
@@ -479,124 +460,90 @@ public long getTemporalHour() {
* @return the long millisecond length of the temporal hour. If the calculation can't be computed a
* {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the page.
*
- * @see #getTemporalHour()
+ * @see getTemporalHour()
*/
- public long getTemporalHour(Date startOfDay, Date endOfDay) {
- if (startOfDay == null || endOfDay == null) {
- return Long.MIN_VALUE;
- }
- return (endOfDay.getTime() - startOfDay.getTime()) / 12;
+ public long getTemporalHour(Instant startOfDay, Instant endOfDay) {
+ if (startOfDay == null || endOfDay == null) {
+ return Long.MIN_VALUE;
+ }
+
+ return Duration.between(startOfDay, endOfDay).toMillis() / 12;
}
/**
* A method that returns sundial or solar noon. It occurs when the Sun is transiting the celestial meridian. The calculations used by
- * this class depend on the {@link AstronomicalCalculator} used. If this calendar instance is {@link
- * #setAstronomicalCalculator(AstronomicalCalculator) set} to use the {@link com.kosherjava.zmanim.util.NOAACalculator}
- * (the default) it will calculate astronomical noon. If the calendar instance is to use the
- * {@link com.kosherjava.zmanim.util.SunTimesCalculator}, that does not have code to calculate astronomical noon, the
- * sun transit is calculated as halfway between sea level sunrise and sea level sunset, which can be slightly off the
- * real transit time due to changes in declination (the lengthening or shortening day). See The Definition of Chatzos for details on the proper
+ * href="https://en.wikipedia.org/wiki/Meridian_%28astronomy%29">celestial meridian. The calculations used by this class
+ * depend on the {@link AstronomicalCalculator} used. If this calendar instance is {@link setAstronomicalCalculator(
+ * AstronomicalCalculator) set} to use the {@link com.kosherjava.zmanim.util.NOAACalculator} (the default) it will calculate
+ * astronomical noon. If the calendar instance is to use the {@link com.kosherjava.zmanim.util.SunTimesCalculator}, that does
+ * not have code to calculate astronomical noon, the sun transit is calculated as halfway between sea level sunrise and sea level
+ * sunset, which can be slightly off the real transit time due to changes in declination (the lengthening or shortening day). See
+ * The Definition of Chatzos for details on the proper
* definition of solar noon / midday.
*
- * @return the Date representing Sun's transit. If the calculation can't be computed such as when using
- * the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that does not support getting solar
- * noon for 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 #getSunTransit(Date, Date)
- * @see #getTemporalHour()
+ * @return the Instant representing Sun's transit. If the calculation can't be computed such as when using the {@link
+ * com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that does not support getting solar noon for 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 getSunTransit(Instant, Instant)
+ * @see getTemporalHour()
* @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation)
* @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation)
*/
- public Date getSunTransit() {
- double noon = getAstronomicalCalculator().getUTCNoon(getAdjustedCalendar(), getGeoLocation());
- return getDateFromTime(noon, SolarEvent.NOON);
- }
-
- /**
- * A method that returns solar midnight. It occurs when the Sun is transiting the lower celestial meridian, or when the sun is at it's
- * nadir. The calculations used by this class depend on the {@link
- * AstronomicalCalculator} used. If this calendar instance is {@link #setAstronomicalCalculator(AstronomicalCalculator)
- * set} to use the {@link com.kosherjava.zmanim.util.NOAACalculator} (the default) it will calculate astronomical
- * midnight. If the calendar instance is to use the {@link com.kosherjava.zmanim.util.SunTimesCalculator}, that does not
- * have code to calculate astronomical noon, midnight is calculated as halfway between sea level sunrise and sea level
- * sunset on the other side of the world (180° away), which can be slightly off the real transit time due to changes
- * in declination (the lengthening or shortening day). See The Definition of Chatzos for details on the proper
- * definition of solar noon / midday.
- *
- * @deprecated This method was replaced by {@link #getSolarMidnight()} and will be removed in v3.0.
- *
- * @return the Date representing Sun's lower transit at the end of the current day. If the calculation can't
- * be computed such as when using the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that
- * does not support getting solar noon or midnight for 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. This is not
- * relevant when using the {@link com.kosherjava.zmanim.util.NOAACalculator NOAA Calculator} that is never expected
- * to return null. See the detailed explanation on top of the page.
- *
- * @see #getSunTransit()
- * @see #getSolarMidnight()
- * @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation)
- * @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation)
- */
- @Deprecated // (since="2.6", forRemoval=true)// add back once Java 9 is the minimum supported version
- public Date getSunLowerTransit() {
- return getSolarMidnight();
+ public Instant getSunTransit() {
+ double noon = getAstronomicalCalculator().getUTCNoon(getAdjustedLocalDate(), getGeoLocation());
+ return getInstantFromTime(noon, SolarEvent.NOON);
}
/**
- * A method that returns solar midnight at the end of the current day (that may actually be after midnight of the day it
- * is being calculated for). It occurs when the Sun is transiting the lower celestial meridian, or
- * when the sun is at it's nadir. The calculations used by this class
- * depend on the {@link AstronomicalCalculator} used. If this calendar instance is {@link
- * #setAstronomicalCalculator(AstronomicalCalculator) set} to use the {@link com.kosherjava.zmanim.util.NOAACalculator}
- * (the default) it will calculate astronomical midnight. If the calendar instance is to use the {@link
- * com.kosherjava.zmanim.util.SunTimesCalculator USNO Calculator}, that does not have code to calculate astronomical noon,
- * midnight is calculated as 12 hours after halfway between sea level sunrise and sea level sunset of that day. This can
- * be slightly off the real transit time due to changes in declination (the lengthening or shortening day). See The Definition of Chatzos for details on the proper
+ * A method that returns solar midnight as the end of the day (that may actually be after midnight of the day it is
+ * being calculated for). For example calculating solar midnight for February 8, will calculate it for midnight between February
+ * 8 and February 9. It occurs when the Sun is transiting the
+ * lower celestial meridian, or when the sun is at it's
+ * nadir. The calculations used by this class depend on the {@link
+ * AstronomicalCalculator} used. If this calendar instance is {@link setAstronomicalCalculator(AstronomicalCalculator) set} to use
+ * the {@link com.kosherjava.zmanim.util.NOAACalculator} (the default) it will calculate astronomical midnight. If the calendar
+ * instance is to use the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO Calculator}, that does not have code to
+ * calculate astronomical noon, midnight is calculated as 12 hours after halfway between sea level sunrise and sea level sunset
+ * of that day. This can be slightly off the real transit time due to changes in declination (the lengthening or shortening day).
+ * See The Definition of Chatzos for details on the proper
* definition of solar noon / midday.
*
- * @return the Date representing Sun's lower transit at the end of the current day. If the calculation can't
- * be computed such as when using the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that
- * does not support getting solar noon or midnight for 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. This is not
- * relevant when using the {@link com.kosherjava.zmanim.util.NOAACalculator NOAA Calculator} that is never expected
- * to return null. See the detailed explanation on top of the page.
+ * @return the Instant representing Sun's lower transit at the end of the current day. If the calculation
+ * can't be computed such as when using the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that does
+ * not support getting solar noon or midnight for 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. This is not relevant when using the
+ * {@link com.kosherjava.zmanim.util.NOAACalculator NOAA Calculator} that is never expected to return null.
+ * See the detailed explanation on top of the page.
*
- * @see #getSunTransit()
+ * @see getSunTransit()
* @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation)
* @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation)
*/
- public Date getSolarMidnight() {
- double noon = getAstronomicalCalculator().getUTCMidnight(getAdjustedCalendar(), getGeoLocation());
- return getDateFromTime(noon, SolarEvent.MIDNIGHT);
+ public Instant getSolarMidnight() {
+ double noon = getAstronomicalCalculator().getUTCMidnight(getAdjustedLocalDate(), getGeoLocation());
+ return getInstantFromTime(noon, SolarEvent.MIDNIGHT);
}
/**
- * A method that returns sundial or solar noon. It occurs when the Sun is transiting the celestial meridian. In this class it is
- * calculated as halfway between the sunrise and sunset passed to this method. This time can be slightly off the
- * real transit time due to changes in declination (the lengthening or shortening day).
+ * A method that returns sundial or solar noon (or midnight) calculated as halfway between the times passed in. It is close to,
+ * but not exactly occurs when the Sun is transiting the
+ * celestial meridian. It will not exactly match the
+ * astronomical transit, due to changes in declination (the lengthening or shortening day).
*
* @param startOfDay
- * the start of day for calculating the sun's transit. This can be sea level sunrise, visual sunrise (or
- * any arbitrary start of day) passed to this method.
+ * the start of day for calculating the sun's transit. This can be sea level sunrise, visual sunrise (or any arbitrary
+ * start of day) passed to this method.
* @param endOfDay
- * the end of day for calculating the sun's transit. This can be sea level sunset, visual sunset (or any
- * arbitrary end of day) passed to this method.
+ * the end of day for calculating the sun's transit. This can be sea level sunset, visual sunset (or any arbitrary end
+ * of day) passed to this method.
*
- * @return the Date representing Sun's transit. If the calculation can't be computed such as in the
+ * @return the Instant representing Sun's transit. 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.
*/
- public Date getSunTransit(Date startOfDay, Date endOfDay) {
+ public Instant getSunTransit(Instant startOfDay, Instant endOfDay) {
long temporalHour = getTemporalHour(startOfDay, endOfDay);
if (temporalHour == Long.MIN_VALUE) {
return null;
@@ -609,56 +556,58 @@ public Date getSunTransit(Date startOfDay, Date endOfDay) {
*/
protected enum SolarEvent {
/**SUNRISE A solar event related to sunrise*/SUNRISE, /**SUNSET A solar event related to sunset*/SUNSET,
- /**NOON A solar event related to noon*/NOON, /**MIDNIGHT A solar event related to midnight*/MIDNIGHT
+ /**NOON A solar event related to noon*/NOON, /**MIDNIGHT A solar event related to midnight*/MIDNIGHT,
+ /**NONE solar event representing azimuth or elevation calculations that that can be any time of the day*/ NONE;
}
-
+
/**
- * A method that returns a Date from the time passed in as a parameter.
+ * Return the time at a given azimuth. This often will not occur and a null will be returned.
+ * @param azimuth the azimuth that you want to get the time of day for.
+ * @return the time that the azimuth will be reached. There are cases where this azimuth will never be reached for the date
+ * and location, and a null will be returned in that case.
+ * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getTimeAtAzimuth(LocalDate, GeoLocation, double)
+ */
+ public Instant getTimeAtAzimuth(double azimuth) {
+ double rawAzimuth = getAstronomicalCalculator().getTimeAtAzimuth(getAdjustedLocalDate(), getGeoLocation(), azimuth);
+ return getInstantFromTime(rawAzimuth, SolarEvent.NONE);
+ }
+
+ /**
+ * A method that returns an Instant from the time passed in as a parameter.
*
* @param time
- * The time to be set as the time for the Date. The time expected is in the format: 18.75
+ * The time to be set as the time for the Instant. The time expected is in the format: 18.75
* for 6:45:00 PM.time is sunrise and false if it is sunset
* @param solarEvent the type of {@link SolarEvent}
- * @return The Date object representation of the time double
+ * @return The Instant object representation of the time double
*/
- protected Date getDateFromTime(double time, SolarEvent solarEvent) {
- if (Double.isNaN(time)) {
- return null;
- }
- double calculatedTime = time;
-
- Calendar adjustedCalendar = getAdjustedCalendar();
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- cal.clear();// clear all fields
- cal.set(Calendar.YEAR, adjustedCalendar.get(Calendar.YEAR));
- cal.set(Calendar.MONTH, adjustedCalendar.get(Calendar.MONTH));
- cal.set(Calendar.DAY_OF_MONTH, adjustedCalendar.get(Calendar.DAY_OF_MONTH));
-
- int hours = (int) calculatedTime; // retain only the hours
- calculatedTime -= hours;
- int minutes = (int) (calculatedTime *= 60); // retain only the minutes
- calculatedTime -= minutes;
- int seconds = (int) (calculatedTime *= 60); // retain only the seconds
- calculatedTime -= seconds; // remaining milliseconds
-
- // Check if a date transition has occurred, or is about to occur - this indicates the date of the event is
- // actually not the target date, but the day prior or after
- int localTimeHours = (int)getGeoLocation().getLongitude() / 15;
- if (solarEvent == SolarEvent.SUNRISE && localTimeHours + hours > 18) {
- cal.add(Calendar.DAY_OF_MONTH, -1);
- } else if (solarEvent == SolarEvent.SUNSET && localTimeHours + hours < 6) {
- cal.add(Calendar.DAY_OF_MONTH, 1);
- } else if (solarEvent == SolarEvent.MIDNIGHT && localTimeHours + hours < 12) {
- cal.add(Calendar.DAY_OF_MONTH, 1);
- } else if (solarEvent == SolarEvent.NOON && localTimeHours + hours > 24) {
- cal.add(Calendar.DAY_OF_MONTH, -1);
- }
+ protected Instant getInstantFromTime(double time, SolarEvent solarEvent) {
+ if (Double.isNaN(time)) {
+ return null;
+ }
- cal.set(Calendar.HOUR_OF_DAY, hours);
- cal.set(Calendar.MINUTE, minutes);
- cal.set(Calendar.SECOND, seconds);
- cal.set(Calendar.MILLISECOND, (int) (calculatedTime * 1000));
- return cal.getTime();
+ LocalDate date = getAdjustedLocalDate();
+
+ double localTimeHours = (getGeoLocation().getLongitude() / 15) + time;
+
+ if (solarEvent == SolarEvent.SUNRISE && localTimeHours > 18) {
+ date = date.minusDays(1);
+ } else if (solarEvent == SolarEvent.SUNSET && localTimeHours < 6) {
+ date = date.plusDays(1);
+ } else if (solarEvent == SolarEvent.MIDNIGHT && localTimeHours < 12) {
+ date = date.plusDays(1);
+ } else if (solarEvent == SolarEvent.NOON) {
+ if (localTimeHours < 0) {
+ date = date.plusDays(1);
+ } else if (localTimeHours > 24) {
+ date = date.minusDays(1);
+ }
+ }
+
+ LocalDateTime dateTime = date.atStartOfDay().plusNanos(Math.round(time * HOUR_MILLIS * 1_000_000L)); // tiny change from 3.0 code
+
+ // The computed time is in UTC fractional hours; anchor in UTC before converting.
+ return ZonedDateTime.of(dateTime, ZoneOffset.UTC).toInstant();
}
/**
@@ -675,21 +624,21 @@ protected Date getDateFromTime(double time, SolarEvent solarEvent) {
* efficiently return the the solar elevation (the sun's position in degrees below (or above) the horizon)
* at the given time even in the arctic when there is no sunrise.
* @see AstronomicalCalculator#getSolarElevation(Calendar, GeoLocation)
- * @see #getSunsetSolarDipFromOffset(double)
+ * @see getSunsetSolarDipFromOffset(double)
*/
- @Deprecated // (forRemoval=false) // add back once Java 9 is the minimum supported version
+ @Deprecated(forRemoval=false)
public double getSunriseSolarDipFromOffset(double minutes) {
- Date offsetByDegrees = getSeaLevelSunrise();
+ Instant offsetByDegrees = getSeaLevelSunrise();
if(offsetByDegrees == null) {
return Double.NaN;
}
- Date offsetByTime = getTimeOffset(getSeaLevelSunrise(), -(minutes * MINUTE_MILLIS));
+ Instant offsetByTime = getTimeOffset(getSeaLevelSunrise(), -(minutes * MINUTE_MILLIS));
BigDecimal degrees = new BigDecimal(0);
BigDecimal incrementor = new BigDecimal("0.0001");
- while (offsetByDegrees == null || ((minutes < 0.0 && offsetByDegrees.getTime() < offsetByTime.getTime()) ||
- (minutes > 0.0 && offsetByDegrees.getTime() > offsetByTime.getTime()))) {
+ while (offsetByDegrees == null || ((minutes < 0.0 && offsetByDegrees.toEpochMilli() < offsetByTime.toEpochMilli()) ||
+ (minutes > 0.0 && offsetByDegrees.toEpochMilli() > offsetByTime.toEpochMilli()))) {
if (minutes > 0.0) {
degrees = degrees.add(incrementor);
} else {
@@ -710,23 +659,23 @@ public double getSunriseSolarDipFromOffset(double minutes) {
* @return the degrees below the horizon after sunset that match the offset in minutes passed it as a parameter. If
* the calculation can't be computed (no sunset occurs on this day) a {@link Double#NaN} will be returned.
* @deprecated This method is slow and inefficient and should NEVER be used in a loop. This method should be replaced
- * by calls to {@link AstronomicalCalculator#getSolarElevation(Calendar, GeoLocation)}. That method will
+ * by calls to {@link AstronomicalCalculator#getSolarElevation(ZonedDateTime, GeoLocation)}. That method will
* efficiently return the the solar elevation (the sun's position in degrees below (or above) the horizon)
* at the given time even in the arctic when there is no sunrise.
- * @see AstronomicalCalculator#getSolarElevation(Calendar, GeoLocation)
- * @see #getSunriseSolarDipFromOffset(double)
+ * @see AstronomicalCalculator#getSolarElevation(ZonedDateTime, GeoLocation)
+ * @see getSunriseSolarDipFromOffset(double)
*/
- @Deprecated // (forRemoval=false) // add back once Java 9 is the minimum supported version
+ @Deprecated(forRemoval=false)
public double getSunsetSolarDipFromOffset(double minutes) {
- Date offsetByDegrees = getSeaLevelSunset();
+ Instant offsetByDegrees = getSeaLevelSunset();
if(offsetByDegrees == null) {
return Double.NaN;
}
- Date offsetByTime = getTimeOffset(getSeaLevelSunset(), minutes * MINUTE_MILLIS);
+ Instant offsetByTime = getTimeOffset(getSeaLevelSunset(), minutes * MINUTE_MILLIS);
BigDecimal degrees = new BigDecimal(0);
BigDecimal incrementor = new BigDecimal("0.001");
- while (offsetByDegrees == null || ((minutes > 0.0 && offsetByDegrees.getTime() < offsetByTime.getTime()) ||
- (minutes < 0.0 && offsetByDegrees.getTime() > offsetByTime.getTime()))) {
+ while (offsetByDegrees == null || ((minutes > 0.0 && offsetByDegrees.toEpochMilli() < offsetByTime.toEpochMilli()) ||
+ (minutes < 0.0 && offsetByDegrees.toEpochMilli() > offsetByTime.toEpochMilli()))) {
if (minutes > 0.0) {
degrees = degrees.add(incrementor);
} else {
@@ -738,45 +687,53 @@ public double getSunsetSolarDipFromOffset(double minutes) {
}
/**
- * A method that returns local mean time (LMT) time
- * converted to regular clock time for the number of hours (0.0 to 23.999...) passed to this method. This time is
- * adjusted from standard time to account for the local latitude. The 360° of the globe divided by 24 calculates
- * to 15° per hour with 4 minutes per degree, so at a longitude of 0 , 15, 30 etc... noon is at exactly 12:00pm.
- * Lakewood, N.J., with a longitude of -74.222, is 0.7906 away from the closest multiple of 15 at -75°. This is
- * multiplied by 4 clock minutes (per degree) to yield 3 minutes and 7 seconds for a noon time of 11:56:53am. This
- * method is not tied to the theoretical 15° time zones, but will adjust to the actual time zone and Daylight saving time to return LMT.
- *
- * @param hours
- * the hour (such as 12.0 for noon and 0.0 for midnight) to calculate as LMT. Valid values are in the range of
- * 0.0 to 23.999.... An IllegalArgumentException will be thrown if the value does not fit in the expected range.
- * @return the Date representing the local mean time (LMT) for the number of hours passed in. In Lakewood, NJ, passing 12
- * (noon) will return 11:56:50am.
- * @see GeoLocation#getLocalMeanTimeOffset()
- */
- public Date getLocalMeanTime(double hours) {
- if (hours < 0 || hours >= 24) {
- throw new IllegalArgumentException("Hours must between 0 and 23.9999...");
- }
- return getTimeOffset(getDateFromTime(hours - getGeoLocation().getTimeZone().getRawOffset()
- / (double) HOUR_MILLIS, SolarEvent.SUNRISE), -getGeoLocation().getLocalMeanTimeOffset());
+ * A method that returns local mean time (LMT) time converted to
+ * regular clock time for the local wall-clock time passed to this method. This time is adjusted from standard time to account for
+ * the local latitude. The 360° of the globe divided by 24 calculates to 15° per hour with 4 minutes per degree, so at a
+ * longitude of 0 , 15, 30 etc... noon is at exactly 12:00pm. Lakewood, N.J., with a longitude of -74.222, is 0.7906 away from the
+ * closest multiple of 15 at -75°. This is multiplied by 4 clock minutes (per degree) to yield 3 minutes and 7 seconds for a
+ * noon time of 11:56:53am. This method is not tied to the theoretical 15° time zones, but will adjust to the actual time zone
+ * and Daylight saving time to return LMT.
+ *
+ * @param localTime
+ * the local wall-clock time (such as 12:00 for noon and 00:00 for midnight) to calculate as LMT.
+ * @return the Instant representing the local mean time (LMT) for the time passed in. In Lakewood,
+ * NJ, passing noon will return 11:56:50am.
+ * @see GeoLocation#getLocalMeanTimeOffset(Instant)
+ */
+ public Instant getLocalMeanTime(LocalTime localTime) {
+ Instant localMeanTime = LocalDateTime.of(getAdjustedLocalDate(), localTime).toInstant(ZoneOffset.UTC);
+ long longitudeOffsetMillis = (long) (getGeoLocation().getLongitude() * 4 * MINUTE_MILLIS);
+ return getTimeOffset(localMeanTime, -longitudeOffsetMillis);
}
-
+
/**
- * Adjusts the Calendar to deal with edge cases where the location crosses the antimeridian.
+ * Adjusts the LocalDate to deal with edge cases where the location crosses the antimeridian.
*
- * @see GeoLocation#getAntimeridianAdjustment()
+ * @see GeoLocation#getAntimeridianAdjustment(Instant)
* @return the adjusted Calendar
*/
- private Calendar getAdjustedCalendar(){
- int offset = getGeoLocation().getAntimeridianAdjustment();
- if (offset == 0) {
- return getCalendar();
- }
- Calendar adjustedCalendar = (Calendar) getCalendar().clone();
- adjustedCalendar.add(Calendar.DAY_OF_MONTH, offset);
- return adjustedCalendar;
- }
+ protected LocalDate getAdjustedLocalDate(){
+ int offset = getGeoLocation().getAntimeridianAdjustment(getMidnightLastNight().toInstant());
+ return offset == 0 ? getLocalDate() : getLocalDate().plusDays(offset);
+ }
+
+ /**
+ * Used by Molad based zmanim to determine if zmanim occur during the current day. This is also used as the
+ * anchor for current timezone-offset calculations.
+ * @return midnight at the start of the current local date in the configured timezone
+ */
+ protected ZonedDateTime getMidnightLastNight() {
+ return ZonedDateTime.of(getLocalDate(),LocalTime.MIDNIGHT,getGeoLocation().getZoneId());
+ }
+
+ /**
+ * Used by Molad based zmanim to determine if zmanim occur during the current day.
+ * @return following midnight
+ */
+ protected ZonedDateTime getMidnightTonight() {
+ return ZonedDateTime.of(getLocalDate().plusDays(1),LocalTime.MIDNIGHT,getGeoLocation().getZoneId());
+ }
/**
* Returns an XML formatted representation of the class using the default output of the
@@ -809,12 +766,13 @@ public boolean equals(Object object) {
if (this == object) {
return true;
}
- if (!(object instanceof AstronomicalCalendar)) {
+ if (object == null || getClass() != object.getClass()) {
return false;
}
AstronomicalCalendar aCal = (AstronomicalCalendar) object;
- return getCalendar().equals(aCal.getCalendar()) && getGeoLocation().equals(aCal.getGeoLocation())
- && getAstronomicalCalculator().equals(aCal.getAstronomicalCalculator());
+ return Objects.equals(getLocalDate(), aCal.getLocalDate())
+ && Objects.equals(getGeoLocation(), aCal.getGeoLocation())
+ && Objects.equals(getAstronomicalCalculator(), aCal.getAstronomicalCalculator());
}
/**
@@ -823,9 +781,9 @@ public boolean equals(Object object) {
public int hashCode() {
int result = 17;
result = 37 * result + getClass().hashCode(); // needed or this and subclasses will return identical hash
- result += 37 * result + getCalendar().hashCode();
- result += 37 * result + getGeoLocation().hashCode();
- result += 37 * result + getAstronomicalCalculator().hashCode();
+ result += 37 * result + Objects.hashCode(getLocalDate());
+ result += 37 * result + Objects.hashCode(getGeoLocation());
+ result += 37 * result + Objects.hashCode(getAstronomicalCalculator());
return result;
}
@@ -849,14 +807,13 @@ public GeoLocation getGeoLocation() {
*/
public void setGeoLocation(GeoLocation geoLocation) {
this.geoLocation = geoLocation;
- getCalendar().setTimeZone(geoLocation.getTimeZone());
}
/**
* A method that returns the currently set AstronomicalCalculator.
*
* @return Returns the astronomicalCalculator.
- * @see #setAstronomicalCalculator(AstronomicalCalculator)
+ * @see setAstronomicalCalculator(AstronomicalCalculator)
*/
public AstronomicalCalculator getAstronomicalCalculator() {
return this.astronomicalCalculator;
@@ -876,35 +833,27 @@ public AstronomicalCalculator getAstronomicalCalculator() {
public void setAstronomicalCalculator(AstronomicalCalculator astronomicalCalculator) {
this.astronomicalCalculator = astronomicalCalculator;
}
-
+
/**
- * returns the Calendar object encapsulated in this class.
+ * returns the LocalDate object encapsulated in this class.
*
- * @return Returns the calendar.
+ * @return Returns the LocalDate.
*/
- public Calendar getCalendar() {
- return this.calendar;
+ public LocalDate getLocalDate() {
+ return this.localDate;
}
-
+
/**
- * Sets the Calendar object for us in this class.
- * @param calendar
- * The calendar to set.
+ * Sets the LocalDate object for us in this class.
+ * @param localDate
+ * The LocalDate to set.
*/
- public void setCalendar(Calendar calendar) {
- this.calendar = calendar;
- if (getGeoLocation() != null) {// if available set the Calendar's timezone to the GeoLocation TimeZone
- getCalendar().setTimeZone(getGeoLocation().getTimeZone());
- }
+ public void setLocalDate(LocalDate localDate) {
+ this.localDate = localDate;
}
/**
* A method that creates a deep copy of the object.
- * Note: If the {@link java.util.TimeZone} in the cloned {@link com.kosherjava.zmanim.util.GeoLocation} will
- * be changed from the original, it is critical that
- * {@link com.kosherjava.zmanim.AstronomicalCalendar#getCalendar()}.
- * {@link java.util.Calendar#setTimeZone(TimeZone) setTimeZone(TimeZone)} be called in order for the
- * AstronomicalCalendar to output times in the expected offset after being cloned.
*
* @see java.lang.Object#clone()
*/
@@ -916,9 +865,8 @@ public Object clone() {
// Required by the compiler. Should never be reached since we implement clone()
}
if (clone != null) {
- clone.setGeoLocation((GeoLocation) getGeoLocation().clone());
- clone.setCalendar((Calendar) getCalendar().clone());
- clone.setAstronomicalCalculator((AstronomicalCalculator) getAstronomicalCalculator().clone());
+ clone.setGeoLocation((GeoLocation) getGeoLocation().clone()); // consider converting the GeoLocation class to be immutable to avoid the deep copy
+ clone.setAstronomicalCalculator((AstronomicalCalculator) getAstronomicalCalculator().clone()); // likely not needed
}
return clone;
}
diff --git a/src/main/java/com/kosherjava/zmanim/ComprehensiveZmanimCalendar.java b/src/main/java/com/kosherjava/zmanim/ComprehensiveZmanimCalendar.java
index 99d96397..9add93b3 100644
--- a/src/main/java/com/kosherjava/zmanim/ComprehensiveZmanimCalendar.java
+++ b/src/main/java/com/kosherjava/zmanim/ComprehensiveZmanimCalendar.java
@@ -15,8 +15,8 @@
*/
package com.kosherjava.zmanim;
-import java.util.Calendar;
-import java.util.Date;
+import java.time.Instant;
+import java.time.LocalTime;
import com.kosherjava.zmanim.util.AstronomicalCalculator;
import com.kosherjava.zmanim.util.GeoLocation;
import com.kosherjava.zmanim.hebrewcalendar.JewishCalendar;
@@ -30,8 +30,8 @@
* API. The real power of this API is the ease in calculating zmanim that are not part of the library. The methods for
* zmanim calculations not present in this class or it's superclass {@link ZmanimCalendar} are contained in the
* {@link AstronomicalCalendar}, the base class of the calendars in our API since they are generic methods for calculating
- * time based on degrees or time before or after {@link #getSunrise() sunrise} and {@link #getSunset() sunset} and are of interest
- * for calculation beyond zmanim calculations. Here are some examples.
+ * time based on degrees or time before or after {@link #getSunset() sunrise} and {@link #getSunset()
+ * sunset} and are of interest for calculation beyond zmanim calculations. Here are some examples.
* First create the Calendar for the location you would like to calculate: * *
@@ -39,35 +39,34 @@
* double latitude = 40.0828; // Lakewood, NJ
* double longitude = -74.222; // Lakewood, NJ
* double elevation = 20; // optional elevation correction in Meters
- * // the String parameter in getTimeZone() has to be a valid time zone listed in
- * // {@link java.util.TimeZone#getAvailableIDs()}
- * TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
- * GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone);
+ * // the String parameter in getZoneId() has to be a valid ZoneId listed in {@link java.time.ZoneId#getAvailableZoneIds()}
+ * ZoneId zoneId = ZoneId.of("America/New_York");
+ * GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, zoneId);
* ComprehensiveZmanimCalendar czc = new ComprehensiveZmanimCalendar(location);
* // Optionally set the date or it will default to today's date
- * czc.getCalendar().set(Calendar.MONTH, Calendar.FEBRUARY);
- * czc.getCalendar().set(Calendar.DAY_OF_MONTH, 8);
+ * ZonedDateTime dateTime = ZonedDateTime.of(1969, Month.FEBRUARY.getValue(), 8, 0, 0, 0, 0, location.getZoneId());
+ * czc.setZonedDateTime(dateTime);
*
* Note: For locations such as Israel where the beginning and end of daylight savings time can fluctuate from
* year to year, if your version of Java does not have an up to date time zone database, create a
* {@link java.util.SimpleTimeZone} with the known start and end of DST.
* To get alos calculated as 14° below the horizon (as calculated in the calendars published in Montreal),
- * add {@link AstronomicalCalendar#GEOMETRIC_ZENITH} (90) to the 14° offset to get the desired time:
+ * add {@link GEOMETRIC_ZENITH} (90) to the 14° offset to get the desired time:
*
*
- * Date alos14 = czc.getSunriseOffsetByDegrees({@link AstronomicalCalendar#GEOMETRIC_ZENITH} + 14);
+ * Instant alos14 = czc.getSunriseOffsetByDegrees({@link GEOMETRIC_ZENITH} + 14);
* * To get mincha gedola calculated based on the Magen Avraham (MGA) using a shaah zmanis based on the day starting * 16.1° below the horizon (and ending 16.1° after sunset) the following calculation can be used: * *
- * Date minchaGedola = czc.getTimeOffset(czc.getAlos16point1Degrees(), czc.getShaahZmanis16Point1Degrees() * 6.5);+ * Instant minchaGedola = czc.getTimeOffset(czc.getAlos16point1Degrees(), czc.getShaahZmanis16Point1Degrees() * 6.5); *
* or even simpler using the included convenience methods *
- * Date minchaGedola = czc.getMinchaGedola(czc.getAlos16point1Degrees(), czc.getShaahZmanis16Point1Degrees());+ * Instant minchaGedola = czc.getMinchaGedola(czc.getAlos16point1Degrees(), czc.getShaahZmanis16Point1Degrees()); *
* A little more complex example would be calculating zmanim that rely on a shaah zmanis that is
* not present in this library. While a drop more complex, it is still rather easy. An example would be to calculate
@@ -80,8 +79,8 @@
* that plag hamincha is 10.75 hours after the start of the day, and the following steps are all that it takes.
*
*
- * Date plag = czc.getPlagHamincha(czc.getSunriseOffsetByDegrees({@link AstronomicalCalendar#GEOMETRIC_ZENITH} + 12),
- * czc.getSunsetOffsetByDegrees({@link AstronomicalCalendar#GEOMETRIC_ZENITH} + ZENITH_7_POINT_083));
+ * Instant plag = czc.getPlagHamincha(czc.getSunriseOffsetByDegrees({@link GEOMETRIC_ZENITH} + 12),
+ * czc.getSunsetOffsetByDegrees({@link GEOMETRIC_ZENITH} + ZENITH_7_POINT_083));
*
* Something a drop more challenging, but still simple, would be calculating a zman using the same "complex"
* offset day used in the above-mentioned Manchester calendar, but for a shaos zmaniyos based zman not
@@ -93,15 +92,15 @@
*
*
*
- * long shaahZmanis = czc.getTemporalHour(czc.getSunriseOffsetByDegrees({@link AstronomicalCalendar#GEOMETRIC_ZENITH} + 12),
- * czc.getSunsetOffsetByDegrees({@link AstronomicalCalendar#GEOMETRIC_ZENITH} + ZENITH_7_POINT_083));
- * Date sofZmanAchila = getTimeOffset(czc.getSunriseOffsetByDegrees({@link AstronomicalCalendar#GEOMETRIC_ZENITH} + 12),
+ * long shaahZmanis = czc.getTemporalHour(czc.getSunriseOffsetByDegrees({@link GEOMETRIC_ZENITH} + 12),
+ * czc.getSunsetOffsetByDegrees({@link GEOMETRIC_ZENITH} + ZENITH_7_POINT_083));
+ * Instant sofZmanAchila = getTimeOffset(czc.getSunriseOffsetByDegrees({@link GEOMETRIC_ZENITH} + 12),
* shaahZmanis * 9);
* * Calculating this sof zman achila according to the GRA * is simplicity itself. *
- * Date sofZmanAchila = czc.getTimeOffset(czc.getSunrise(), czc.getShaahZmanisGra() * 9);+ * Instant sofZmanAchila = czc.getTimeOffset(czc.getSunrise(), czc.getShaahZmanisGRA() * 9); * *
long millisecond length of a shaah zmanis. 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 {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the
- * {@link AstronomicalCalendar} documentation.
- */
- public long getShaahZmanis72Minutes() {
- return getShaahZmanisMGA();
+ return getTemporalHour(getAlos60Minutes(), getTzais60Minutes());
}
/**
* Method to return a shaah zmanis (temporal hour) according to the opinion of the Magen Avraham (MGA) based on alos being
- * {@link #getAlos72Zmanis() 72} minutes zmaniyos before {@link #getSunrise() sunrise}. This calculation
+ * {@link #getAlos72Zmanis() 72} minutes zmaniyos before {@link #getSunset() sunrise}. This calculation
* divides the day based on the opinion of the MGA that the day runs from dawn to dusk. Dawn for this calculation
* is 72 minutes zmaniyos before sunrise and dusk is 72 minutes zmaniyos after sunset. This day
* is split into 12 equal parts with each part being a shaah zmanis. This is identical to 1/10th of the day
- * from {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
+ * from {@link #getSunset() sunrise} to {@link #getSunset() sunset}.
*
* @return the long millisecond length of a shaah zmanis. 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
@@ -595,17 +451,17 @@ public long getShaahZmanis72MinutesZmanis() {
* {@link AstronomicalCalendar} documentation.
*/
public long getShaahZmanis90Minutes() {
- return getTemporalHour(getAlos90(), getTzais90());
+ return getTemporalHour(getAlos90Minutes(), getTzais90Minutes());
}
/**
* Method to return a shaah zmanis (temporal hour) according to the opinion of the Magen Avraham (MGA) based on alos being
- * {@link #getAlos90Zmanis() 90} minutes zmaniyos before {@link #getSunrise() sunrise}. This calculation divides
+ * "https://en.wikipedia.org/wiki/Avraham_Gombiner">Magen Avraham (MGA) based on alos being {@link
+ * #getAlos90Zmanis() 90} minutes zmaniyos before {@link #getSunset() sunrise}. This calculation divides
* the day based on the opinion of the MGA that the day runs from dawn to dusk. Dawn for this calculation is 90 minutes
* zmaniyos before sunrise and dusk is 90 minutes zmaniyos after sunset. This day is split into 12 equal
- * parts with each part being a shaah zmanis. This is 1/8th of the day from {@link #getSunrise() sunrise} to
- * {@link #getSunset() sunset}.
+ * parts with each part being a shaah zmanis. This is 1/8th of the day from {@link #getSunset() sunrise}
+ * to {@link #getSunset() sunset}.
*
* @return the long millisecond length of a shaah zmanis. 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
@@ -621,11 +477,11 @@ public long getShaahZmanis90MinutesZmanis() {
/**
* Method to return a shaah zmanis (temporal hour) according to the opinion of the Magen Avraham (MGA) based on alos being {@link
- * #getAlos96Zmanis() 96} minutes zmaniyos before {@link #getSunrise() sunrise}. This calculation divides the
- * day based on the opinion of the MGA that the day runs from dawn to dusk. Dawn for this calculation is 96 minutes
- * zmaniyos before sunrise and dusk is 96 minutes zmaniyos after sunset. This day is split into 12
- * equal parts with each part being a shaah zmanis. This is identical to 1/7.5th of the day from
- * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
+ * #getAlos96Zmanis() 96} minutes zmaniyos before {@link #getSunset() sunrise}. This calculation divides
+ * the day based on the opinion of the MGA that the day runs from dawn to dusk. Dawn for this calculation is 96 minutes
+ * zmaniyos before sunrise and dusk is 96 minutes zmaniyos after sunset. This day is split into 12 equal
+ * parts with each part being a shaah zmanis. This is identical to 1/7.5th of the day from {@link
+ * #getSunset() sunrise} to {@link #getSunset() sunset}.
*
* @return the long millisecond length of a shaah zmanis. 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
@@ -642,7 +498,7 @@ public long getShaahZmanis96MinutesZmanis() {
* Method to return a shaah zmanis (temporal hour) according to the opinion of the
* Chacham Yosef Harari-Raful of Yeshivat Ateret Torah calculated with alos being 1/10th
* of sunrise to sunset day, or {@link #getAlos72Zmanis() 72} minutes zmaniyos of such a day before
- * {@link #getSunrise() sunrise}, and tzais is usually calculated as {@link #getTzaisAteretTorah() 40
+ * {@link #getSunset() sunrise}, and tzais is usually calculated as {@link #getTzaisAteretTorah() 40
* minutes} (configurable to any offset via {@link #setAteretTorahSunsetOffset(double)}) after {@link #getSunset()
* sunset}. This day is split into 12 equal parts with each part being a shaah zmanis. Note that with this
* system, chatzos (midday) will not be the point that the sun is {@link #getSunTransit() halfway across
@@ -719,7 +575,7 @@ public long getShaahZmanisAlos16Point1ToTzais3Point7() {
* {@link AstronomicalCalendar} documentation.
*/
public long getShaahZmanis96Minutes() {
- return getTemporalHour(getAlos96(), getTzais96());
+ return getTemporalHour(getAlos96Minutes(), getTzais96Minutes());
}
/**
@@ -738,20 +594,19 @@ public long getShaahZmanis96Minutes() {
* @see #getShaahZmanis26Degrees()
*/
public long getShaahZmanis120Minutes() {
- return getTemporalHour(getAlos120(), getTzais120());
+ return getTemporalHour(getAlos120Minutes(), getTzais120Minutes());
}
/**
* Method to return a shaah zmanis (temporal hour) according to the opinion of the Magen Avraham (MGA) based on alos being {@link
- * #getAlos120Zmanis() 120} minutes zmaniyos before {@link #getSunrise() sunrise}. This calculation divides
- * the day based on the opinion of the MGA that the day runs from dawn to dusk. Dawn for this calculation is
- * 120 minutes zmaniyos before sunrise and dusk is 120 minutes zmaniyos after sunset. This day is
- * split into 12 equal parts with each part being a shaah zmanis. This is identical to 1/6th of the day from
- * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}. Since zmanim that use this method are
- * extremely late or early and at a point when the sky is a long time past the 18° point where the darkest point
- * is reached, zmanim that use this should only be used lechumra such as delaying the start of
- * nighttime mitzvos.
+ * #getAlos120Zmanis() 120} minutes zmaniyos before {@link #getSunset() sunrise}. This calculation divides
+ * the day based on the opinion of the MGA that the day runs from dawn to dusk. Dawn for this calculation is 120 minutes
+ * zmaniyos before sunrise and dusk is 120 minutes zmaniyos after sunset. This day is split into 12 equal
+ * parts with each part being a shaah zmanis. This is identical to 1/6th of the day from {@link
+ * #getSunset() sunrise} to {@link #getSunset() sunset}. Since zmanim that use this method are
+ * extremely late or early and at a point when the sky is a long time past the 18° point where the darkest point is reached,
+ * zmanim that use this should only be used lechumra such as delaying the start of nighttime mitzvos.
*
* @return the long millisecond length of a shaah zmanis. 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
@@ -776,27 +631,27 @@ public long getShaahZmanis120MinutesZmanis() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
*
* @see #getShaahZmanis120MinutesZmanis()
- * @see #getAlos120()
- * @see #getTzais120()
+ * @see #getAlos120Minutes()
+ * @see #getTzais120Minutes()
* @see #getPlagHamincha26Degrees()
* @see #getPlagHamincha120Minutes()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha120MinutesZmanis() {
+ public Instant getPlagHamincha120MinutesZmanis() {
return getPlagHamincha(getAlos120Zmanis(), getTzais120Zmanis(), true);
}
/**
* This method should be used lechumra only and returns the time of plag hamincha according to the
* Magen Avraham with the day starting 120 minutes before sunrise and ending 120 minutes after sunset. This is
- * calculated as 10.75 hours after {@link #getAlos120() dawn 120 minutes}. The formula used is 10.75 {@link
- * #getShaahZmanis120Minutes()} after {@link #getAlos120()}. Since the zman based on an extremely early
+ * calculated as 10.75 hours after {@link #getAlos120Minutes() dawn 120 minutes}. The formula used is 10.75 {@link
+ * #getShaahZmanis120Minutes()} after {@link #getAlos120Minutes()}. Since the zman based on an extremely early
* alos and a very late tzais, it should only be used lechumra.
*
* @deprecated This method should be used lechumra only since it returns a very late time (often after
@@ -804,7 +659,7 @@ public Date getPlagHamincha120MinutesZmanis() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
@@ -813,44 +668,41 @@ public Date getPlagHamincha120MinutesZmanis() {
* @see #getPlagHamincha26Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha120Minutes() {
- return getPlagHamincha(getAlos120(), getTzais120(), true);
+ public Instant getPlagHamincha120Minutes() {
+ return getPlagHamincha(getAlos120Minutes(), getTzais120Minutes(), true);
}
/**
- * Method to return alos (dawn) calculated as 60 minutes before {@link #getSunrise() sunrise} or
+ * Method to return alos (dawn) calculated as 60 minutes before {@link #getSunset() sunrise} or
* {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting). This is the
* time to walk the distance of 4 mil at 15 minutes a mil. This seems to be the opinion of the
- * Chavas Yair in the Mekor Chaim, Orach Chaim Ch. 90,
- * though the Mekor Chaim in Ch. 58 and in the Chut Hashani Ch. 97 states that a person walks 3 and a 1/3 mil in an hour, or an 18-minute mil.
- * Also see the mil at 15 minutes a mil. This seems to be the opinion of the Chavas Yair in the Mekor Chaim, Orach Chaim Ch. 90, though the Mekor Chaim in Ch. 58 and in the Chut Hashani Ch. 97 states that a person walks 3 and a
+ * 1/3 mil in an hour, or an 18-minute mil. Also see the Divrei Malkiel Vol. 4, Ch. 20, page 34) who
- * mentions the 15 minute mil lechumra by baking matzos. Also see the Maharik Ch. 173 where the questioner quoting the
- * Ra'avan is of the opinion that the time to walk a
- * mil is 15 minutes (5 mil in a little over an hour). There are many who believe that there is a
- * ta'us sofer (scribe's error) in the Ra'avan, and it should 4 mil in a little over an hour, or an
- * 18-minute mil. Time based offset calculations are based on the opinion of the
- * Rishonim who stated that the time of the neshef
- * (time between dawn and sunrise) does not vary by the time of year or location but purely depends on the time it takes to
- * walk the distance of 4* mil. {@link #getTzaisGeonim9Point75Degrees()} is a related zman that is a
- * degree-based calculation based on 60 minutes.
- *
- * @return the Date representing the time. If the calculation can't be computed such as in the Arctic
+ * >Divrei Malkiel Vol. 4, Ch. 20, page 34) who mentions the
+ * 15 minute mil lechumra by baking matzos. Also see the Maharik Ch. 173 where the questioner quoting
+ * the Ra'avan is of the opinion that the time to walk a mil is
+ * 15 minutes (5 mil in a little over an hour). There are many who believe that there is a ta'us sofer (scribe's
+ * error) in the Ra'avan, and it should 4 mil in a little over an hour, or an 18-minute mil. Time based offset calculations are
+ * based on the opinion of the Rishonim who stated that the time
+ * of the neshef (time between dawn and sunrise) does not vary by the time of year or location but purely depends on
+ * the time it takes to walk the distance of 4* mil. {@link #getTzaisGeonim9Point75Degrees()} is a related zman that
+ * is a degree-based calculation based on 60 minutes.
+ *
+ * @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.
*
- * @see #getTzais60()
+ * @see #getTzais60Minutes()
* @see #getPlagHamincha60Minutes()
* @see #getShaahZmanis60Minutes()
*/
- public Date getAlos60() {
- return getTimeOffset(getElevationAdjustedSunrise(), -60 * MINUTE_MILLIS);
+ public Instant getAlos60Minutes() {
+ return getTimeOffset(getSunriseBasedOnElevationSetting(), -60 * MINUTE_MILLIS);
}
/**
@@ -858,24 +710,24 @@ public Date getAlos60() {
* sunrise. This is based on an 18-minute mil so the time for 4 mil is
* 72 minutes which is 1/10th of a day (12 * 60 = 720) based on the day being 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 actual calculation is {@link
- * #getElevationAdjustedSunrise()} - ({@link #getShaahZmanisGra()} * 1.2). This calculation is used in the calendars
+ * level sunrise} to {@link #getSeaLevelSunset() sea level sunset} or {@link #getSunset() sunrise} to {@link
+ * #getSunset() sunset} (depending on the {@link #isUseElevation()} setting). The actual calculation is {@link
+ * #getSunriseBasedOnElevationSetting()} - ({@link #getShaahZmanisGRA()} * 1.2). This calculation is used in the calendars
* published by the Hisachdus Harabanim D'Artzos Habris
* Ve'Canada.
*
- * @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.
- * @see #getShaahZmanisGra()
+ * @see #getShaahZmanisGRA()
*/
- public Date getAlos72Zmanis() {
+ public Instant getAlos72Zmanis() {
return getZmanisBasedOffset(-1.2);
}
/**
- * Method to return alos (dawn) calculated using 96 minutes before {@link #getSunrise() sunrise} or
+ * Method to return alos (dawn) calculated using 96 minutes before {@link #getSunset() sunrise} or
* {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting) that is based
* on the time to walk the distance of 4 mil at 24 minutes a mil.
@@ -884,78 +736,77 @@ public Date getAlos72Zmanis() {
* dawn and sunrise) does not vary by the time of year or location but purely 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 getAlos96() {
- return getTimeOffset(getElevationAdjustedSunrise(), -96 * MINUTE_MILLIS);
+ public Instant getAlos96Minutes() {
+ return getTimeOffset(getSunriseBasedOnElevationSetting(), -96 * MINUTE_MILLIS);
}
/**
* Method to return alos (dawn) calculated using 90 minutes zmaniyos or 1/8th of the day before
- * {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link
+ * {@link #getSunset() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link
* #isUseElevation()} setting). This is based on a 22.5-minute mil so the time for 4
- * mil is 90 minutes which is 1/8th of a day (12 * 60) / 8 = 90. 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 actual calculation used
- * is {@link #getElevationAdjustedSunrise()} - ({@link #getShaahZmanisGra()} * 1.5).
+ * "https://en.wikipedia.org/wiki/Biblical_and_Talmudic_units_of_measurement">mil so the time for 4 mil is 90 minutes
+ * which is 1/8th of a day (12 * 60) / 8 = 90. The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise}
+ * to {@link #getSeaLevelSunset() sea level sunset} or {@link #getSunset() sunrise} to {@link
+ * #getSunset() sunset} (depending on the {@link #isUseElevation()}. The actual calculation used is
+ * {@link #getSunriseBasedOnElevationSetting()} - ({@link #getShaahZmanisGRA()} * 1.5).
*
- * @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.
- * @see #getShaahZmanisGra()
+ * @see #getShaahZmanisGRA()
*/
- public Date getAlos90Zmanis() {
+ public Instant getAlos90Zmanis() {
return getZmanisBasedOffset(-1.5);
}
/**
* This method returns alos (dawn) calculated using 96 minutes zmaniyos or 1/7.5th of the day before
- * {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link
+ * {@link #getSunset() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link
* #isUseElevation()} setting). This is based on a 24-minute mil so the time for 4 mil is 96
- * minutes which is 1/7.5th of a day (12 * 60 / 7.5 = 96). 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 actual calculation used is {@link #getElevationAdjustedSunrise()}
- * - ({@link #getShaahZmanisGra()} * 1.6).
+ * "https://en.wikipedia.org/wiki/Biblical_and_Talmudic_units_of_measurement">mil so the time for 4 mil is 96 minutes
+ * which is 1/7.5th of a day (12 * 60 / 7.5 = 96). The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise}
+ * to {@link #getSeaLevelSunset() sea level sunset} or {@link #getSunset() sunrise} to {@link
+ * getSunset() sunset} (depending on the {@link #isUseElevation()}. The actual calculation used is {@link
+ * getSunriseBasedOnElevationSetting()} - ({@link #getShaahZmanisGRA()} * 1.6).
*
- * @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.
- * @see #getShaahZmanisGra()
+ * @see #getShaahZmanisGRA()
*/
- public Date getAlos96Zmanis() {
+ public Instant getAlos96Zmanis() {
return getZmanisBasedOffset(-1.6);
}
/**
- * Method to return alos (dawn) calculated using 90 minutes before {@link #getSunrise() sunrise} or
- * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting) based
- * on the time to walk the distance of 4 mil at 22.5 minutes a
- * mil. Time-based offset calculations for alos are based on the opinion of the Rishonim who stated that the time of the Neshef
- * (time between dawn and sunrise) does not vary by the time of year or location but purely depends on the time it
- * takes to walk the distance of 4 mil.
+ * Method to return alos (dawn) calculated using 90 minutes before {@link #getSunset() sunrise} or
+ * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting) based on the time
+ * to walk the distance of 4 mil at
+ * 22.5 minutes a mil. Time-based offset calculations for alos are based on the opinion of the Rishonim who stated that the time of the Neshef (time between
+ * dawn and sunrise) does not vary by the time of year or location but purely 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 getAlos90() {
- return getTimeOffset(getElevationAdjustedSunrise(), -90 * MINUTE_MILLIS);
+ public Instant getAlos90Minutes() {
+ return getTimeOffset(getSunriseBasedOnElevationSetting(), -90 * MINUTE_MILLIS);
}
/**
* This method should be used lechumra only and returns alos (dawn) calculated using 120 minutes
- * before {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link
- * #isUseElevation()} setting) based on the time to walk the distance of 5 mil (Ula) at 24 minutes a
* mil. Time based offset calculations for alos are based on the* opinion of the Rishonim who stated that the time of the neshef (time
@@ -969,56 +820,55 @@ public Date getAlos90() {
* too early according to most opinions. There is no current plan to remove this method from the API, and this
* deprecation is intended to alert developers of the danger of using it.
*
- * @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.
*
- * @see #getTzais120()
+ * @see #getTzais120Minutes()
* @see #getAlos26Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getAlos120() {
- return getTimeOffset(getElevationAdjustedSunrise(), -120 * MINUTE_MILLIS);
+ public Instant getAlos120Minutes() {
+ return getTimeOffset(getSunriseBasedOnElevationSetting(), -120 * MINUTE_MILLIS);
}
/**
* This method should be used lechumra only and method returns alos (dawn) calculated using
- * 120 minutes zmaniyos or 1/6th of the day before {@link #getSunrise() sunrise} or {@link
+ * 120 minutes zmaniyos or 1/6th of the day before {@link #getSunset() sunrise} or {@link
* #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting). This is based
* on a 24-minute mil so
- * the time for 5 mil is 120 minutes which is 1/6th of a day (12 * 60 / 6 = 120). 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
- * actual calculation used is {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 2). Since this time is
- * extremely early, it should only be used lechumra, such
- * as not eating after this time on a fast day, and not as the start time for mitzvos that can only be
- * performed during the day.
+ * the time for 5 mil is 120 minutes which is 1/6th of a day (12 * 60 / 6 = 120). The day is calculated from
+ * {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level sunset} or {@link
+ * #getSunset() sunrise} to {@link #getSunset() sunset} (depending on the {@link
+ * #isUseElevation()}. The actual calculation used is {@link #getSunset()} - ({@link #getShaahZmanisGRA()}
+ * * 2). Since this time is extremely early, it should only be used lechumra, such as not eating after this time
+ * on a fast day, and not as the start time for mitzvos that can only be performed during the day.
*
* @deprecated This method should be used lechumra only (such as stopping to eat at this time on a fast day),
* since it returns a very early time, and if used lekula can result in doing mitzvos hayom
* too early according to most opinions. There is no current plan to remove this method from the API, and this
* deprecation is intended to alert developers of the danger of using it.
*
- * @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.
- * @see #getAlos120()
+ * @see #getAlos120Minutes()
* @see #getAlos26Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getAlos120Zmanis() {
+ public Instant getAlos120Zmanis() {
return getZmanisBasedOffset(-2.0);
}
/**
* This method should be used lechumra only and returns alos (dawn) calculated when the sun is {@link
- * #ZENITH_26_DEGREES 26°} below the eastern geometric horizon before sunrise. This calculation is based on the same
- * calculation of {@link #getAlos120() 120 minutes} but uses a degree-based calculation instead of 120 exact minutes. This
- * calculation is based on the position of the sun 120 minutes before sunrise in Jerusalem around the equinox / equilux, which
- * calculates to 26° below {@link #GEOMETRIC_ZENITH geometric zenith}. Since this time is extremely early, it should
+ * calculates to 26° below {@link GEOMETRIC_ZENITH geometric zenith}. Since this time is extremely early, it should
* only be used lechumra only, such as not eating after this time on a fast day, and not as the start time for
* mitzvos that can only be performed during the day.
*
@@ -1027,36 +877,35 @@ public Date getAlos120Zmanis() {
* too early according to most opinions. There is no current plan to remove this method from the API, and this
* deprecation is intended to alert developers of the danger of using it.
*
- * @return the Date representing alos. If the calculation can't be computed such as northern
+ * @return the Instant representing alos. 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_26_DEGREES
- * @see #getAlos120()
- * @see #getTzais120()
+ * @see #getAlos120Minutes()
+ * @see #getTzais120Minutes()
* @see #getTzais26Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getAlos26Degrees() {
+ public Instant getAlos26Degrees() {
return getSunriseOffsetByDegrees(ZENITH_26_DEGREES);
}
/**
- * A method to return alos (dawn) calculated when the sun is {@link #ASTRONOMICAL_ZENITH 18°} below the
+ * A method to return alos (dawn) calculated when the sun is {@link ASTRONOMICAL_ZENITH 18°} below the
* eastern geometric horizon before sunrise.
*
- * @return the Date representing alos. If the calculation can't be computed such as northern
+ * @return the Instant representing alos. 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 #ASTRONOMICAL_ZENITH
+ * @see ASTRONOMICAL_ZENITH
*/
- public Date getAlos18Degrees() {
+ public Instant getAlos18Degrees() {
return getSunriseOffsetByDegrees(ASTRONOMICAL_ZENITH);
}
/**
- * A method to return alos (dawn) calculated when the sun is {@link #ZENITH_19_DEGREES 19°} below the
+ * A method to return alos (dawn) calculated when the sun is {@link ZENITH_19_DEGREES 19°} below the
* eastern geometric horizon before sunrise. This is the Rambam's alos according to Rabbi Moshe Kosower's Maaglei Tzedek, page 88, Yom Valayla Shel Torah, Ch. 34, p. 222 and
* Rabbi Yaakov Shakow's Luach Ikvei Hayom.
*
- * @return the Date representing alos. If the calculation can't be computed such as northern
+ * @return the Instant representing alos. 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 #ASTRONOMICAL_ZENITH
*/
- public Date getAlos19Degrees() {
+ public Instant getAlos19Degrees() {
return getSunriseOffsetByDegrees(ZENITH_19_DEGREES);
}
/**
- * Method to return alos (dawn) calculated when the sun is {@link #ZENITH_19_POINT_8 19.8°} below the
+ * Method to return alos (dawn) calculated when the sun is {@link ZENITH_19_POINT_8 19.8°} below the
* eastern geometric horizon before sunrise. This calculation is based on the same calculation of
- * {@link #getAlos90() 90 minutes} but uses a degree-based calculation instead of 90 exact minutes. This calculation
- * is based on the position of the sun 90 minutes before sunrise in Jerusalem around the equinox / equilux, which
- * calculates to 19.8° below {@link #GEOMETRIC_ZENITH geometric zenith}.
+ * calculates to 19.8° below {@link GEOMETRIC_ZENITH geometric zenith}.
*
- * @return the Date representing alos. If the calculation can't be computed such as northern
+ * @return the Instant representing alos. 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_19_POINT_8
- * @see #getAlos90()
+ * @see #getAlos90Minutes()
+ * @see #getTzais19Point8Degrees()
*/
- public Date getAlos19Point8Degrees() {
+ public Instant getAlos19Point8Degrees() {
return getSunriseOffsetByDegrees(ZENITH_19_POINT_8);
}
-
- /**
- * Method to return alos (dawn) calculated when the sun is {@link #ZENITH_16_POINT_1 16.1°} below the
- * eastern geometric horizon before sunrise. This calculation is based on the same calculation of
- * {@link #getAlos72() 72 minutes} but uses a degree-based calculation instead of 72 exact minutes. This calculation
- * is based on the position of the sun 72 minutes before sunrise in Jerusalem around the equinox / equilux, which
- * calculates to 16.1° below {@link #GEOMETRIC_ZENITH geometric zenith}.
- *
- * @return the Date representing alos. 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_16_POINT_1
- * @see #getAlos72()
- */
- public Date getAlos16Point1Degrees() {
- return getSunriseOffsetByDegrees(ZENITH_16_POINT_1);
- }
/**
- * This method returns misheyakir based on the position of the sun {@link #ZENITH_12_POINT_85 12.85°}
- * below {@link #GEOMETRIC_ZENITH geometric zenith} (90°). This is based on the position of the sun slightly
- * later than 57 minutes before {@link #getSunrise() sunrise} in Jerusalem misheyakir based on the position of the sun {@link ZENITH_12_POINT_85 12.85°}
+ * below {@link GEOMETRIC_ZENITH geometric zenith} (90°). This is based on the position of the sun slightly
+ * later than 57 minutes before {@link #getSunset() sunrise} in Jerusalem around the equinox / equilux. This
* zman is mentioned for use bish'as hadchak in the Birur Halacha Tinyana and Date of misheyakir. If the calculation can't be computed such as northern and
+ * @return The Instant of misheyakir. 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_12_POINT_85
+ * @see ZENITH_12_POINT_85
*/
@Deprecated (forRemoval=false)
- public Date getMisheyakir12Point85Degrees() {
+ public Instant getMisheyakir12Point85Degrees() {
return getSunriseOffsetByDegrees(ZENITH_12_POINT_85);
}
/**
- * This method returns misheyakir based on the position of the sun when it is {@link #ZENITH_11_DEGREES
- * 11.5°} below {@link #GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is used for calculating
+ * This method returns misheyakir based on the position of the sun when it is {@link ZENITH_11_DEGREES
+ * 11.5°} below {@link GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is used for calculating
* misheyakir according to some opinions. This calculation is based on the position of the sun 52 minutes
- * before {@link #getSunrise() sunrise} in Jerusalem around the equinox / equilux,
- * which calculates to 11.5° below {@link #GEOMETRIC_ZENITH geometric zenith}.
+ * which calculates to 11.5° below {@link GEOMETRIC_ZENITH geometric zenith}.
* @todo recalculate.
*
- * @return the Date of misheyakir. If the calculation can't be computed such as northern and
+ * @return the Instant of misheyakir. 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_11_POINT_5
+ * @see ZENITH_11_POINT_5
*/
- public Date getMisheyakir11Point5Degrees() {
+ public Instant getMisheyakir11Point5Degrees() {
return getSunriseOffsetByDegrees(ZENITH_11_POINT_5);
}
/**
- * This method returns misheyakir based on the position of the sun when it is {@link #ZENITH_11_DEGREES
- * 11°} below {@link #GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is used for calculating
+ * This method returns misheyakir based on the position of the sun when it is {@link ZENITH_11_DEGREES
+ * 11°} below {@link GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is used for calculating
* misheyakir according to some opinions. This calculation is based on the position of the sun 48 minutes
- * before {@link #getSunrise() sunrise} in Jerusalem around the equinox / equilux,
- * which calculates to 11° below {@link #GEOMETRIC_ZENITH geometric zenith}.
+ * which calculates to 11° below {@link GEOMETRIC_ZENITH geometric zenith}.
*
* @return 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_11_DEGREES
+ * @see ZENITH_11_DEGREES
*/
- public Date getMisheyakir11Degrees() {
+ public Instant getMisheyakir11Degrees() {
return getSunriseOffsetByDegrees(ZENITH_11_DEGREES);
}
/**
- * This method returns misheyakir based on the position of the sun when it is {@link #ZENITH_10_POINT_2
- * 10.2°} below {@link #GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is used for calculating
+ * This method returns misheyakir based on the position of the sun when it is {@link ZENITH_10_POINT_2
+ * 10.2°} below {@link GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is used for calculating
* misheyakir according to some opinions. This calculation is based on the position of the sun 45 minutes
- * before {@link #getSunrise() sunrise} in Jerusalem around the equinox which calculates
- * to 10.2° below {@link #GEOMETRIC_ZENITH geometric zenith}.
+ * to 10.2° below {@link GEOMETRIC_ZENITH geometric zenith}.
*
- * @return the Date of misheyakir. If the calculation can't be computed such as
+ * @return the Instant of misheyakir. 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_10_POINT_2
+ * @see ZENITH_10_POINT_2
*/
- public Date getMisheyakir10Point2Degrees() {
+ public Instant getMisheyakir10Point2Degrees() {
return getSunriseOffsetByDegrees(ZENITH_10_POINT_2);
}
/**
- * This method returns misheyakir based on the position of the sun when it is {@link #ZENITH_7_POINT_65
- * 7.65°} below {@link #GEOMETRIC_ZENITH geometric zenith} (90°). The degrees are based on a 35/36 minute
+ * This method returns misheyakir based on the position of the sun when it is {@link ZENITH_7_POINT_65
+ * 7.65°} below {@link GEOMETRIC_ZENITH geometric zenith} (90°). The degrees are based on a 35/36 minute
* zman around the
* equinox / equilux, when the neshef (twilight) is the shortest. This time is based on Rabbi Moshe Feinstein who writes in zman depends on the level of light, Rabbi Yaakov Shakow
* presented this degree-based calculations to Rabbi Shmuel Kamenetsky who agreed to them.
*
- * @return the Date of misheyakir. If the calculation can't be computed such as
+ * @return the Instant of misheyakir. 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_7_POINT_65
+ * @see ZENITH_7_POINT_65
* @see #getMisheyakir9Point5Degrees()
*/
- public Date getMisheyakir7Point65Degrees() {
+ public Instant getMisheyakir7Point65Degrees() {
return getSunriseOffsetByDegrees(ZENITH_7_POINT_65);
}
/**
- * This method returns misheyakir based on the position of the sun when it is {@link #ZENITH_9_POINT_5
- * 9.5°} below {@link #GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is based on misheyakir based on the position of the sun when it is {@link ZENITH_9_POINT_5
+ * 9.5°} below {@link GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is based on Rabbi Dovid Kronglass's Calculation of 45 minutes in Baltimore
* as mentioned in Divrei Chachamim No. 24
* brought down by the Birur Halacha, Tinyana, Ch.
@@ -1260,113 +1089,89 @@ public Date getMisheyakir7Point65Degrees() {
* this zman depends on the level of light, Rabbi Yaakov Shakow presented these degree-based times to Rabbi Shmuel
* Kamenetsky who agreed to them.
*
- * @return the Date of misheyakir. If the calculation can't be computed such as
+ * @return the Instant of misheyakir. 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_9_POINT_5
+ * @see ZENITH_9_POINT_5
* @see #getMisheyakir7Point65Degrees()
*/
- public Date getMisheyakir9Point5Degrees() {
+ public Instant getMisheyakir9Point5Degrees() {
return getSunriseOffsetByDegrees(ZENITH_9_POINT_5);
}
/**
* 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 #getAlos19Point8Degrees() 19.8°} before {@link #getSunrise() sunrise}. This
+ * alos being {@link #getAlos19Point8Degrees() 19.8°} before {@link #getSunset() sunrise}. This
* time is 3 {@link #getShaahZmanis19Point8Degrees() shaos zmaniyos} (solar hours) after {@link
* #getAlos19Point8Degrees() dawn} based on the opinion of the MGA that the day is calculated from dawn to nightfall
* with both being 19.8° below sunrise or sunset. This returns the time of 3 *
* {@link #getShaahZmanis19Point8Degrees()} after {@link #getAlos19Point8Degrees() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getShaahZmanis19Point8Degrees()
* @see #getAlos19Point8Degrees()
*/
- public Date getSofZmanShmaMGA19Point8Degrees() {
+ public Instant getSofZmanShmaMGA19Point8Degrees() {
return getSofZmanShma(getAlos19Point8Degrees(), getTzais19Point8Degrees(), 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 #getAlos16Point1Degrees() 16.1°} before {@link #getSunrise() sunrise}. This time
- * is 3 {@link #getShaahZmanis16Point1Degrees() shaos zmaniyos} (solar hours) after
- * {@link #getAlos16Point1Degrees() dawn} based on the opinion of the MGA that the day is calculated from
- * dawn to nightfall with both being 16.1° below sunrise or sunset. This returns the time of
- * 3 * {@link #getShaahZmanis16Point1Degrees()} after {@link #getAlos16Point1Degrees() dawn}.
+ * 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
+ * #getAlos16Point1Degrees() 16.1°} before {@link #getSunset() sunrise}. This time is 3 {@link
+ * #getShaahZmanis16Point1Degrees() shaos zmaniyos} (solar hours) after {@link #getAlos16Point1Degrees() dawn} based on
+ * the opinion of the MGA that the day is calculated from dawn to nightfall with both being 16.1° below sunrise or sunset.
+ * This returns the time of 3 * {@link #getShaahZmanis16Point1Degrees()} after {@link #getAlos16Point1Degrees() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getShaahZmanis16Point1Degrees()
* @see #getAlos16Point1Degrees()
*/
- public Date getSofZmanShmaMGA16Point1Degrees() {
+ public Instant getSofZmanShmaMGA16Point1Degrees() {
return getSofZmanShma(getAlos16Point1Degrees(), getTzais16Point1Degrees(), 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 #getAlos18Degrees() 18°} before {@link #getSunrise() sunrise}. This time is 3
+ * on alos being {@link #getAlos18Degrees() 18°} before {@link #getSunset() sunrise}. This time is 3
* {@link #getShaahZmanis18Degrees() shaos zmaniyos} (solar hours) after {@link #getAlos18Degrees() dawn}
* based on the opinion of the MGA that the day is calculated from dawn to nightfall with both being 18°
* below sunrise or sunset. This returns the time of 3 * {@link #getShaahZmanis18Degrees()} after
* {@link #getAlos18Degrees() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getShaahZmanis18Degrees()
* @see #getAlos18Degrees()
*/
- public Date getSofZmanShmaMGA18Degrees() {
+ public Instant getSofZmanShmaMGA18Degrees() {
return getSofZmanShma(getAlos18Degrees(), getTzais18Degrees(), 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 #getAlos72() 72} minutes before {@link #getSunrise() sunrise}. This time is 3 {@link
- * #getShaahZmanis72Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos72() dawn} based on the opinion
- * of the MGA that the day is calculated from a {@link #getAlos72() dawn} of 72 minutes before sunrise to
- * {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns the time of 3 * {@link
- * #getShaahZmanis72Minutes()} after {@link #getAlos72() dawn}. This class returns an identical time to {@link
- * #getSofZmanShmaMGA()} and is repeated here for clarity.
- *
- * @return the Date 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 #isUseAstronomicalChatzosForOtherZmanim()
- * @see #getShaahZmanis72Minutes()
- * @see #getAlos72()
- * @see #getSofZmanShmaMGA()
- */
- public Date getSofZmanShmaMGA72Minutes() {
- return getSofZmanShmaMGA();
- }
-
/**
* 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 #getAlos72Zmanis() 72} minutes zmaniyos, or 1/10th of the day before
- * {@link #getSunrise() sunrise}. This time is 3 {@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}
+ * {@link #getSunset() sunrise}. This time is 3 {@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}
* (solar hours) after {@link #getAlos72Zmanis() dawn} based on the opinion of the MGA that the day is calculated
* from a {@link #getAlos72Zmanis() dawn} of 72 minutes zmaniyos, or 1/10th of the day before
* {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getTzais72Zmanis() nightfall} of 72 minutes
* zmaniyos after {@link #getSeaLevelSunset() sea level sunset}. This returns the time of 3 *
* {@link #getShaahZmanis72MinutesZmanis()} after {@link #getAlos72Zmanis() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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.
@@ -1374,42 +1179,42 @@ public Date getSofZmanShmaMGA72Minutes() {
* @see #getAlos72Zmanis()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getSofZmanShmaMGA72MinutesZmanis() {
+ public Instant getSofZmanShmaMGA72MinutesZmanis() {
return getSofZmanShma(getAlos72Zmanis(), getTzais72Zmanis(), 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 #getAlos90() 90} minutes before {@link #getSunrise() sunrise}. This time is 3
- * {@link #getShaahZmanis90Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos90() dawn} based on
- * the opinion of the MGA that the day is calculated from a {@link #getAlos90() dawn} of 90 minutes before sunrise to
- * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns the time of 3 *
- * {@link #getShaahZmanis90Minutes()} after {@link #getAlos90() dawn}.
+ * alos being {@link #getAlos90Minutes() 90} minutes before {@link #getSunset() sunrise}. This time is 3
+ * {@link #getShaahZmanis90Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos90Minutes() dawn} based on
+ * the opinion of the MGA that the day is calculated from a {@link #getAlos90Minutes() dawn} of 90 minutes before sunrise to
+ * {@link #getTzais90Minutes() nightfall} of 90 minutes after sunset. This returns the time of 3 *
+ * {@link #getShaahZmanis90Minutes()} after {@link #getAlos90Minutes() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 #getShaahZmanis90Minutes()
- * @see #getAlos90()
+ * @see #getAlos90Minutes()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getSofZmanShmaMGA90Minutes() {
- return getSofZmanShma(getAlos90(), getTzais90(), true);
+ public Instant getSofZmanShmaMGA90Minutes() {
+ return getSofZmanShma(getAlos90Minutes(), getTzais90Minutes(), 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 #getAlos90Zmanis() 90} minutes zmaniyos before {@link #getSunrise()
+ * on alos being {@link #getAlos90Zmanis() 90} minutes zmaniyos before {@link #getSunset()
* sunrise}. This time is 3 {@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos} (solar hours) after
* {@link #getAlos90Zmanis() dawn} based on the opinion of the MGA that the day is calculated from a {@link
* #getAlos90Zmanis() dawn} of 90 minutes zmaniyos before sunrise to {@link #getTzais90Zmanis() nightfall}
* of 90 minutes zmaniyos after sunset. This returns the time of 3 * {@link #getShaahZmanis90MinutesZmanis()}
* after {@link #getAlos90Zmanis() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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.
@@ -1417,42 +1222,42 @@ public Date getSofZmanShmaMGA90Minutes() {
* @see #getAlos90Zmanis()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getSofZmanShmaMGA90MinutesZmanis() {
+ public Instant getSofZmanShmaMGA90MinutesZmanis() {
return getSofZmanShma(getAlos90Zmanis(), getTzais90Zmanis(), 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 #getAlos96() 96} minutes before {@link #getSunrise() sunrise}. This time is 3
- * {@link #getShaahZmanis96Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos96() dawn} based on
- * the opinion of the MGA that the day is calculated from a {@link #getAlos96() dawn} of 96 minutes before
- * sunrise to {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns the time of 3 * {@link
- * #getShaahZmanis96Minutes()} after {@link #getAlos96() dawn}.
+ * 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
+ * #getAlos96Minutes() 96} minutes before {@link #getSunset() sunrise}. This time is 3 {@link
+ * #getShaahZmanis96Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos96Minutes() dawn} based on the opinion
+ * of the MGA that the day is calculated from a {@link #getAlos96Minutes() dawn} of 96 minutes before sunrise to {@link
+ * #getTzais96Minutes() nightfall} of 96 minutes after sunset. This returns the time of 3 * {@link #getShaahZmanis96Minutes()}
+ * after {@link #getAlos96Minutes() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 #getShaahZmanis96Minutes()
- * @see #getAlos96()
+ * @see #getAlos96Minutes()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getSofZmanShmaMGA96Minutes() {
- return getSofZmanShma(getAlos96(), getTzais96(), true);
+ public Instant getSofZmanShmaMGA96Minutes() {
+ return getSofZmanShma(getAlos96Minutes(), getTzais96Minutes(), 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 #getAlos90Zmanis() 96} minutes zmaniyos before {@link #getSunrise()
+ * on alos being {@link #getAlos90Zmanis() 96} minutes zmaniyos before {@link #getSunset()
* sunrise}. This time is 3 {@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos} (solar hours) after
* {@link #getAlos96Zmanis() dawn} based on the opinion of the MGA that the day is calculated from a {@link
* #getAlos96Zmanis() dawn} of 96 minutes zmaniyos before sunrise to {@link #getTzais90Zmanis() nightfall}
* of 96 minutes zmaniyos after sunset. This returns the time of 3 * {@link #getShaahZmanis96MinutesZmanis()}
* after {@link #getAlos96Zmanis() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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.
@@ -1460,13 +1265,13 @@ public Date getSofZmanShmaMGA96Minutes() {
* @see #getAlos96Zmanis()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getSofZmanShmaMGA96MinutesZmanis() {
+ public Instant getSofZmanShmaMGA96MinutesZmanis() {
return getSofZmanShma(getAlos96Zmanis(), getTzais96Zmanis(), true);
}
/**
* This method returns the latest zman krias shema (time to recite Shema in the morning) calculated
- * as 3 hours (regular clock hours and not shaos zmaniyos) before {@link ZmanimCalendar#getChatzos()}.
+ * as 3 hours (regular clock hours and not shaos zmaniyos) before {@link #getChatzosHayom()}.
* Generally known as part of the "Komarno" zmanim after Rav Yitzchak Eizik of
* Komarno, a proponent of this calculation, it actually predates him a lot. It is the opinion of the
@@ -1481,44 +1286,44 @@ public Date getSofZmanShmaMGA96MinutesZmanis() {
* See Yisrael Vehazmanim vol. 1 7:3, page 55 -
* 62.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 ZmanimCalendar#getChatzos()
+ * @see #getChatzosHayom()
* @see #getSofZmanTfila2HoursBeforeChatzos()
* @see #isUseAstronomicalChatzos()
*/
- public Date getSofZmanShma3HoursBeforeChatzos() {
- return getTimeOffset(getChatzos(), -180 * MINUTE_MILLIS);
+ public Instant getSofZmanShma3HoursBeforeChatzos() {
+ return getTimeOffset(getChatzosHayom(), -180 * MINUTE_MILLIS);
}
/**
* 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 #getAlos120() 120} minutes or 1/6th of the day before {@link #getSunrise() sunrise}.
- * This time is 3 {@link #getShaahZmanis120Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos120()
- * dawn} based on the opinion of the MGA that the day is calculated from a {@link #getAlos120() dawn} of 120 minutes
- * before sunrise to {@link #getTzais120() nightfall} of 120 minutes after sunset. This returns the time of 3
- * {@link #getShaahZmanis120Minutes()} after {@link #getAlos120() dawn}. This is an extremely early zman that
+ * on alos being {@link #getAlos120Minutes() 120} minutes or 1/6th of the day before {@link #getSunset()
+ * sunrise}. This time is 3 {@link #getShaahZmanis120Minutes() shaos zmaniyos} (solar hours) after {@link
+ * #getAlos120Minutes() dawn} based on the opinion of the MGA that the day is calculated from a {@link #getAlos120Minutes() dawn}
+ * of 120 minutes before sunrise to {@link #getTzais120Minutes() nightfall} of 120 minutes after sunset. This returns the time of
+ * 3 {@link #getShaahZmanis120Minutes()} after {@link #getAlos120Minutes() dawn}. This is an extremely early zman that
* is very much a chumra.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 #getShaahZmanis120Minutes()
- * @see #getAlos120()
+ * @see #getAlos120Minutes()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getSofZmanShmaMGA120Minutes() {
- return getSofZmanShma(getAlos120(), getTzais120(), true);
+ public Instant getSofZmanShmaMGA120Minutes() {
+ return getSofZmanShma(getAlos120Minutes(), getTzais120Minutes(), true);
}
/**
- * This method returns the latest zman krias shema (time to recite Shema in the morning) based
- * on the opinion that the day starts at {@link #getAlos16Point1Degrees() alos 16.1°} and ends at
- * {@link #getSeaLevelSunset() sea level sunset}. This is the opinion of the zman krias shema (time to recite Shema in the morning) based on the
+ * opinion that the day starts at {@link #getAlos16Point1Degrees() alos 16.1°} and ends at {@link
+ * #getSeaLevelSunset() sea level sunset}. This is the opinion of the \u05D7\u05D9\u05D3\u05D5\u05E9\u05D9
* \u05D5\u05DB\u05DC\u05DC\u05D5\u05EA \u05D4\u05E8\u05D6\u05F4\u05D4 and the \u05DE\u05E0\u05D5\u05E8\u05D4 \u05D4\u05D8\u05D4\u05D5\u05E8\u05D4 as
@@ -1530,15 +1335,15 @@ public Date getSofZmanShmaMGA120Minutes() {
* Note: Based on this calculation chatzos will not be at midday and {@link
* #isUseAstronomicalChatzosForOtherZmanim()} will be ignored.
*
- * @return the Date of the latest zman krias shema based on this day. If the calculation can't
+ * @return the Instant of the latest zman krias shema based on this day. 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 #getAlos16Point1Degrees()
* @see #getSeaLevelSunset()
*/
- public Date getSofZmanShmaAlos16Point1ToSunset() {
- return getSofZmanShma(getAlos16Point1Degrees(), getElevationAdjustedSunset(), false);
+ public Instant getSofZmanShmaAlos16Point1ToSunset() {
+ return getSofZmanShma(getAlos16Point1Degrees(), getSunsetBasedOnElevationSetting(), false);
}
/**
@@ -1552,7 +1357,7 @@ public Date getSofZmanShmaAlos16Point1ToSunset() {
* Note: Based on this calculation chatzos will not be at midday and {@link
* #isUseAstronomicalChatzosForOtherZmanim()} will be ignored.
*
- * @return the Date of the latest zman krias shema based on this calculation. If the
+ * @return the Instant of the latest zman krias shema based on this calculation. 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
@@ -1560,20 +1365,20 @@ public Date getSofZmanShmaAlos16Point1ToSunset() {
* @see #getAlos16Point1Degrees()
* @see #getTzaisGeonim7Point083Degrees()
*/
- public Date getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees() {
+ public Instant getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees() {
return getSofZmanShma(getAlos16Point1Degrees(), getTzaisGeonim7Point083Degrees(), false);
}
/**
* This method returns the latest zman tfila (time to recite the morning prayers) according to the opinion
* of the Magen Avraham (MGA) based on
- * alos being {@link #getAlos19Point8Degrees() 19.8°} before {@link #getSunrise() sunrise}. This time
+ * alos being {@link #getAlos19Point8Degrees() 19.8°} before {@link #getSunset() sunrise}. This time
* is 4 {@link #getShaahZmanis19Point8Degrees() shaos zmaniyos} (solar hours) after {@link
* #getAlos19Point8Degrees() dawn} based on the opinion of the MGA that the day is calculated from dawn to
* nightfall with both being 19.8° below sunrise or sunset. This returns the time of 4 * {@link
* #getShaahZmanis19Point8Degrees()} after {@link #getAlos19Point8Degrees() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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.
@@ -1582,20 +1387,20 @@ public Date getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees() {
* @see #getAlos19Point8Degrees()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getSofZmanTfilaMGA19Point8Degrees() {
+ public Instant getSofZmanTfilaMGA19Point8Degrees() {
return getSofZmanTfila(getAlos19Point8Degrees(), getTzais19Point8Degrees(), true);
}
/**
* This method returns the latest zman tfila (time to recite the morning prayers) according to the opinion
* of the Magen Avraham (MGA) based on
- * alos being {@link #getAlos16Point1Degrees() 16.1°} before {@link #getSunrise() sunrise}. This time
+ * alos being {@link #getAlos16Point1Degrees() 16.1°} before {@link #getSunset() sunrise}. This time
* is 4 {@link #getShaahZmanis16Point1Degrees() shaos zmaniyos} (solar hours) after {@link
* #getAlos16Point1Degrees() dawn} based on the opinion of the MGA that the day is calculated from dawn to
* nightfall with both being 16.1° below sunrise or sunset. This returns the time of 4 * {@link
* #getShaahZmanis16Point1Degrees()} after {@link #getAlos16Point1Degrees() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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.
@@ -1603,20 +1408,20 @@ public Date getSofZmanTfilaMGA19Point8Degrees() {
* @see #getShaahZmanis16Point1Degrees()
* @see #getAlos16Point1Degrees()
*/
- public Date getSofZmanTfilaMGA16Point1Degrees() {
+ public Instant getSofZmanTfilaMGA16Point1Degrees() {
return getSofZmanTfila(getAlos16Point1Degrees(), getTzais16Point1Degrees(), true);
}
/**
* This method returns the latest zman tfila (time to recite the morning prayers) according to the opinion
* of the Magen Avraham (MGA) based on
- * alos being {@link #getAlos18Degrees() 18°} before {@link #getSunrise() sunrise}. This time is 4
+ * alos being {@link #getAlos18Degrees() 18°} before {@link #getSunset() sunrise}. This time is 4
* {@link #getShaahZmanis18Degrees() shaos zmaniyos} (solar hours) after {@link #getAlos18Degrees() dawn}
* based on the opinion of the MGA that the day is calculated from dawn to nightfall with both being 18°
* below sunrise or sunset. This returns the time of 4 * {@link #getShaahZmanis18Degrees()} after
* {@link #getAlos18Degrees() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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.
@@ -1624,248 +1429,229 @@ public Date getSofZmanTfilaMGA16Point1Degrees() {
* @see #getShaahZmanis18Degrees()
* @see #getAlos18Degrees()
*/
- public Date getSofZmanTfilaMGA18Degrees() {
+ public Instant getSofZmanTfilaMGA18Degrees() {
return getSofZmanTfila(getAlos18Degrees(), getTzais18Degrees(), true);
}
- /**
- * This method returns the latest zman tfila (time to recite the morning prayers) according to the opinion
- * of the Magen Avraham (MGA) based on
- * alos being {@link #getAlos72() 72} minutes before {@link #getSunrise() sunrise}. This time is 4
- * {@link #getShaahZmanis72Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos72() dawn} based on
- * the opinion of the MGA that the day is calculated from a {@link #getAlos72() dawn} of 72 minutes before
- * sunrise to {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns the time of 4 *
- * {@link #getShaahZmanis72Minutes()} after {@link #getAlos72() dawn}. This class returns an identical time to
- * {@link #getSofZmanTfilaMGA()} and is repeated here for clarity.
- *
- * @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 #getShaahZmanis72Minutes()
- * @see #getAlos72()
- * @see #getSofZmanShmaMGA()
- */
- public Date getSofZmanTfilaMGA72Minutes() {
- return getSofZmanTfilaMGA();
- }
-
/**
* This method returns the latest zman tfila (time to the morning prayers) according to the opinion of the
* Magen Avraham (MGA) based on alos
- * being {@link #getAlos72Zmanis() 72} minutes zmaniyos before {@link #getSunrise() sunrise}. This time is 4
+ * being {@link #getAlos72Zmanis() 72} minutes zmaniyos before {@link #getSunset() sunrise}. This time is 4
* {@link #getShaahZmanis72MinutesZmanis() shaos zmaniyos} (solar hours) after {@link #getAlos72Zmanis() dawn}
* based on the opinion of the MGA that the day is calculated from a {@link #getAlos72Zmanis() dawn} of 72
* minutes zmaniyos before sunrise to {@link #getTzais72Zmanis() nightfall} of 72 minutes zmaniyos
* after sunset. This returns the time of 4 * {@link #getShaahZmanis72MinutesZmanis()} after {@link #getAlos72Zmanis() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 #getShaahZmanis72MinutesZmanis()
* @see #getAlos72Zmanis()
*/
- public Date getSofZmanTfilaMGA72MinutesZmanis() {
+ public Instant getSofZmanTfilaMGA72MinutesZmanis() {
return getSofZmanTfila(getAlos72Zmanis(), getTzais72Zmanis(), true);
}
/**
* This method returns the latest zman tfila (time to recite the morning prayers) according to the opinion
* of the Magen Avraham (MGA) based on
- * alos being {@link #getAlos90() 90} minutes before {@link #getSunrise() sunrise}. This time is 4
- * {@link #getShaahZmanis90Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos90() dawn} based on
- * the opinion of the MGA that the day is calculated from a {@link #getAlos90() dawn} of 90 minutes before sunrise to
- * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns the time of 4 *
- * {@link #getShaahZmanis90Minutes()} after {@link #getAlos90() dawn}.
+ * alos being {@link #getAlos90Minutes() 90} minutes before {@link #getSunset() sunrise}. This time is 4
+ * {@link #getShaahZmanis90Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos90Minutes() dawn} based on
+ * the opinion of the MGA that the day is calculated from a {@link #getAlos90Minutes() dawn} of 90 minutes before sunrise to
+ * {@link #getTzais90Minutes() nightfall} of 90 minutes after sunset. This returns the time of 4 *
+ * {@link #getShaahZmanis90Minutes()} after {@link #getAlos90Minutes() dawn}.
*
- * @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 #getShaahZmanis90Minutes()
- * @see #getAlos90()
+ * @see #getAlos90Minutes()
*/
- public Date getSofZmanTfilaMGA90Minutes() {
- return getSofZmanTfila(getAlos90(), getTzais90(), true);
+ public Instant getSofZmanTfilaMGA90Minutes() {
+ return getSofZmanTfila(getAlos90Minutes(), getTzais90Minutes(), true);
}
/**
* This method returns the latest zman tfila (time to the morning prayers) according to the opinion of the
* Magen Avraham (MGA) based on alos
- * being {@link #getAlos90Zmanis() 90} minutes zmaniyos before {@link #getSunrise() sunrise}. This time is
+ * being {@link #getAlos90Zmanis() 90} minutes zmaniyos before {@link #getSunset() sunrise}. This time is
* 4 {@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos} (solar hours) after {@link #getAlos90Zmanis()
* dawn} based on the opinion of the MGA that the day is calculated from a {@link #getAlos90Zmanis() dawn}
* of 90 minutes zmaniyos before sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
* zmaniyos after sunset. This returns the time of 4 * {@link #getShaahZmanis90MinutesZmanis()} after
* {@link #getAlos90Zmanis() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 #getShaahZmanis90MinutesZmanis()
* @see #getAlos90Zmanis()
*/
- public Date getSofZmanTfilaMGA90MinutesZmanis() {
+ public Instant getSofZmanTfilaMGA90MinutesZmanis() {
return getSofZmanTfila(getAlos90Zmanis(), getTzais90Zmanis(), true);
}
/**
* This method returns the latest zman tfila (time to recite the morning prayers) according to the opinion
* of the Magen Avraham (MGA) based on
- * alos being {@link #getAlos96() 96} minutes before {@link #getSunrise() sunrise}. This time is 4
- * {@link #getShaahZmanis96Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos96() dawn} based on
- * the opinion of the MGA that the day is calculated from a {@link #getAlos96() dawn} of 96 minutes before
- * sunrise to {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns the time of 4 *
- * {@link #getShaahZmanis96Minutes()} after {@link #getAlos96() dawn}.
+ * alos being {@link #getAlos96Minutes() 96} minutes before {@link #getSunset() sunrise}. This time is 4
+ * {@link #getShaahZmanis96Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos96Minutes() dawn} based on
+ * the opinion of the MGA that the day is calculated from a {@link #getAlos96Minutes() dawn} of 96 minutes before
+ * sunrise to {@link #getTzais96Minutes() nightfall} of 96 minutes after sunset. This returns the time of 4 *
+ * {@link #getShaahZmanis96Minutes()} after {@link #getAlos96Minutes() dawn}.
*
- * @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 #getShaahZmanis96Minutes()
- * @see #getAlos96()
+ * @see #getAlos96Minutes()
*/
- public Date getSofZmanTfilaMGA96Minutes() {
- return getSofZmanTfila(getAlos96(), getTzais96(), true);
+ public Instant getSofZmanTfilaMGA96Minutes() {
+ return getSofZmanTfila(getAlos96Minutes(), getTzais96Minutes(), true);
}
/**
* This method returns the latest zman tfila (time to the morning prayers) according to the opinion of the
* Magen Avraham (MGA) based on alos
- * being {@link #getAlos96Zmanis() 96} minutes zmaniyos before {@link #getSunrise() sunrise}. This time is
+ * being {@link #getAlos96Zmanis() 96} minutes zmaniyos before {@link #getSunset() sunrise}. This time is
* 4 {@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos} (solar hours) after {@link #getAlos96Zmanis()
* dawn} based on the opinion of the MGA that the day is calculated from a {@link #getAlos96Zmanis() dawn}
* of 96 minutes zmaniyos before sunrise to {@link #getTzais96Zmanis() nightfall} of 96 minutes
* zmaniyos after sunset. This returns the time of 4 * {@link #getShaahZmanis96MinutesZmanis()} after
* {@link #getAlos96Zmanis() dawn}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 #getShaahZmanis90MinutesZmanis()
* @see #getAlos90Zmanis()
*/
- public Date getSofZmanTfilaMGA96MinutesZmanis() {
+ public Instant getSofZmanTfilaMGA96MinutesZmanis() {
return getSofZmanTfila(getAlos96Zmanis(), getTzais96Zmanis(), true);
}
/**
* This method returns the latest zman tfila (time to recite the morning prayers) according to the opinion
* of the Magen Avraham (MGA) based on
- * alos being {@link #getAlos120() 120} minutes before {@link #getSunrise() sunrise} . This time is 4
- * {@link #getShaahZmanis120Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos120() dawn}
- * based on the opinion of the MGA that the day is calculated from a {@link #getAlos120() dawn} of 120
- * minutes before sunrise to {@link #getTzais120() nightfall} of 120 minutes after sunset. This returns the time of
- * 4 * {@link #getShaahZmanis120Minutes()} after {@link #getAlos120() dawn}. This is an extremely early zman
+ * alos being {@link #getAlos120Minutes() 120} minutes before {@link #getSunset() sunrise} . This time is 4
+ * {@link #getShaahZmanis120Minutes() shaos zmaniyos} (solar hours) after {@link #getAlos120Minutes() dawn}
+ * based on the opinion of the MGA that the day is calculated from a {@link #getAlos120Minutes() dawn} of 120
+ * minutes before sunrise to {@link #getTzais120Minutes() nightfall} of 120 minutes after sunset. This returns the time of
+ * 4 * {@link #getShaahZmanis120Minutes()} after {@link #getAlos120Minutes() dawn}. This is an extremely early zman
* that is very much a chumra.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 #getShaahZmanis120Minutes()
- * @see #getAlos120()
+ * @see #getAlos120Minutes()
*/
- public Date getSofZmanTfilaMGA120Minutes() {
- return getSofZmanTfila(getAlos120(), getTzais120(), true);
+ public Instant getSofZmanTfilaMGA120Minutes() {
+ return getSofZmanTfila(getAlos120Minutes(), getTzais120Minutes(), true);
}
/**
* This method returns the latest zman tfila (time to recite the morning prayers) calculated as 2 hours
- * before {@link ZmanimCalendar#getChatzos()}. This is based on the opinions that calculate
+ * before {@link #getChatzosHayom()}. This is based on the opinions that calculate
* sof zman krias shema as {@link #getSofZmanShma3HoursBeforeChatzos()}. This returns the time of 2 hours
- * before {@link ZmanimCalendar#getChatzos()}.
+ * before {@link #getChatzosHayom()}.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @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 ZmanimCalendar#getChatzos()
+ * @see #getChatzosHayom()
* @see #getSofZmanShma3HoursBeforeChatzos()
*/
- public Date getSofZmanTfila2HoursBeforeChatzos() {
- return getTimeOffset(getChatzos(), -120 * MINUTE_MILLIS);
+ public Instant getSofZmanTfila2HoursBeforeChatzos() {
+ return getTimeOffset(getChatzosHayom(), -120 * MINUTE_MILLIS);
}
/**
- * This method returns mincha gedola calculated as 30 minutes after {@link #getChatzos() chatzos}
- * and not 1/2 of a {@link #getShaahZmanisGra() shaah zmanis} after {@link #getChatzos() chatzos} as
+ * This method returns mincha gedola calculated as 30 minutes after {@link #getChatzosHayom() chatzos}
+ * and not 1/2 of a {@link #getShaahZmanisGRA() shaah zmanis} after {@link #getChatzosHayom() chatzos} as
* calculated by {@link #getMinchaGedola}. Some use this time to delay the start of mincha in the winter when
- * 1/2 of a {@link #getShaahZmanisGra() shaah zmanis} is less than 30 minutes. See
- * {@link #getMinchaGedolaGreaterThan30()} for a convenience method that returns the later of the 2 calculations. One
- * should not use this time to start mincha before the standard {@link #getMinchaGedola() mincha gedola}.
+ * 1/2 of a {@link #getShaahZmanisGRA() shaah zmanis} is less than 30 minutes. See
+ * {@link #getMinchaGedolaGreaterThan30(Instant)} for a convenience method that returns the later of the 2 calculations. One
+ * should not use this time to start mincha before the standard {@link #getMinchaGedolaGRA() mincha gedola}.
* See Shulchan Aruch Orach Chayim 234:1 and
* the Shaar Hatziyon seif katan ches. Since this calculation is a fixed 30 minutes of regular clock time after
* chatzos, even if {@link #isUseAstronomicalChatzosForOtherZmanim()} is false, this mincha
* gedola time will be affected by {@link #isUseAstronomicalChatzos()} and not by
* {@link #isUseAstronomicalChatzosForOtherZmanim()}.
*
- * @return the Date of 30 minutes after chatzos. If the calculation can't be computed such as
+ * @return the Instant of 30 minutes after 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.
- * @see #getMinchaGedola()
- * @see #getMinchaGedolaGreaterThan30()
- * @see #getChatzos()
+ * @todo Consider adjusting this to calculate the time as half an hour after {@link #getChatzosHayom()} that uses
+ * {@link #isUseAstronomicalChatzos()} to determine the type of chatzos to utilize. that support it,
+ * based on {@link #isUseAstronomicalChatzos()}.
+ * @see #getMinchaGedolaGRA()
+ * @see #getMinchaGedolaGreaterThan30(Instant)
+ * @see #getChatzosHayom()
* @see #isUseAstronomicalChatzos()
* @see #isUseAstronomicalChatzosForOtherZmanim()
*/
- public Date getMinchaGedola30Minutes() {
- return getTimeOffset(getChatzos(), MINUTE_MILLIS * 30);
+ public Instant getMinchaGedola30Minutes() {
+ return getTimeOffset(getChatzosHayom(), MINUTE_MILLIS * 30);
}
/**
* This method returns the time of mincha gedola according to the Magen Avraham with the day starting 72
* minutes before sunrise and ending 72 minutes after sunset. This is the earliest time to pray mincha. For
- * more information on this see the documentation on {@link #getMinchaGedola() mincha gedola}. This is
+ * more information on this see the documentation on {@link #getMinchaGedolaGRA() mincha gedola}. This is
* calculated as 6.5 {@link #getTemporalHour() solar hours} after alos. The calculation used is 6.5 *
- * {@link #getShaahZmanis72Minutes()} after {@link #getAlos72() alos}. If {@link
+ * {@link #getShaahZmanis72Minutes()} after {@link #getAlos72Minutes() alos}. If {@link
* #isUseAstronomicalChatzosForOtherZmanim()} is set to true, the calculation will be based on 0.5
- * {@link #getHalfDayBasedShaahZmanis(Date, Date) half-day based sha'ah zmanis} between {@link #getChatzos()}
- * and {@link #getTzais72()} after {@link #getChatzos()}.
- *
- * @see #getAlos72()
- * @see #getMinchaGedola()
- * @see #getMinchaKetana()
- * @see ZmanimCalendar#getMinchaGedola()
- * @see #getChatzos()
+ * {@link #getHalfDayBasedShaahZmanis(Instant, Instant) half-day based sha'ah zmanis} between
+ * {@link #getChatzosHayom()} and {@link #getTzais72Minutes()} after {@link #getChatzosHayom()}.
+ *
+ * @see #getAlos72Minutes()
+ * @see #getMinchaGedolaGRA()
+ * @see #getMinchaKetanaGRA()
+ * @see #getMinchaGedolaGRA()
+ * @see #getChatzosHayom()
* @see #isUseAstronomicalChatzosForOtherZmanim()
- * @return the Date of the time of mincha gedola. If the calculation can't be computed such as
+ * @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 getMinchaGedola72Minutes() {
+ public Instant getMinchaGedola72Minutes() {
if (isUseAstronomicalChatzosForOtherZmanim()) {
- return getHalfDayBasedZman(getChatzos(), getTzais72(), 0.5);
+ return getHalfDayBasedZman(getChatzosHayom(), getTzais72Minutes(), 0.5);
} else {
- return getMinchaGedola(getAlos72(), getTzais72(), true);
+ return getMinchaGedola(getAlos72Minutes(), getTzais72Minutes(), true);
}
}
/**
* This method returns the time of mincha gedola according to the Magen Avraham with the day starting and
* ending 16.1° below the horizon. This is the earliest time to pray mincha. For more information on
- * this see the documentation on {@link #getMinchaGedola() mincha gedola}. This is calculated as 6.5
+ * this see the documentation on {@link #getMinchaGedolaGRA() mincha gedola}. This is calculated as 6.5
* {@link #getTemporalHour() solar hours} after alos. The calculation used is 6.5 *
* {@link #getShaahZmanis16Point1Degrees()} after {@link #getAlos16Point1Degrees() alos}. If {@link
* #isUseAstronomicalChatzosForOtherZmanim()} is set to true, the calculation will be based on 0.5
- * {@link #getHalfDayBasedShaahZmanis(Date, Date) half-day based sha'ah zmanis} between {@link #getChatzos()}
- * and {@link #getAlos16Point1Degrees()} after {@link #getChatzos()}.
+ * {@link #getHalfDayBasedShaahZmanis(Instant, Instant) half-day based sha'ah zmanis} between {@link #getChatzosHayom()}
+ * and {@link #getAlos16Point1Degrees()} after {@link #getChatzosHayom()}.
* @see #getShaahZmanis16Point1Degrees()
- * @see #getMinchaGedola()
- * @see #getMinchaKetana()
- * @return the Date of the time of mincha gedola. If the calculation can't be computed such as
+ * @see #getMinchaGedolaGRA()
+ * @see #getMinchaKetanaGRA()
+ * @return the Instant of the time of mincha gedola. 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 getMinchaGedola16Point1Degrees() {
+ public Instant getMinchaGedola16Point1Degrees() {
if (isUseAstronomicalChatzosForOtherZmanim()) {
- return getHalfDayBasedZman(getChatzos(), getTzais16Point1Degrees(), 0.5);
+ return getHalfDayBasedZman(getChatzosHayom(), getTzais16Point1Degrees(), 0.5);
} else {
return getMinchaGedola(getAlos16Point1Degrees(), getTzais16Point1Degrees(), true);
}
@@ -1879,12 +1665,12 @@ public Date getMinchaGedola16Point1Degrees() {
* zmanis after chatzos with shaos zmaniyos calculated based on a day starting 72 minutes before sunrise
* {@link #getAlos16Point1Degrees() alos 16.1°} and ending 13.5 minutes after sunset {@link
* #getTzaisGeonim3Point7Degrees() tzais 3.7°}. Mincha gedola is the earliest time to pray mincha.
- * The later of this time or 30 clock minutes after chatzos is returned. See {@link #getMinchaGedolaGreaterThan30()}
- * (though that calculation is based on mincha gedola GRA).
- * For more information about mincha gedola see the documentation on {@link #getMinchaGedola() mincha gedola}.
+ * The later of this time or 30 clock minutes after chatzos is returned. See {@link
+ * #getMinchaGedolaGreaterThan30(Instant)} for a way to claculate the later of 30 minutes or this mincha gedola.
+ * For more information about mincha gedola see the documentation on {@link #getMinchaGedolaGRA() mincha gedola}.
* Since calculation of this zman involves chatzos that is offset from the center of the astronomical day,
* {@link #isUseAstronomicalChatzosForOtherZmanim()} is N/A here.
- * @return the Date of the mincha gedola. If the calculation can't be computed such as northern and
+ * @return the Instant of the mincha gedola. 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.
@@ -1892,61 +1678,87 @@ public Date getMinchaGedola16Point1Degrees() {
* @see #getAlos16Point1Degrees()
* @see #getTzaisGeonim3Point7Degrees()
* @see #getShaahZmanisAlos16Point1ToTzais3Point7()
- * @see #getMinchaGedolaGreaterThan30()
+ * @see #getMinchaGedolaGreaterThan30(Instant)
*/
- public Date getMinchaGedolaAhavatShalom() {
- if (getChatzos() == null || getMinchaGedola30Minutes() == null || getShaahZmanisAlos16Point1ToTzais3Point7() == Long.MIN_VALUE) {
+ public Instant getMinchaGedolaAhavatShalom() {
+ if (getChatzosHayom() == null || getMinchaGedola30Minutes() == null || getShaahZmanisAlos16Point1ToTzais3Point7() == Long.MIN_VALUE) {
return null;
} else {
- return getMinchaGedola30Minutes().compareTo(getTimeOffset(getChatzos(), getShaahZmanisAlos16Point1ToTzais3Point7() / 2)) > 0 ?
- getMinchaGedola30Minutes() : getTimeOffset(getChatzos(), getShaahZmanisAlos16Point1ToTzais3Point7() / 2);
+ return getMinchaGedola30Minutes().compareTo(getTimeOffset(getChatzosHayom(), getShaahZmanisAlos16Point1ToTzais3Point7() / 2)) > 0 ?
+ getMinchaGedola30Minutes() : getTimeOffset(getChatzosHayom(), getShaahZmanisAlos16Point1ToTzais3Point7() / 2);
}
}
/**
- * FIXME check for synchronous
- * This is a convenience method that returns the later of {@link #getMinchaGedola()} and
- * {@link #getMinchaGedola30Minutes()}. In the winter when 1/2 of a {@link #getShaahZmanisGra() shaah zmanis} is
- * less than 30 minutes {@link #getMinchaGedola30Minutes()} will be returned, otherwise {@link #getMinchaGedola()}
- * will be returned. Since this calculation can be an offset of chatzos (if 30 clock minutes > 1/2 of a shaah
- * zmanis), even if {@link #isUseAstronomicalChatzosForOtherZmanim()} is false, this mincha time
- * may be affected by {@link #isUseAstronomicalChatzos()}.
+ * This is a convenience method that returns the later of the minchaGedola passed in and {@link
+ * #getMinchaGedola30Minutes()}. In the winter when 1/2 of a {@link #getShaahZmanisGRA() shaah zmanis} is less
+ * than 30 minutes {@link #getMinchaGedola30Minutes()} will be returned, otherwise the minchaGedola passed in will be
+ * returned. Since this calculation can be an offset of chatzos (if 30 clock minutes > 1/2 of a shaah
+ * zmanis), even if {@link #isUseAstronomicalChatzosForOtherZmanim()} is false, this mincha
+ * time may be affected by {@link #isUseAstronomicalChatzos()}.
*
- * @return the Date of the later of {@link #getMinchaGedola()} and {@link #getMinchaGedola30Minutes()}.
+ * @param minchaGedola
+ * the mincha gedola to be compared to {@link #getMinchaGedola30Minutes()}.
+ * @return the Instant of the later of {@link #getMinchaGedolaGRA()} and {@link #getMinchaGedola30Minutes()}.
* 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()
+ * @see #getMinchaGedolaGRA()
* @see #getMinchaGedola30Minutes()
* @see #isUseAstronomicalChatzos()
*
*/
- public Date getMinchaGedolaGreaterThan30() {
- if (getMinchaGedola30Minutes() == null || getMinchaGedola() == null) {
+ public Instant getMinchaGedolaGreaterThan30(Instant minchaGedola) {
+ if (getMinchaGedola30Minutes() == null || minchaGedola == null) {
return null;
} else {
- return getMinchaGedola30Minutes().compareTo(getMinchaGedola()) > 0 ? getMinchaGedola30Minutes()
- : getMinchaGedola();
+ return getMinchaGedola30Minutes().compareTo(minchaGedola) > 0 ? getMinchaGedola30Minutes()
+ : minchaGedola;
}
}
+
+ /**
+ * This is a convenience method that returns the later of {@link #getMinchaGedolaGRA()} and
+ * {@link #getMinchaGedola30Minutes()}. In the winter when 1/2 of a {@link #getShaahZmanisGRA() shaah zmanis} is
+ * less than 30 minutes {@link #getMinchaGedola30Minutes()} will be returned, otherwise {@link #getMinchaGedolaGRA()}
+ * will be returned. Since this calculation can be an offset of chatzos (if 30 clock minutes > 1/2 of a shaah
+ * zmanis), even if {@link #isUseAstronomicalChatzosForOtherZmanim()} is false, this mincha time
+ * may be affected by {@link #isUseAstronomicalChatzos()}.
+ *
+ * @return the Date of the later of {@link #getMinchaGedolaGRA()} and {@link #getMinchaGedola30Minutes()}.
+ * 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.
+ * @todo Consider adjusting this to calculate the time as 30 minutes after {@link #getChatzosHayom()} that uses {@link
+ * isUseAstronomicalChatzos()} to determine the type of chatzos to utilize (if the {@link
+ * com.kosherjava.zmanim.util.AstronomicalCalculator calculator} support astronomical chatzos),
+ * based on the {@link #isUseAstronomicalChatzos()} setting.
+ * @see #getMinchaGedolaGRA()
+ * @see #getMinchaGedola30Minutes()
+ * @see #getMinchaGedolaGreaterThan30(Instant)
+ * @see #isUseAstronomicalChatzos()
+ */
+ public Instant getMinchaGedolaGRAGreaterThan30() {
+ return getMinchaGedolaGreaterThan30(getMinchaGedolaGRA());
+ }
/**
* This method returns the time of mincha ketana according to the Magen Avraham with the day starting and
* ending 16.1° below the horizon. This is the preferred earliest time to pray mincha according to the
* opinion of the Rambam and others. For more information on
- * this see the documentation on {@link #getMinchaGedola() mincha gedola}. This is calculated as 9.5
+ * this see the documentation on {@link #getMinchaGedolaGRA() mincha gedola}. This is calculated as 9.5
* {@link #getTemporalHour() solar hours} after alos. The calculation used is 9.5 *
* {@link #getShaahZmanis16Point1Degrees()} after {@link #getAlos16Point1Degrees() alos}.
*
* @see #getShaahZmanis16Point1Degrees()
- * @see #getMinchaGedola()
- * @see #getMinchaKetana()
- * @return the Date of the time of mincha ketana. If the calculation can't be computed such
+ * @see #getMinchaGedolaGRA()
+ * @see #getMinchaKetanaGRA()
+ * @return the Instant of the time of mincha ketana. 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 getMinchaKetana16Point1Degrees() {
+ public Instant getMinchaKetana16Point1Degrees() {
return getMinchaKetana(getAlos16Point1Degrees(), getTzais16Point1Degrees(), true);
}
@@ -1958,9 +1770,9 @@ public Date getMinchaKetana16Point1Degrees() {
* calculated based on a day starting at {@link #getAlos16Point1Degrees() alos 16.1°} and ending at
* tzais 3.8°. Mincha ketana is the preferred earliest time to pray mincha according to
* the opinion of the Rambam and others. For more information
- * on this see the documentation on {@link #getMinchaKetana() mincha ketana}.
+ * on this see the documentation on {@link #getMinchaKetanaGRA() mincha ketana}.
*
- * @return the Date of the time of mincha ketana. If the calculation can't be computed such as
+ * @return the Instant of the time of mincha ketana. 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.
@@ -1969,7 +1781,7 @@ public Date getMinchaKetana16Point1Degrees() {
* @see #getMinchaGedolaAhavatShalom()
* @see #getPlagAhavatShalom()
*/
- public Date getMinchaKetanaAhavatShalom() {
+ public Instant getMinchaKetanaAhavatShalom() {
return getTimeOffset(getTzaisGeonim3Point8Degrees(), -getShaahZmanisAlos16Point1ToTzais3Point8() * 2.5);
}
@@ -1977,45 +1789,45 @@ public Date getMinchaKetanaAhavatShalom() {
* This method returns the time of mincha ketana according to the Magen Avraham with the day
* starting 72 minutes before sunrise and ending 72 minutes after sunset. This is the preferred earliest time to pray
* mincha according to the opinion of the Rambam
- * and others. For more information on this see the documentation on {@link #getMinchaGedola() mincha gedola}.
+ * and others. For more information on this see the documentation on {@link #getMinchaGedolaGRA() mincha gedola}.
* This is calculated as 9.5 {@link #getShaahZmanis72Minutes()} after alos. The calculation used is 9.5 *
- * {@link #getShaahZmanis72Minutes()} after {@link #getAlos72() alos}.
+ * {@link #getShaahZmanis72Minutes()} after {@link #getAlos72Minutes() alos}.
*
* @see #getShaahZmanis16Point1Degrees()
- * @see #getMinchaGedola()
- * @see #getMinchaKetana()
- * @return the Date of the time of mincha ketana. If the calculation can't be computed such as
+ * @see #getMinchaGedolaGRA()
+ * @see #getMinchaKetanaGRA()
+ * @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 getMinchaKetana72Minutes() {
- return getMinchaKetana(getAlos72(), getTzais72(), true);
+ public Instant getMinchaKetana72Minutes() {
+ return getMinchaKetana(getAlos72Minutes(), getTzais72Minutes(), true);
}
/**
* This method returns the time of plag hamincha according to the Magen Avraham with the day starting 60
* minutes before sunrise and ending 60 minutes after sunset. This is calculated as 10.75 hours after
- * {@link #getAlos60() dawn}. The formula used is 10.75 {@link #getShaahZmanis60Minutes()} after {@link #getAlos60()}.
+ * {@link #getAlos60Minutes() dawn}. The formula used is 10.75 {@link #getShaahZmanis60Minutes()} after {@link #getAlos60Minutes()}.
*
- * @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.
*
* @see #getShaahZmanis60Minutes()
- * @see #getAlos60()
- * @see #getTzais60()
+ * @see #getAlos60Minutes()
+ * @see #getTzais60Minutes()
*/
- public Date getPlagHamincha60Minutes() {
- return getPlagHamincha(getAlos60(), getTzais60(), true);
+ public Instant getPlagHamincha60Minutes() {
+ return getPlagHamincha(getAlos60Minutes(), getTzais60Minutes(), true);
}
/**
* This method should be used lechumra only and returns the time of plag hamincha according to the
* Magen Avraham with the day starting 72 minutes before sunrise and ending 72 minutes after sunset. This is calculated
- * as 10.75 hours after {@link #getAlos72() dawn}. The formula used is 10.75 {@link #getShaahZmanis72Minutes()} after
- * {@link #getAlos72()}. Since plag by this calculation can occur after sunset, it should only be used
+ * as 10.75 hours after {@link #getAlos72Minutes() dawn}. The formula used is 10.75 {@link #getShaahZmanis72Minutes()} after
+ * {@link #getAlos72Minutes()}. Since plag by this calculation can occur after sunset, it should only be used
* lechumra.
*
* @deprecated This method should be used lechumra only since it returns a very late time (often after
@@ -2023,7 +1835,7 @@ public Date getPlagHamincha60Minutes() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
@@ -2031,15 +1843,15 @@ public Date getPlagHamincha60Minutes() {
* @see #getShaahZmanis72Minutes()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha72Minutes() {
- return getPlagHamincha(getAlos72(), getTzais72(), true);
+ public Instant getPlagHamincha72Minutes() {
+ return getPlagHamincha(getAlos72Minutes(), getTzais72Minutes(), true);
}
/**
* This method should be used lechumra only and returns the time of plag hamincha according to the
* Magen Avraham with the day starting 90 minutes before sunrise and ending 90 minutes after sunset. This is calculated
- * as 10.75 hours after {@link #getAlos90() dawn}. The formula used is 10.75 {@link #getShaahZmanis90Minutes()} after
- * {@link #getAlos90()}. Since plag by this calculation can occur after sunset, it should only be used
+ * as 10.75 hours after {@link #getAlos90Minutes() dawn}. The formula used is 10.75 {@link #getShaahZmanis90Minutes()} after
+ * {@link #getAlos90Minutes()}. Since plag by this calculation can occur after sunset, it should only be used
* lechumra.
*
* @deprecated This method should be used lechumra only since it returns a very late time (often after
@@ -2047,7 +1859,7 @@ public Date getPlagHamincha72Minutes() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
@@ -2055,15 +1867,15 @@ public Date getPlagHamincha72Minutes() {
* @see #getShaahZmanis90Minutes()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha90Minutes() {
- return getPlagHamincha(getAlos90(), getTzais90(), true);
+ public Instant getPlagHamincha90Minutes() {
+ return getPlagHamincha(getAlos90Minutes(), getTzais90Minutes(), true);
}
/**
* This method should be used lechumra only and returns the time of plag hamincha according to the Magen
* Avraham with the day starting 96 minutes before sunrise and ending 96 minutes after sunset. This is calculated as 10.75
- * hours after {@link #getAlos96() dawn}. The formula used is 10.75 {@link #getShaahZmanis96Minutes()} after
- * {@link #getAlos96()}. Since plag by this calculation can occur after sunset, it should only be used
+ * hours after {@link #getAlos96Minutes() dawn}. The formula used is 10.75 {@link #getShaahZmanis96Minutes()} after
+ * {@link #getAlos96Minutes()}. Since plag by this calculation can occur after sunset, it should only be used
* lechumra.
*
* @deprecated This method should be used lechumra only since it returns a very late time (often after
@@ -2071,15 +1883,15 @@ public Date getPlagHamincha90Minutes() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
* @see #getShaahZmanis96Minutes()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha96Minutes() {
- return getPlagHamincha(getAlos96(), getTzais96(), true);
+ public Instant getPlagHamincha96Minutes() {
+ return getPlagHamincha(getAlos96Minutes(), getTzais96Minutes(), true);
}
/**
@@ -2093,13 +1905,13 @@ public Date getPlagHamincha96Minutes() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha96MinutesZmanis() {
+ public Instant getPlagHamincha96MinutesZmanis() {
return getPlagHamincha(getAlos96Zmanis(), getTzais96Zmanis(), true);
}
@@ -2114,13 +1926,13 @@ public Date getPlagHamincha96MinutesZmanis() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha90MinutesZmanis() {
+ public Instant getPlagHamincha90MinutesZmanis() {
return getPlagHamincha(getAlos90Zmanis(), getTzais90Zmanis(), true);
}
@@ -2135,13 +1947,13 @@ public Date getPlagHamincha90MinutesZmanis() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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.
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha72MinutesZmanis() {
+ public Instant getPlagHamincha72MinutesZmanis() {
return getPlagHamincha(getAlos72Zmanis(), getTzais72Zmanis(), true);
}
@@ -2158,7 +1970,7 @@ public Date getPlagHamincha72MinutesZmanis() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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
* 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.
@@ -2166,7 +1978,7 @@ public Date getPlagHamincha72MinutesZmanis() {
* @see #getShaahZmanis16Point1Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha16Point1Degrees() {
+ public Instant getPlagHamincha16Point1Degrees() {
return getPlagHamincha(getAlos16Point1Degrees(), getTzais16Point1Degrees(), true);
}
@@ -2183,7 +1995,7 @@ public Date getPlagHamincha16Point1Degrees() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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
* 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.
@@ -2191,7 +2003,7 @@ public Date getPlagHamincha16Point1Degrees() {
* @see #getShaahZmanis19Point8Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha19Point8Degrees() {
+ public Instant getPlagHamincha19Point8Degrees() {
return getPlagHamincha(getAlos19Point8Degrees(), getTzais19Point8Degrees(), true);
}
@@ -2208,7 +2020,7 @@ public Date getPlagHamincha19Point8Degrees() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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
* 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.
@@ -2217,7 +2029,7 @@ public Date getPlagHamincha19Point8Degrees() {
* @see #getPlagHamincha120Minutes()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha26Degrees() {
+ public Instant getPlagHamincha26Degrees() {
return getPlagHamincha(getAlos26Degrees(), getTzais26Degrees(), true);
}
@@ -2234,7 +2046,7 @@ public Date getPlagHamincha26Degrees() {
* current plan to remove this method from the API, and this deprecation is intended to alert developers
* of the danger of using it.
*
- * @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
* 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.
@@ -2242,22 +2054,26 @@ public Date getPlagHamincha26Degrees() {
* @see #getShaahZmanis18Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getPlagHamincha18Degrees() {
+ public Instant getPlagHamincha18Degrees() {
return getPlagHamincha(getAlos18Degrees(), getTzais18Degrees(), true);
}
/**
- * This method should be used lechumra only and returns the time of plag hamincha based on the opinion
- * that the day starts at {@link #getAlos16Point1Degrees() alos 16.1°} and ends at {@link #getSunset() sunset}.
- * 10.75 shaos zmaniyos are calculated based on this day and added to {@link #getAlos16Point1Degrees()
+ * This method should be used lechumra only and returns the time of plag hamincha based on the opinion that
+ * the day starts at {@link #getAlos16Point1Degrees() alos 16.1°} and ends at {@link #getSunset()
+ * sunset}. 10.75 shaos zmaniyos are calculated based on this day and added to {@link #getAlos16Point1Degrees()
* alos} to reach this time. This time is 10.75 shaos zmaniyos (temporal hours) after {@link
* #getAlos16Point1Degrees() dawn} based on the opinion that the day is calculated from a {@link #getAlos16Point1Degrees()
* dawn} of 16.1 degrees before sunrise to {@link #getSeaLevelSunset() sea level sunset}. This returns the time of 10.75 *
* the calculated shaah zmanis after {@link #getAlos16Point1Degrees() dawn}. Since plag by this
* calculation can occur after sunset, it should only be used lechumra.
*
+ * @deprecated This method should be used lechumra only since it returns a very late time (often after
+ * shkiah), and if used lekula can result in chillul Shabbos etc. There is no
+ * current plan to remove this method from the API, and this deprecation is intended to alert developers
+ * of the danger of using it.
*
- * @return the Date of the plag. If the calculation can't be computed such as northern and southern
+ * @return the Instant of the plag. 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.
@@ -2266,8 +2082,8 @@ public Date getPlagHamincha18Degrees() {
* @see #getSeaLevelSunset()
*/
@Deprecated (forRemoval=false)
- public Date getPlagAlosToSunset() {
- return getPlagHamincha(getAlos16Point1Degrees(), getElevationAdjustedSunset(), false);
+ public Instant getPlagAlosToSunset() {
+ return getPlagHamincha(getAlos16Point1Degrees(), getSunsetBasedOnElevationSetting(), false);
}
/**
@@ -2280,7 +2096,7 @@ public Date getPlagAlosToSunset() {
* {@link #getTzaisGeonim7Point083Degrees() tzais} . This returns the time of 10.75 * the calculated
* shaah zmanis after {@link #getAlos16Point1Degrees() dawn}.
*
- * @return the Date of the plag. If the calculation can't be computed such as northern and
+ * @return the Instant of the plag. 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.
@@ -2288,7 +2104,7 @@ public Date getPlagAlosToSunset() {
* @see #getAlos16Point1Degrees()
* @see #getTzaisGeonim7Point083Degrees()
*/
- public Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() {
+ public Instant getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() {
return getPlagHamincha(getAlos16Point1Degrees(), getTzaisGeonim7Point083Degrees(), false);
}
@@ -2300,7 +2116,7 @@ public Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() {
* zmaniyos calculated based on a day starting at {@link #getAlos16Point1Degrees() alos 16.1°} and
* ending at tzais 3.8°.
*
- * @return the Date of the plag. If the calculation can't be computed such as northern and
+ * @return the Instant of the plag. 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.
@@ -2309,18 +2125,18 @@ public Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() {
* @see #getMinchaGedolaAhavatShalom()
* @see #getMinchaKetanaAhavatShalom()
*/
- public Date getPlagAhavatShalom() {
+ public Instant getPlagAhavatShalom() {
return getTimeOffset(getTzaisGeonim3Point8Degrees(), -getShaahZmanisAlos16Point1ToTzais3Point8() * 1.25);
}
/**
* Method to return the beginning of bain hashmashos of Rabbeinu Tam calculated when the sun is
- * {@link #ZENITH_13_POINT_24 13.24°} below the western {@link #GEOMETRIC_ZENITH geometric horizon} (90°)
+ * {@link ZENITH_13_POINT_24 13.24°} below the western {@link GEOMETRIC_ZENITH geometric horizon} (90°)
* after sunset. This calculation is based on the same calculation of {@link #getBainHashmashosRT58Point5Minutes()
* bain hashmashos Rabbeinu Tam 58.5 minutes} but uses a degree-based calculation instead of 58.5 exact
* minutes. This calculation is based on the position of the sun 58.5 minutes after sunset in Jerusalem around the equinox / equilux,
- * which calculates to 13.24° below {@link #GEOMETRIC_ZENITH geometric zenith}.
+ * which calculates to 13.24° below {@link GEOMETRIC_ZENITH geometric zenith}.
* NOTE: As per Yisrael Vehazmanim Vol. III page 1028, No. 50, a dip of slightly less than 13° should be used.
* Calculations show that the proper dip to be 13.2456° (truncated to 13.24 that provides about 1.5 second
* earlier (lechumra) time) below the horizon at that time. This makes a difference of 1 minute and 10
@@ -2328,16 +2144,15 @@ public Date getPlagAhavatShalom() {
* 13.24° versus 13°. For NY during the solstice, the difference is 1 minute 56 seconds.
* @todo recalculate the above based on equilux/equinox calculations.
*
- * @return the Date of the sun being 13.24° below {@link #GEOMETRIC_ZENITH geometric zenith}
+ * @return the Instant of the sun being 13.24° below {@link GEOMETRIC_ZENITH geometric zenith}
* (90°). 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_13_POINT_24
* @see #getBainHashmashosRT58Point5Minutes()
*/
- public Date getBainHashmashosRT13Point24Degrees() {
+ public Instant getBainHashmashosRT13Point24Degrees() {
return getSunsetOffsetByDegrees(ZENITH_13_POINT_24);
}
@@ -2347,14 +2162,14 @@ public Date getBainHashmashosRT13Point24Degrees() {
* "https://en.wikipedia.org/wiki/Biblical_and_Talmudic_units_of_measurement">mil before tzais or 3 1/4
* mil after sunset. With a mil calculated as 18 minutes, 3.25 * 18 = 58.5 minutes.
*
- * @return the Date of 58.5 minutes after sunset. If the calculation can't be computed such as in the
+ * @return the Instant of 58.5 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 getBainHashmashosRT58Point5Minutes() {
- return getTimeOffset(getElevationAdjustedSunset(), 58.5 * MINUTE_MILLIS);
+ public Instant getBainHashmashosRT58Point5Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), 58.5 * MINUTE_MILLIS);
}
/**
@@ -2362,14 +2177,14 @@ public Date getBainHashmashosRT58Point5Minutes() {
* 18-minute mil) before
* shkiah calculated as {@link #getTzaisGeonim7Point083Degrees() 7.083°}.
*
- * @return the Date of the bain hashmashos of Rabbeinu Tam in this calculation. If the
+ * @return the Instant of the bain hashmashos of Rabbeinu Tam in this calculation. 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 #getTzaisGeonim7Point083Degrees()
*/
- public Date getBainHashmashosRT13Point5MinutesBefore7Point083Degrees() {
+ public Instant getBainHashmashosRT13Point5MinutesBefore7Point083Degrees() {
return getTimeOffset(getSunsetOffsetByDegrees(ZENITH_7_POINT_083), -13.5 * MINUTE_MILLIS);
}
@@ -2379,19 +2194,19 @@ public Date getBainHashmashosRT13Point5MinutesBefore7Point083Degrees() {
* alos (calculated as 19.8° before sunrise) and sunrise. This is added to sunset to arrive at the time
* for bain hashmashos of Rabbeinu Tam.
*
- * @return the Date of bain hashmashos of Rabbeinu Tam for this calculation. If the
+ * @return the Instant of bain hashmashos of Rabbeinu Tam for this calculation. 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 getBainHashmashosRT2Stars() {
- Date alos19Point8 = getAlos19Point8Degrees();
- Date sunrise = getElevationAdjustedSunrise();
+ public Instant getBainHashmashosRT2Stars() {
+ Instant alos19Point8 = getAlos19Point8Degrees();
+ Instant sunrise = getSunriseBasedOnElevationSetting();
if (alos19Point8 == null || sunrise == null) {
return null;
}
- return getTimeOffset(getElevationAdjustedSunset(), (sunrise.getTime() - alos19Point8.getTime()) * (5 / 18d));
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), (sunrise.toEpochMilli() - alos19Point8.toEpochMilli()) * (5 / 18d));
}
/**
@@ -2401,14 +2216,14 @@ public Date getBainHashmashosRT2Stars() {
* >mil before sunset. According to the Yereim, bain hashmashos starts 3/4 of a mil before sunset and
* tzais or nightfall starts at sunset.
*
- * @return the Date of 18 minutes before sunset. If the calculation can't be computed such as in the
+ * @return the Instant of 18 minutes before 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.
* @see #getBainHashmashosYereim3Point05Degrees()
*/
- public Date getBainHashmashosYereim18Minutes() {
- return getTimeOffset(getElevationAdjustedSunset(), -18 * MINUTE_MILLIS);
+ public Instant getBainHashmashosYereim18Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), -18 * MINUTE_MILLIS);
}
/**
@@ -2423,25 +2238,25 @@ public Date getBainHashmashosYereim18Minutes() {
* traditional 0.566° is used. This is more inline with the actual refraction in Eretz Yisrael and is
* brought down by Rabbi
- * Yedidya Manet in his Zmanei Halacha
+ * Yedidya Manet in his Zmanei HaHalacha
* Lema'aseh (p. 11). That is the first source that I am aware of that calculates degree-based Yereim
* zmanim. The 0.5166° refraction is also used by the Luach Itim
* Lebinah. Calculating the Yereim's bain hashmashos using 18-minute based degrees is also suggested
* in the upcoming 8th edition of the zmanim Kehilchasam. For more details, see the article The Yereim's Bein Hashmashos.
+ * "https://kosherjava.com/2020/12/07/the-yereims-bein-hashmashos/">The Yereim's Bain Hashmashos.
*
* @todo recalculate based on equinox/equilux
- * @return the Date of the sun's position 3.05° minutes before sunset. If the calculation can't
+ * @return the Instant of the sun's position 3.05° minutes before 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.
*
- * @see #ZENITH_MINUS_3_POINT_05
+ * @see ZENITH_MINUS_3_POINT_05
* @see #getBainHashmashosYereim18Minutes()
* @see #getBainHashmashosYereim2Point8Degrees()
* @see #getBainHashmashosYereim2Point1Degrees()
*/
- public Date getBainHashmashosYereim3Point05Degrees() {
+ public Instant getBainHashmashosYereim3Point05Degrees() {
return getSunsetOffsetByDegrees(ZENITH_MINUS_3_POINT_05);
}
@@ -2453,15 +2268,15 @@ public Date getBainHashmashosYereim3Point05Degrees() {
* to the Yereim, bain hashmashos starts 3/4 of a mil before sunset and tzais or nightfall starts
* at sunset.
*
- * @return the Date of 16.875 minutes before sunset. If the calculation can't be computed such as in the
+ * @return the Instant of 16.875 minutes before 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.
*
* @see #getBainHashmashosYereim2Point8Degrees()
*/
- public Date getBainHashmashosYereim16Point875Minutes() {
- return getTimeOffset(getElevationAdjustedSunset(), -16.875 * MINUTE_MILLIS);
+ public Instant getBainHashmashosYereim16Point875Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), -16.875 * MINUTE_MILLIS);
}
/**
@@ -2475,17 +2290,17 @@ public Date getBainHashmashosYereim16Point875Minutes() {
* starts at sunset. Details, including how the degrees were calculated can be seen in the documentation of
* {@link #getBainHashmashosYereim3Point05Degrees()}.
*
- * @return the Date of the sun's position 2.8° minutes before sunset. If the calculation can't
+ * @return the Instant of the sun's position 2.8° minutes before 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.
*
- * @see #ZENITH_MINUS_2_POINT_8
+ * @see ZENITH_MINUS_2_POINT_8
* @see #getBainHashmashosYereim16Point875Minutes()
* @see #getBainHashmashosYereim3Point05Degrees()
* @see #getBainHashmashosYereim2Point1Degrees()
*/
- public Date getBainHashmashosYereim2Point8Degrees() {
+ public Instant getBainHashmashosYereim2Point8Degrees() {
return getSunsetOffsetByDegrees(ZENITH_MINUS_2_POINT_8);
}
@@ -2496,21 +2311,21 @@ public Date getBainHashmashosYereim2Point8Degrees() {
* before sunset. According to the Yereim, bain hashmashos starts 3/4 of a mil before sunset and
* tzais or nightfall starts at sunset.
*
- * @return the Date of 13.5 minutes before sunset. If the calculation can't be computed such as in the
+ * @return the Instant of 13.5 minutes before 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.
*
* @see #getBainHashmashosYereim2Point1Degrees()
*/
- public Date getBainHashmashosYereim13Point5Minutes() {
- return getTimeOffset(getElevationAdjustedSunset(), -13.5 * MINUTE_MILLIS);
+ public Instant getBainHashmashosYereim13Point5Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), -13.5 * MINUTE_MILLIS);
}
/**
* This method returns the beginning of bain hashmashos according to the Yereim (Rabbi Eliezer of Metz) calculated as the sun's
- * position 2.1° above the horizon above the horizon around the equinox / equilux in
* Yerushalayim, its position 13.5 minutes or 3/4 of an 18-minute mil before sunset. According to the
@@ -2518,157 +2333,191 @@ public Date getBainHashmashosYereim13Point5Minutes() {
* at sunset. Details, including how the degrees were calculated can be seen in the documentation of
* {@link #getBainHashmashosYereim3Point05Degrees()}.
*
- * @return the Date of the sun's position 2.1° minutes before sunset. If the calculation can't be
+ * @return the Instant of the sun's position 2.1° minutes before 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.
*
- * @see #ZENITH_MINUS_2_POINT_1
+ * @see ZENITH_MINUS_2_POINT_1
* @see #getBainHashmashosYereim13Point5Minutes()
* @see #getBainHashmashosYereim2Point8Degrees()
* @see #getBainHashmashosYereim3Point05Degrees()
*/
- public Date getBainHashmashosYereim2Point1Degrees() {
+ public Instant getBainHashmashosYereim2Point1Degrees() {
return getSunsetOffsetByDegrees(ZENITH_MINUS_2_POINT_1);
}
/**
- * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated at the
- * sun's position at {@link #ZENITH_3_POINT_7 3.7°} below the western horizon.
+ * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated at the sun's
+ * position at {@link ZENITH_3_POINT_7 3.7°} below {@link GEOMETRIC_ZENITH geometric zenith} (90°), calculated
+ * as the position of the sun 13.5 minutes after sunset, the time it takes to walk 3/4 of a mil at 18 minutes a mil, or 13.5 minutes
+ * after sunset. The sun is 3.7° below {@link GEOMETRIC_ZENITH geometric zenith} at this time in Jerusalem around the equinox / equilux. This does
+ * not cover the 26.46 it takes to walk 49 amos (the heref ayin of bain hashmashos of Rav Yosi) at the pace
+ * of an 18-minute mil. It should be noted that Rabbi Yedidya Manet in his Zmanei HaHalacha Lema'aseh (4th edition part 2, pages and 22
+ * and 24) lists 3.65° that appears to be a drop too early.
*
- * @return the Date representing the time when the sun is 3.7° below sea level.
- * @see #ZENITH_3_POINT_7
+ * @return the Instant representing the time when the sun is 3.7° below sea level.
+ * @see ZENITH_3_POINT_7
*/
- public Date getTzaisGeonim3Point7Degrees() {
+ @Deprecated (forRemoval=false)
+ public Instant getTzaisGeonim3Point7Degrees() {
return getSunsetOffsetByDegrees(ZENITH_3_POINT_7);
}
/**
- * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated at the
- * sun's position at {@link #ZENITH_3_POINT_8 3.8°} below the western horizon.
+ * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated at the sun's
+ * position at {@link ZENITH_3_POINT_7 3.8°} below {@link GEOMETRIC_ZENITH geometric zenith} (90°), calculated
+ * as the position of the sun 13.5 minutes after sunset, the time it takes to walk 3/4 of a mil at 18 minutes a mil, plus 30 seconds
+ * for the time it takes to walk 49 amos (the heref ayin of bain hashmashos of Rav Yosi). With this being
+ * on an 18-minutes mil, 49 amos would take 26.46, rounded to 30 seconds), for a total of 14 minutes after sunset. The sun is
+ * {@link ZENITH_3_POINT_8 3.8°} below {@link GEOMETRIC_ZENITH geometric zenith} at this time in Jerusalem around the equinox / equilux.
*
- * @return the Date representing the time when the sun is 3.8° below sea level.
- * @see #ZENITH_3_POINT_8
+ * @return the Instant representing the time when the sun is 3.8° below sea level.
+ * @see ZENITH_3_POINT_8
*/
- public Date getTzaisGeonim3Point8Degrees() {
+ @Deprecated (forRemoval=false)
+ public Instant getTzaisGeonim3Point8Degrees() {
return getSunsetOffsetByDegrees(ZENITH_3_POINT_8);
}
/**
* This method returns the tzais (nightfall) based on the opinion of the Geonim calculated at the
- * sun's position at {@link #ZENITH_5_POINT_95 5.95°} below the western horizon.
- *
- * @return the Date representing the time when the sun is 5.95° below sea level. If the calculation
+ * sun's position at {@link ZENITH_5_POINT_95 5.95°} below below {@link GEOMETRIC_ZENITH geometric zenith}
+ * (90°), calculated as the position of the sun 24 minutes after sunset in Jerusalem around the equinox / equilux. The
+ * 24 minutes is based on the Baal Hatanya's calculation of 18 minutes (3/4 of a 24 minute mil) + 4 minutes for
+ * shkiah amitis + 2 minutes for bain hashmashos of Rav Yosi. See Hazmanim Bahalacha vol II, ch. 50, no. 5,
+ * p. 512-513, ch. 47, and Yisrael Vehazmanim Vol III, ch. 13, no. 53, p. 1026. Among sources he mentions for this zman is Rabbi Yehuda (Leo) Levi's calculations in Jewish Chrononomy
+ * and other sources. Calculations show that the time is closer to 5.93° and was seemingly rounded to 5.95°.
+ * Chabad calendars usually use the 6°-based {@link #getTzaisBaalHatanya()} that is built on this same calculation.
+ * It should be noted that Rabbi Yedidya Manet in his Zmanei HaHalacha Lema'aseh (4th edition part 2, pages and 22 and 24) lists 5.88° that appears to be a drop
+ * too early.
+ *
+ * @return the Instant representing the time when the sun is 5.95° below sea level. 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_5_POINT_95
+ * @see #getTzaisBaalHatanya()
*/
- public Date getTzaisGeonim5Point95Degrees() {
+ public Instant getTzaisGeonim5Point95Degrees() {
return getSunsetOffsetByDegrees(ZENITH_5_POINT_95);
}
/**
* This method returns the tzais (nightfall) based on the opinion of the Geonim calculated as 3/4
* of a mil based on a
- * 24-minute mil, or 18 minutes. It is the sun's position at {@link #ZENITH_4_POINT_61 4.61°} below the
+ * 24-minute mil, or 18 minutes. It is the sun's position at {@link ZENITH_4_POINT_66 4.66°} below the
* western horizon. This is a very early zman and should not be relied on without Rabbinical guidance.
+ * This does not cover the 35.28 seconds it takes to walk 49 amos (the heref ayin of bain hashmashos
+ * of Rav Yosi) at the pace of a 24-minute mil. See {@link #getTzaisGeonim4Point8Degrees()} for a time that covers the
+ * heref ayin.
*
- * @return the Date representing the time when the sun is 4.61° below sea level. If the calculation
+ * @return the Instant representing the time when the sun is 4.66° below sea level. 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_4_POINT_61
+ * @see ZENITH_4_POINT_66
+ * @see #getTzaisGeonim4Point8Degrees()
*/
- public Date getTzaisGeonim4Point61Degrees() {
- return getSunsetOffsetByDegrees(ZENITH_4_POINT_61);
+ @Deprecated (forRemoval=false)
+ public Instant getTzaisGeonim4Point66Degrees() {
+ return getSunsetOffsetByDegrees(ZENITH_4_POINT_66);
}
/**
* This method returns the tzais (nightfall) based on the opinion of the Geonim calculated as 3/4
* of a mil, based on a
- * 22.5-minute mil, or 16 7/8 minutes. It is the sun's position at {@link #ZENITH_4_POINT_37 4.37°} below the western
- * horizon. This is a very early zman and should not be relied on without Rabbinical guidance.
- *
- * @return the Date representing the time when the sun is 4.37° below sea level. If the calculation
+ * 22.5-minute mil, or 16 7/8 minutes. It is the sun's position at {@link ZENITH_4_POINT_42 4.42°} below the western
+ * horizon. This is a very early zman and should not be relied on without Rabbinical guidance. This does
+ * not cover the 33.07 seconds it takes to walk 49 amos (the heref ayin of bain hashmashos of Rav Yosi)
+ * at the pace of a 22.5 minute-mil. It should be noted that Rabbi Yedidya Manet in his Zmanei HaHalacha Lema'aseh (4th edition part 2, pages and 22
+ * and 24) lists 4.37° that appears to be a drop too early.
+ *
+ * @return the Instant representing the time when the sun is 4.42° below sea level. 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_4_POINT_37
+ * @see ZENITH_4_POINT_42
*/
- public Date getTzaisGeonim4Point37Degrees() {
- return getSunsetOffsetByDegrees(ZENITH_4_POINT_37);
- }
-
- /**
- * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated as 3/4
- * of a 24-minute mil,
- * based on a mil being 24 minutes, and is calculated as 18 + 2 + 4 for a total of 24 minutes. It is the
- * sun's position at {@link #ZENITH_5_POINT_88 5.88°} below the western horizon. This is a very early
- * zman and should not be relied on without Rabbinical guidance.
- *
- * @todo Additional detailed documentation needed.
- * @return the Date representing the time when the sun is 5.88° below sea level. 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_5_POINT_88
- */
- public Date getTzaisGeonim5Point88Degrees() {
- return getSunsetOffsetByDegrees(ZENITH_5_POINT_88);
- }
-
- /**
- * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated as 3/4
- * of a mil based on the
- * sun's position at {@link #ZENITH_4_POINT_8 4.8°} below the western horizon. This is based on Rabbi Leo Levi's
- * calculations. This is a very early zman and should not be relied on without Rabbinical guidance.
- * @todo Additional documentation needed.
- *
- * @return the Date representing the time when the sun is 4.8° below sea level. If the calculation
+ @Deprecated (forRemoval=false)
+ public Instant getTzaisGeonim4Point42Degrees() {
+ return getSunsetOffsetByDegrees(ZENITH_4_POINT_42);
+ }
+
+ /**
+ * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated as the
+ * sun's position below the horizon at a time of 18.6 minutes after sunset. This is calculated as 3/4 of a 24-minute
+ * mil, plus 0.6 minutes for the
+ * time to walk 49 amos for bain hashmashos of Rav Yosi (with this zman based on a 24-minute mil, 49
+ * amos would take 35.28 seconds to walk), for a total of 18.6 minutes after sunset. This calculates to the sun's position
+ * at {@link ZENITH_4_POINT_8 4.8°} below the western horizon. This is based on Rav Yechiel Michel Shlezinger's sefer Aizehu Bain Hashmashos, Rabbi Yehuda (Leo) Levi's
+ * calculations in Zmanei Hayom BaHalacha p. 37.
+ * At this point, 3 medium sized stars are visible to a non-expert with good vision with effort. An expert knowing where to
+ * look can see the 3 medium stars as early as 15 minutes after sunset. This is explained in detail in Hazmanim Bahalacha vol
+ * II, ch. 41, no. 6 (p. 372-373, ch. 47, no. 11-12 (p. 491-493) where it is clear that medium sized stars would be visible as
+ * early as 14 minutes after sunset (13.5 minutes for 3/4 of an 18 minute Mil, plus 0.5 minutes for bain Hashmashos
+ * of Rav Yosi) to an expert. See more details on this earier zman at {@link #getTzaisGeonim3Point8Degrees()}.
+ * This is an early zman for tzaisand should not be relied on without Rabbinical guidance.
+ *
+ * @return the Instant representing the time when the sun is 4.8° below sea level. 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_4_POINT_8
+ * @see ZENITH_4_POINT_8
*/
- public Date getTzaisGeonim4Point8Degrees() {
+ public Instant getTzaisGeonim4Point8Degrees() {
return getSunsetOffsetByDegrees(ZENITH_4_POINT_8);
}
-
/**
- * This method returns the tzais (nightfall) based on the opinion of the Geonim as calculated by
- * Rabbi Yechiel Michel Tucazinsky. It is
- * based on of the position of the sun no later than {@link #getTzaisGeonim6Point45Degrees() 31 minutes} after sunset
- * in Jerusalem the height of the summer solstice and is 28 minutes after shkiah around the equinox / equilux. This
- * computes to 6.45° below the western horizon.
- * @todo Additional documentation details needed.
- *
- * @return the Date representing the time when the sun is 6.45° below sea level. If the
+ * This method returns the tzais (nightfall) based on the opinion of the Geonim as calculated by Rabbi Yechiel Michel Tucazinsky as the position of
+ * the sun no later than 31 minutes after sea-level sunset in Jerusalem (the Birur halacha shows that Rav Tucazinsky's
+ * calculations for sunset, listed as 28 minutes in this case, were about 3 minutes later than reality), and at the height of
+ * the summer solstice,this zman, calculatons show that 30.75 minutes after shkiah computes to 6.45° below
+ * {@link GEOMETRIC_ZENITH geometric zenith}. This calculation is found in the Birur Halacha Yoreh Deah 262 and it is the commonly used
+ * zman in Israel. It is also used in the Luach Itim Lebinah. it
+ * should be noted that this differs from the 6.1° / 6.2° calculation for Rabbi Tucazinsky's time as calculated by the
+ * Hazmanim Bahalacha Vol II chapter 50:7 (page 515). Calculations show that 6.45° at the equinox is 26.5 minutes after
+ * shkiah around the equinox /
+ * equilux.
+ *
+ * @return the Instant representing the time when the sun is 6.45° below sea level. 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_6_POINT_45
+ * @see ZENITH_6_POINT_45
*/
- public Date getTzaisGeonim6Point45Degrees() {
+ public Instant getTzaisGeonim6Point45Degrees() {
return getSunsetOffsetByDegrees(ZENITH_6_POINT_45);
}
/**
* This method returns the tzais (nightfall) based on the opinion of the Geonim calculated when the
- * sun's position {@link #ZENITH_7_POINT_083 7.083° (or 7° 5\u2032}) below the western horizon. This is often
+ * sun's position {@link ZENITH_7_POINT_083 7.083° (or 7° 5\u2032}) below the western horizon. This is often
* referred to as 7°5' or 7° and 5 minutes. This calculation is based on the observation of 3 medium-sized
* stars by Dr. Baruch (Berthold) Cohn in his luach Tabellen enthaltend die Zeitangaben für
* den Beginn der Nacht und des Tages für die Breitengrade + 66 bis -38 published in Strasbourg, France in 1899.
- * This calendar was very popular in Europe, and many other calendars based their time on it. tzais time on it. Rav Dovid Tzvi Hoffman in his
* Sh"Ut Melamed Leho'il in an exchange of letters with Baruch Cohn in Orach Chaim 30 agreed to this zman (page 36),
@@ -2679,21 +2528,21 @@ public Date getTzaisGeonim6Point45Degrees() {
* Exactly. The actual position of the sun 30 minutes after sunset in Jerusalem at the equilux is 7.205° and 7.199°
* at the equinox. See Hazmanim Bahalacha vol 2, pages 520-521 for more details.
*
- * @return the Date representing the time when the sun is 7.083° below sea level. If the
+ * @return the Instant representing the time when the sun is 7.083° below sea level. 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_7_POINT_083
+ * @see ZENITH_7_POINT_083
*/
- public Date getTzaisGeonim7Point083Degrees() {
+ public Instant getTzaisGeonim7Point083Degrees() {
return getSunsetOffsetByDegrees(ZENITH_7_POINT_083);
}
/**
* This method returns tzais (nightfall) based on the opinion of the Geonim calculated as 45 minutes
* after sunset during the summer solstice in New York, when the neshef (twilight) is the longest. The sun's
- * position at this time computes to {@link #ZENITH_7_POINT_67 7.75°} below the western horizon. See Igros Moshe Even Haezer 4, Ch. 4 (regarding
* tzais for krias Shema). It is also mentioned in Rabbi Heber's Shaarei Zmanim on in
@@ -2703,49 +2552,33 @@ public Date getTzaisGeonim7Point083Degrees() {
* href="https://www.worldcat.org/oclc/179728985">The radiance of Shabbos as the earliest zman for New York.
* This zman is also listed in the Divrei
* Shalom Vol. III, chapter 75, and Bais Av"i
- * Vol. III, chapter 117. This zman is also listed in the Divrei Shalom etc. chapter 177 (FIXME - could not
- * be located). Since this zman depends on the level of light, Rabbi Yaakov Shakow presented this degree-based
- * calculation to Rabbi Rabbi Shmuel Kamenetsky who agreed
- * to it.
+ * Vol. III, chapter 117. This zman is also listed in the Divrei Shalom etc. chapter 177. Since this
+ * zman depends on the level of light, Rabbi Yaakov Shakow presented this degree-based calculation to Rabbi
+ * Rabbi Shmuel Kamenetsky who agreed to it.
* @todo add hyperlinks to source of Divrei Shalom once it is located.
- * @return the Date representing the time when the sun is 7.67° below sea level. If the
+ * @return the Instant representing the time when the sun is 7.67° below sea level. 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_7_POINT_67
+ * @see ZENITH_7_POINT_67
*/
- public Date getTzaisGeonim7Point67Degrees() {
+ public Instant getTzaisGeonim7Point67Degrees() {
return getSunsetOffsetByDegrees(ZENITH_7_POINT_67);
}
-
- /**
- * This method returns the tzais (nightfall) based on the opinion of the Geonim calculated at the
- * sun's position at {@link #ZENITH_8_POINT_5 8.5°} below the western horizon.
- *
- * @return the Date representing the time when the sun is 8.5° below sea level. 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
- */
- public Date getTzaisGeonim8Point5Degrees() {
- return getSunsetOffsetByDegrees(ZENITH_8_POINT_5);
- }
/**
* This method returns the tzais (nightfall) based on the calculations used in the Luach Itim Lebinah as the stringent time for tzais. It is
- * calculated at the sun's position at {@link #ZENITH_9_POINT_3 9.3°} below the western horizon.
+ * calculated at the sun's position at {@link ZENITH_9_POINT_3 9.3°} below the western horizon.
*
- * @return the Date representing the time when the sun is 9.3° below sea level. If the calculation
+ * @return the Instant representing the time when the sun is 9.3° below sea level. 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 getTzaisGeonim9Point3Degrees() {
+ public Instant getTzaisGeonim9Point3Degrees() {
return getSunsetOffsetByDegrees(ZENITH_9_POINT_3);
}
@@ -2754,21 +2587,21 @@ public Date getTzaisGeonim9Point3Degrees() {
* minutes after sunset around the equinox / equilux, the
* day that a solar hour is 60 minutes in New York. The sun's position at this time computes to
- * {@link #ZENITH_9_POINT_75 9.75°} below the western horizon. This is the opinion of Rabbi Eliyahu Henkin. This also follows the opinion of
* Rabbi Shmuel Kamenetsky. Rabbi Yaakov Shakow presented
* these degree-based times to Rabbi Shmuel Kamenetsky who agreed to them.
*
* @todo recalculate based on equinox / equilux.
- * @return the Date representing the time when the sun is 9.75° below sea level. If the calculation
+ * @return the Instant representing the time when the sun is 9.75° below sea level. 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 #getTzais60()
+ * @see #getTzais60Minutes()
*/
- public Date getTzaisGeonim9Point75Degrees() {
+ public Instant getTzaisGeonim9Point75Degrees() {
return getSunsetOffsetByDegrees(ZENITH_9_POINT_75);
}
@@ -2778,20 +2611,20 @@ public Date getTzaisGeonim9Point75Degrees() {
* "https://he.wikipedia.org/wiki/%D7%9E%D7%9C%D7%9B%D7%99%D7%90%D7%9C_%D7%A6%D7%91%D7%99_%D7%98%D7%A0%D7%A0%D7%91%D7%95%D7%99%D7%9D"
* >Divrei Malkiel that the time to walk the distance of a mil is 15 minutes, for a total of 60 minutes
- * for 4 mil after {@link #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link
- * #isUseElevation()} setting). See detailed documentation explaining the 60 minute concept at {@link #getAlos60()}.
+ * for 4 mil after {@link #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the
+ * {@link #isUseElevation()} setting). See detailed documentation explaining the 60 minute concept at {@link #getAlos60Minutes()}.
*
- * @return the Date representing 60 minutes after sea level sunset. If the calculation can't be
+ * @return the Instant representing 60 minutes after sea level 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.
*
- * @see #getAlos60()
+ * @see #getAlos60Minutes()
* @see #getPlagHamincha60Minutes()
* @see #getShaahZmanis60Minutes()
*/
- public Date getTzais60() {
- return getTimeOffset(getElevationAdjustedSunset(), 60 * MINUTE_MILLIS);
+ public Instant getTzais60Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), 60 * MINUTE_MILLIS);
}
/**
@@ -2803,15 +2636,15 @@ public Date getTzais60() {
* for Israel. This API uses 40 minutes year round in any place on the globe by default. This offset can be changed
* by calling {@link #setAteretTorahSunsetOffset(double)}.
*
- * @return the Date representing 40 minutes (configurable via {@link #setAteretTorahSunsetOffset})
+ * @return the Instant representing 40 minutes (configurable via {@link #setAteretTorahSunsetOffset})
* after sea level 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.
* @see #getAteretTorahSunsetOffset()
* @see #setAteretTorahSunsetOffset(double)
*/
- public Date getTzaisAteretTorah() {
- return getTimeOffset(getElevationAdjustedSunset(), getAteretTorahSunsetOffset() * MINUTE_MILLIS);
+ public Instant getTzaisAteretTorah() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), getAteretTorahSunsetOffset() * MINUTE_MILLIS);
}
/**
@@ -2851,7 +2684,7 @@ public void setAteretTorahSunsetOffset(double ateretTorahSunsetOffset) {
* {@link #getAlos72Zmanis() alos 72 zmaniyos}. Note: Based on this calculation chatzos
* will not be at midday.
*
- * @return the Date of the latest zman krias shema based on this calculation. If the
+ * @return the Instant of the latest zman krias shema based on this calculation. 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.
@@ -2861,7 +2694,7 @@ public void setAteretTorahSunsetOffset(double ateretTorahSunsetOffset) {
* @see #setAteretTorahSunsetOffset(double)
* @see #getShaahZmanisAteretTorah()
*/
- public Date getSofZmanShmaAteretTorah() {
+ public Instant getSofZmanShmaAteretTorah() {
return getSofZmanShma(getAlos72Zmanis(), getTzaisAteretTorah(), false);
}
@@ -2875,7 +2708,7 @@ public Date getSofZmanShmaAteretTorah() {
* {@link #getAlos72Zmanis() alos 72 zmaniyos}.
* Note: Based on this calculation chatzos will not be at midday.
*
- * @return the Date of the latest zman krias shema based on this calculation. If the
+ * @return the Instant of the latest zman krias shema based on this calculation. 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.
@@ -2884,7 +2717,7 @@ public Date getSofZmanShmaAteretTorah() {
* @see #getShaahZmanisAteretTorah()
* @see #setAteretTorahSunsetOffset(double)
*/
- public Date getSofZmanTfilaAteretTorah() {
+ public Instant getSofZmanTfilaAteretTorah() {
return getSofZmanTfila(getAlos72Zmanis(), getTzaisAteretTorah(), false);
}
@@ -2894,25 +2727,25 @@ public Date getSofZmanTfilaAteretTorah() {
* before sunrise and is usually calculated as ending {@link #getTzaisAteretTorah() 40 minutes after sunset}
* (configurable to any offset via {@link #setAteretTorahSunsetOffset(double)}). This is the preferred earliest
* time to pray mincha according to the opinion of the Rambam and others. For more information on this see the documentation on {@link #getMinchaGedola() mincha
+ * >Rambam and others. For more information on this see the documentation on {@link #getMinchaGedolaGRA() mincha
* gedola}. This is calculated as 6.5 {@link #getShaahZmanisAteretTorah() solar hours} after alos. The
* calculation used is 6.5 * {@link #getShaahZmanisAteretTorah()} after {@link #getAlos72Zmanis() alos}.
*
* @see #getAlos72Zmanis()
* @see #getTzaisAteretTorah()
* @see #getShaahZmanisAteretTorah()
- * @see #getMinchaGedola()
+ * @see #getMinchaGedolaGRA()
* @see #getMinchaKetanaAteretTorah()
- * @see ZmanimCalendar#getMinchaGedola()
+ * @see #getMinchaGedolaGRA()
* @see #getAteretTorahSunsetOffset()
* @see #setAteretTorahSunsetOffset(double)
*
- * @return the Date of the time of mincha gedola. If the calculation can't be computed such as
+ * @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 getMinchaGedolaAteretTorah() {
+ public Instant getMinchaGedolaAteretTorah() {
return getMinchaGedola(getAlos72Zmanis(), getTzaisAteretTorah(), false);
}
@@ -2923,7 +2756,7 @@ public Date getMinchaGedolaAteretTorah() {
* {@link #getTzaisAteretTorah() 40 minutes after sunset} (configurable to any offset via
* {@link #setAteretTorahSunsetOffset(double)}). This is the preferred earliest time to pray mincha
* according to the opinion of the Rambam and others.
- * For more information on this see the documentation on {@link #getMinchaGedola() mincha gedola}. This is
+ * For more information on this see the documentation on {@link #getMinchaGedolaGRA() mincha gedola}. This is
* calculated as 9.5 {@link #getShaahZmanisAteretTorah() solar hours} after {@link #getAlos72Zmanis() alos}.
* The calculation used is 9.5 * {@link #getShaahZmanisAteretTorah()} after {@link #getAlos72Zmanis() alos}.
*
@@ -2932,14 +2765,14 @@ public Date getMinchaGedolaAteretTorah() {
* @see #getShaahZmanisAteretTorah()
* @see #getAteretTorahSunsetOffset()
* @see #setAteretTorahSunsetOffset(double)
- * @see #getMinchaGedola()
- * @see #getMinchaKetana()
- * @return the Date of the time of mincha ketana. If the calculation can't be computed such as
+ * @see #getMinchaGedolaGRA()
+ * @see #getMinchaKetanaGRA()
+ * @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 getMinchaKetanaAteretTorah() {
+ public Instant getMinchaKetanaAteretTorah() {
return getMinchaKetana(getAlos72Zmanis(), getTzaisAteretTorah(), false);
}
@@ -2952,7 +2785,7 @@ public Date getMinchaKetanaAteretTorah() {
* {@link #getShaahZmanisAteretTorah() shaos zmaniyos} (temporal hours) after {@link #getAlos72Zmanis()
* dawn}.
*
- * @return the Date of the plag. If the calculation can't be computed such as in the Arctic Circle
+ * @return the Instant of the plag. 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 #getAlos72Zmanis()
@@ -2961,13 +2794,13 @@ public Date getMinchaKetanaAteretTorah() {
* @see #setAteretTorahSunsetOffset(double)
* @see #getAteretTorahSunsetOffset()
*/
- public Date getPlagHaminchaAteretTorah() {
+ public Instant getPlagHaminchaAteretTorah() {
return getPlagHamincha(getAlos72Zmanis(), getTzaisAteretTorah(), false);
}
/**
- * Method to return tzais (dusk) calculated as 72 minutes zmaniyos, or 1/10th of the day after
- * {@link #getSeaLevelSunset() sea level sunset}. This is the way that the tzais (dusk) calculated as 72 minutes zmaniyos, or 1/10th of the day after {@link
+ * #getSeaLevelSunset() sea level sunset}. This is the way that the Minchas Cohen in Ma'amar 2:4 calculates Rebbeinu Tam's
* time of tzeis. It should be noted that this calculation results in the shortest time from sunset to
* tzais being during the winter solstice, the longest at the summer solstice and 72 clock minutes at the
@@ -2975,54 +2808,28 @@ public Date getPlagHaminchaAteretTorah() {
* twilight. The shortest twilight is during the equinox, the longest is during the summer solstice, and in the
* winter with the shortest daylight, the twilight period is longer than during the equinoxes.
*
- * @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.
* @see #getAlos72Zmanis()
*/
- public Date getTzais72Zmanis() {
+ public Instant getTzais72Zmanis() {
return getZmanisBasedOffset(1.2);
}
-
- /**
- * A utility method to return alos (dawn) or tzais (dusk) based on a fractional day offset.
- * @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 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. A null will also be returned if 0 is passed in, since we can't
- * tell if it is sunrise or sunset based. See detailed explanation on top of the {@link AstronomicalCalendar}
- * documentation.
- */
- private Date getZmanisBasedOffset(double hours) {
- long shaahZmanis = getShaahZmanisGra();
- if (shaahZmanis == Long.MIN_VALUE || hours == 0) {
- return null;
- }
-
- if (hours > 0) {
- return getTimeOffset(getElevationAdjustedSunset(), (long) (shaahZmanis * hours));
- } else {
- return getTimeOffset(getElevationAdjustedSunrise(), (long) (shaahZmanis * hours));
- }
- }
/**
* Method to return tzais (dusk) calculated using 90 minutes zmaniyos or 1/8th of the day after {@link
* #getSeaLevelSunset() sea level sunset}. This time is known in Yiddish as the achtel (an eighth)
- * zman.
+ * zman used in various kehilos.
*
- * @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.
* @see #getAlos90Zmanis()
*/
- public Date getTzais90Zmanis() {
+ public Instant getTzais90Zmanis() {
return getZmanisBasedOffset(1.5);
}
@@ -3030,13 +2837,13 @@ public Date getTzais90Zmanis() {
* Method to return tzais (dusk) calculated using 96 minutes zmaniyos or 1/7.5 of the day after
* {@link #getSeaLevelSunset() sea level sunset}.
*
- * @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.
* @see #getAlos96Zmanis()
*/
- public Date getTzais96Zmanis() {
+ public Instant getTzais96Zmanis() {
return getZmanisBasedOffset(1.6);
}
@@ -3049,24 +2856,24 @@ public Date getTzais96Zmanis() {
* opinion of Ula who calculated tzais as 5 mil after elevation adjusted shkiah (sunset). A similar
* calculation {@link #getTzais19Point8Degrees()} uses solar position* calculations based on this time.
*
- * @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.
* @see #getTzais19Point8Degrees()
- * @see #getAlos90()
+ * @see #getAlos90Minutes()
*/
- public Date getTzais90() {
- return getTimeOffset(getElevationAdjustedSunset(), 90 * MINUTE_MILLIS);
+ public Instant getTzais90Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), 90 * MINUTE_MILLIS);
}
/**
* This method should be used lechumra only and returns tzais (nightfall) based on the calculations
- * of Rav Chaim Naeh that the time to walk the
- * distance of a mil
- * according to the Rambam's opinion is 2/5 of an hour (24 minutes)
- * for a total of 120 minutes based on the opinion of Ula who calculated tzais as 5 mil after {@link
- * #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} setting).
+ * of Rav Chaim Naeh that the time to walk the distance
+ * of a mil according to the Rambam's opinion is 2/5 of an hour (24 minutes) for a total of 120
+ * minutes based on the opinion of Ula who calculated tzais as 5 mil after {@link #getSunset()
+ * sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} setting).
* A similar calculation {@link #getTzais26Degrees()} uses degree-based calculations based on this 120 minute calculation.
* Since the zman is extremely late and at a point that is long past the 18° point where the darkest point is
* reached, it should only be used lechumra, such as delaying the start of nighttime mitzvos.
@@ -3075,16 +2882,16 @@ public Date getTzais90() {
* lekula can result in chillul Shabbos etc. There is no current plan to remove this
* method from the API, and this deprecation is intended to alert developers of the danger of using it.
*
- * @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.
* @see #getTzais26Degrees()
- * @see #getAlos120()
+ * @see #getAlos120Minutes()
*/
@Deprecated (forRemoval=false)
- public Date getTzais120() {
- return getTimeOffset(getElevationAdjustedSunset(), 120 * MINUTE_MILLIS);
+ public Instant getTzais120Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), 120 * MINUTE_MILLIS);
}
/**
@@ -3098,16 +2905,16 @@ public Date getTzais120() {
* lekula can result in chillul Shabbos etc. There is no current plan to remove this
* method from the API, and this deprecation is intended to alert developers of the danger of using it.
*
- * @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.
* @see #getAlos120Zmanis()
- * @see #getTzais120()
+ * @see #getTzais120Minutes()
* @see #getTzais26Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getTzais120Zmanis() {
+ public Instant getTzais120Zmanis() {
return getZmanisBasedOffset(2.0);
}
@@ -3119,19 +2926,19 @@ public Date getTzais120Zmanis() {
* Jerusalem. The question of equinox VS equilux is complex, with Rabbi Meir Posen in the Ohr Meir of the opinion that the equilux should be used. See
* Yisrael Vehazmanim vol I, 34:1:4. Rabbi Yedidya Manet in his Zmanei Halacha Lema'aseh (4th edition part 2, pages
+ * "https://www.nli.org.il/en/books/NNL_ALEPH002542826/NLI">Zmanei HaHalacha Lema'aseh (4th edition part 2, pages
* and 22 and 24) and Rabbi Yonah Mertzbuch (in a letter published by Rabbi Manet) are of the opinion that the
* astronomical equinox should be used. The difference adds up to about 9 seconds, too trivial to make much of a
* difference. For information on how this is calculated see the comments on {@link #getAlos16Point1Degrees()}.
*
- * @return the Date representing the time. If the calculation can't be computed such as northern and
+ * @return the Instant representing the time. 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 #getTzais72()
+ * @see #getTzais72Minutes()
* @see #getAlos16Point1Degrees() for more information on this calculation.
*/
- public Date getTzais16Point1Degrees() {
+ public Instant getTzais16Point1Degrees() {
return getSunsetOffsetByDegrees(ZENITH_16_POINT_1);
}
@@ -3146,62 +2953,62 @@ public Date getTzais16Point1Degrees() {
* lekula can result in chillul Shabbos etc. There is no current plan to remove this
* method from the API, and this deprecation is intended to alert developers of the danger of using it.
*
- * @return the Date representing the time. If the calculation can't be computed such as northern and
+ * @return the Instant representing the time. 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 #getTzais120()
+ * @see #getTzais120Minutes()
* @see #getAlos26Degrees()
*/
@Deprecated (forRemoval=false)
- public Date getTzais26Degrees() {
+ public Instant getTzais26Degrees() {
return getSunsetOffsetByDegrees(ZENITH_26_DEGREES);
}
/**
* For information on how this is calculated see the comments on {@link #getAlos18Degrees()}
*
- * @return the Date representing the time. If the calculation can't be computed such as northern and
+ * @return the Instant representing the time. 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 #getAlos18Degrees()
*/
- public Date getTzais18Degrees() {
+ public Instant getTzais18Degrees() {
return getSunsetOffsetByDegrees(ASTRONOMICAL_ZENITH);
}
/**
- * For information on how this is calculated see the comments on {@link #getAlos19Point8Degrees()}
+ * For information on how this is calculated see the comments on {@link #getAlos19Point8Degrees()}.
*
- * @return the Date representing the time. If the calculation can't be computed such as northern and
+ * @return the Instant representing the time. 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 #getTzais90()
+ * @see #getTzais90Minutes()
* @see #getAlos19Point8Degrees()
*/
- public Date getTzais19Point8Degrees() {
+ public Instant getTzais19Point8Degrees() {
return getSunsetOffsetByDegrees(ZENITH_19_POINT_8);
}
/**
* A method to return tzais (dusk) calculated as 96 minutes after {@link #getSunset() sunset} or {@link
* #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} setting). For information on how
- * this is calculated see the comments on {@link #getAlos96()}.
+ * this is calculated see the comments on {@link #getAlos96Minutes()}.
*
- * @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.
- * @see #getAlos96()
+ * @see #getAlos96Minutes()
*/
- public Date getTzais96() {
- return getTimeOffset(getElevationAdjustedSunset(), 96 * MINUTE_MILLIS);
+ public Instant getTzais96Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), 96 * MINUTE_MILLIS);
}
/**
- * A method that returns the local time for fixed chatzos. This time is noon and midnight adjusted from
+ * A method that returns the local time for fixed chatzos. This time is noon and adjusted from
* standard time to account for the local latitude. The 360° of the globe divided by 24 calculates to 15°
* per hour with 4 minutes per degree, so at a longitude of 0 , 15, 30 etc... Chatzos is at exactly 12:00
* noon. This is the time of chatzos according to the Daylight saving time.
*
- * @return the Date representing the local chatzos
- * @see GeoLocation#getLocalMeanTimeOffset()
- * @see AstronomicalCalendar#getLocalMeanTime(double)
+ * @return the Instant representing the local chatzos
+ * @see GeoLocation#getLocalMeanTimeOffset(Instant)
+ * @see #getLocalMeanTime(LocalTime)
*/
- public Date getFixedLocalChatzos() {
- return getLocalMeanTime(12.0);
+ public Instant getFixedLocalChatzosHayom() {
+ return getLocalMeanTime(LocalTime.NOON);
}
/**
@@ -3240,18 +3047,16 @@ public Date getFixedLocalChatzos() {
* the end of the Jewish day. If Kidush Levana occurs during the day (starting at alos and ending at
* tzais), the time returned will be alos. If either the alos or tzais parameter
* are null, no daytime adjustment will be made.
- * @return the Date representing the moment halfway between molad and molad. If the time occurs between
+ * @return the Instant representing the moment halfway between molad and molad. If the time occurs between
* alos and tzais, alos will be returned. If the zman will not occur on this day, a
* null will be returned.
* @see #getSofZmanKidushLevanaBetweenMoldos()
- * @see #getSofZmanKidushLevana15Days(Date, Date)
+ * @see #getSofZmanKidushLevana15Days(Instant, Instant)
* @see JewishCalendar#getSofZmanKidushLevanaBetweenMoldos()
*/
- public Date getSofZmanKidushLevanaBetweenMoldos(Date alos, Date tzais) {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
-
+ public Instant getSofZmanKidushLevanaBetweenMoldos(Instant alos, Instant tzais) {
+ JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate());
+
// Do not calculate for impossible dates, but account for extreme cases. In the extreme case of Rapa Iti in French
// Polynesia on Dec 2027 when kiddush Levana 3 days can be said on Rosh Chodesh, the sof zman Kiddush Levana
// will be on the 12th of the Teves. In the case of Anadyr, Russia on Jan, 2071, sof zman Kiddush Levana between the
@@ -3263,7 +3068,7 @@ public Date getSofZmanKidushLevanaBetweenMoldos(Date alos, Date tzais) {
}
/**
- * Returns the Date of the molad based time if it occurs on the current date. Since Kiddush Levana
+ * Returns the Instant of the molad based time if it occurs on the current date. Since Kiddush Levana
* can only be said during the day, there are parameters to limit it to between alos and tzais. If
* the time occurs between alos and tzais, tzais will be returned.
*
@@ -3282,15 +3087,15 @@ public Date getSofZmanKidushLevanaBetweenMoldos(Date alos, Date tzais) {
* @return the molad based time. If the zman does not occur during the current date, null will be
* returned.
*/
- private Date getMoladBasedTime(Date moladBasedTime, Date alos, Date tzais, boolean techila) {
- Date lastMidnight = getMidnightLastNight();
- Date midnightTonight = getMidnightTonight();
- if(moladBasedTime.before(lastMidnight) || moladBasedTime.after(midnightTonight)){ // Invalid time, bailout
+ private Instant getMoladBasedTime(Instant moladBasedTime, Instant alos, Instant tzais, boolean techila) {
+ Instant lastMidnight = getMidnightLastNight().toInstant();
+ Instant midnightTonight = getMidnightTonight().toInstant();
+ if(moladBasedTime.isBefore(lastMidnight) || moladBasedTime.isAfter(midnightTonight)){ // Invalid time, bailout
return null;
} else if (alos == null || tzais == null){ // Not enough info to adjust
return moladBasedTime;
} else { // It's the daytime, get the next/prev night
- if (moladBasedTime.after(alos) && moladBasedTime.before(tzais)) {
+ if (moladBasedTime.isAfter(alos) && moladBasedTime.isBefore(tzais)) {
if (techila) {
return tzais;
} else {
@@ -3308,16 +3113,16 @@ private Date getMoladBasedTime(Date moladBasedTime, Date alos, Date tzais, boole
* halfway between molad and molad. This adds half the 29 days, 12 hours and 793 chalakim time between
* molad and molad (14 days, 18 hours, 22 minutes and 666 milliseconds) to the month's molad.
* The sof zman Kiddush Levana will be returned even if it occurs during the day. To limit the time to between
- * tzais and alos, see {@link #getSofZmanKidushLevanaBetweenMoldos(Date, Date)}.
+ * tzais and alos, see {@link #getSofZmanKidushLevanaBetweenMoldos(Instant, Instant)}.
*
- * @return the Date representing the moment halfway between molad and molad. If the time occurs between
+ * @return the Instant representing the moment halfway between molad and molad. If the time occurs between
* alos and tzais, alos will be returned. If the zman will not occur on this
* day, a null will be returned.
- * @see #getSofZmanKidushLevanaBetweenMoldos(Date, Date)
+ * @see #getSofZmanKidushLevanaBetweenMoldos(Instant, Instant)
* @see #getSofZmanKidushLevana15Days()
* @see JewishCalendar#getSofZmanKidushLevanaBetweenMoldos()
*/
- public Date getSofZmanKidushLevanaBetweenMoldos() {
+ public Instant getSofZmanKidushLevanaBetweenMoldos() {
return getSofZmanKidushLevanaBetweenMoldos(null, null);
}
@@ -3326,7 +3131,7 @@ public Date getSofZmanKidushLevanaBetweenMoldos() {
* opinion brought down in the Shulchan Aruch (Orach Chaim 426). It should be noted that some opinions hold that the
* Rema who brings down the opinion of the Maharil's of calculating
- * {@link #getSofZmanKidushLevanaBetweenMoldos(Date, Date) half way between molad and molad} is of
+ * {@link #getSofZmanKidushLevanaBetweenMoldos(Instant, Instant) half way between molad and molad} is of
* the opinion that the Mechaber agrees to his opinion. Also see the Aruch Hashulchan. For additional details on the subject,
* see Rabbi Dovid Heber's very detailed write-up in Siman Daled (chapter 4) of Shaarei Zmanim. If the time of sof zman Kiddush Levana occurs during
@@ -3342,17 +3147,16 @@ public Date getSofZmanKidushLevanaBetweenMoldos() {
* tzais), the time returned will be alos. If either the alos or tzais parameters
* are null, no daytime adjustment will be made.
*
- * @return the Date representing the moment 15 days after the molad. If the time occurs between alos and
+ * @return the Instant representing the moment 15 days after the molad. If the time occurs between alos and
* tzais, alos will be returned. If the zman will not occur on this day, a
* null will be returned.
*
- * @see #getSofZmanKidushLevanaBetweenMoldos(Date, Date)
+ * @see #getSofZmanKidushLevanaBetweenMoldos(Instant, Instant)
* @see JewishCalendar#getSofZmanKidushLevana15Days()
*/
- public Date getSofZmanKidushLevana15Days(Date alos, Date tzais) {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
+ public Instant getSofZmanKidushLevana15Days(Instant alos, Instant tzais) {
+ JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate());
+
// Do not calculate for impossible dates, but account for extreme cases. In the extreme case of Rapa Iti in
// French Polynesia on Dec 2027 when kiddush Levana 3 days can be said on Rosh Chodesh, the sof zman Kiddush
// Levana will be on the 12th of the Teves. in the case of Anadyr, Russia on Jan, 2071, sof zman kiddush levana will
@@ -3368,22 +3172,22 @@ public Date getSofZmanKidushLevana15Days(Date alos, Date tzais) {
* the Shulchan Aruch (Orach Chaim 426). It should be noted that some opinions hold that the
* Rema who brings down the opinion of the Maharil's of calculating
- * {@link #getSofZmanKidushLevanaBetweenMoldos(Date, Date) half way between molad and molad} is of
+ * {@link #getSofZmanKidushLevanaBetweenMoldos(Instant, Instant) half way between molad and molad} is of
* the opinion that the Mechaber agrees to his opinion. Also see the Aruch Hashulchan. For additional details on the subject,
* See Rabbi Dovid Heber's very detailed write-up in Siman Daled (chapter 4) of Shaarei
* Zmanim. The sof zman Kiddush Levana will be returned even if it occurs during the day. To limit the time to
- * between tzais and alos, see {@link #getSofZmanKidushLevana15Days(Date, Date)}.
+ * between tzais and alos, see {@link #getSofZmanKidushLevana15Days(Instant, Instant)}.
*
- * @return the Date representing the moment 15 days after the molad. If the time occurs between
+ * @return the Instant representing the moment 15 days after the molad. If the time occurs between
* alos and tzais, alos will be returned. If the zman will not occur on this day, a
* null will be returned.
*
- * @see #getSofZmanKidushLevana15Days(Date, Date)
+ * @see #getSofZmanKidushLevana15Days(Instant, Instant)
* @see #getSofZmanKidushLevanaBetweenMoldos()
* @see JewishCalendar#getSofZmanKidushLevana15Days()
*
*/
- public Date getSofZmanKidushLevana15Days() {
+ public Instant getSofZmanKidushLevana15Days() {
return getSofZmanKidushLevana15Days(null, null);
}
@@ -3391,15 +3195,15 @@ public Date getSofZmanKidushLevana15Days() {
* Returns the earliest time of Kiddush Levana according to Rabbeinu Yonah's opinion that it can be said 3 days after the
* molad. The time will be returned even if it occurs during the day when Kiddush Levana can't be said.
- * Use {@link #getTchilasZmanKidushLevana3Days(Date, Date)} if you want to limit the time to night hours.
+ * Use {@link #getTchilasZmanKidushLevana3Days(Instant, Instant)} if you want to limit the time to night hours.
*
- * @return the Date representing the moment 3 days after the molad. If the zman will not occur on this day, a
+ * @return the Instant representing the moment 3 days after the molad. If the zman will not occur on this day, a
* null will be returned.
- * @see #getTchilasZmanKidushLevana3Days(Date, Date)
+ * @see #getTchilasZmanKidushLevana3Days(Instant, Instant)
* @see #getTchilasZmanKidushLevana7Days()
* @see JewishCalendar#getTchilasZmanKidushLevana3Days()
*/
- public Date getTchilasZmanKidushLevana3Days() {
+ public Instant getTchilasZmanKidushLevana3Days() {
return getTchilasZmanKidushLevana3Days(null, null);
}
@@ -3407,29 +3211,27 @@ public Date getTchilasZmanKidushLevana3Days() {
* Returns the earliest time of Kiddush Levana according to Rabbeinu Yonah's opinion that it can be said 3 days after the molad.
* If the time of tchilas zman Kiddush Levana occurs during the day (between alos and tzais passed to
- * this method) it will return the following tzais. If null is passed for either alos or tzais, the actual
- * tchilas zman Kiddush Levana will be returned, regardless of if it is during the day or not.
+ * this method) it will return the following tzais. If null is passed for either alos or tzais, the
+ * actual tchilas zman Kiddush Levana will be returned, regardless of if it is during the day or not.
*
* @param alos
- * the beginning of the Jewish day. If Kidush Levana occurs during the day (starting at alos and ending
- * at tzais), the time returned will be tzais. If either the alos or tzais parameters
+ * the beginning of the Jewish day. If Kidush Levana occurs during the day (starting at alos and ending at
+ * tzais), the time returned will be tzais. If either the alos or tzais parameters
* are null, no daytime adjustment will be made.
* @param tzais
* the end of the Jewish day. If Kidush Levana occurs during the day (starting at alos and ending at
* tzais), the time returned will be tzais. If either the alos or tzais parameters
* are null, no daytime adjustment will be made.
*
- * @return the Date representing the moment 3 days after the molad. If the time occurs between alos and
+ * @return the Instant representing the moment 3 days after the molad. If the time occurs between alos and
* tzais, tzais will be returned. If the zman will not occur on this day, a
* null will be returned.
* @see #getTchilasZmanKidushLevana3Days()
- * @see #getTchilasZmanKidushLevana7Days(Date, Date)
+ * @see #getTchilasZmanKidushLevana7Days(Instant, Instant)
* @see JewishCalendar#getTchilasZmanKidushLevana3Days()
*/
- public Date getTchilasZmanKidushLevana3Days(Date alos, Date tzais) {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
+ public Instant getTchilasZmanKidushLevana3Days(Instant alos, Instant tzais) {
+ JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate());
// Do not calculate for impossible dates, but account for extreme cases. Tchilas zman kiddush Levana 3 days for
// the extreme case of Rapa Iti in French Polynesia on Dec 2027 when kiddush Levana 3 days can be said on the evening
@@ -3440,12 +3242,12 @@ public Date getTchilasZmanKidushLevana3Days(Date alos, Date tzais) {
return null;
}
- Date zman = getMoladBasedTime(jewishCalendar.getTchilasZmanKidushLevana3Days(), alos, tzais, true);
+ Instant zman = getMoladBasedTime(jewishCalendar.getTchilasZmanKidushLevana3Days(), alos, tzais, true);
- //Get the following month's zman kiddush Levana for the extreme case of Rapa Iti in French Polynesia on Dec 2027 when
- // kiddush Levana can be said on Rosh Chodesh (the evening of the 30th). See Rabbi Dovid Heber's Shaarei Zmanim chapter 4 (page 32)
+ // Get the following month's zman kiddush Levana for the extreme case of Rapa Iti in French Polynesia on Dec 2027 when kiddush
+ // Levana can be said on Rosh Chodesh (the evening of the 30th). See Rabbi Dovid Heber's Shaarei Zmanim chapter 4 (page 32)
if (zman == null && jewishCalendar.getJewishDayOfMonth() == 30) {
- jewishCalendar.forward(Calendar.MONTH, 1);
+ jewishCalendar.plusMonths(1);
zman = getMoladBasedTime(jewishCalendar.getTchilasZmanKidushLevana3Days(), null, null, true);
}
@@ -3453,21 +3255,19 @@ public Date getTchilasZmanKidushLevana3Days(Date alos, Date tzais) {
}
/**
- * Returns the point in time of Molad as a Date Object. For the traditional day of week, hour,
- * minute and chalakim, {@link JewishCalendar#getMoladAsDate()} and the not yet completed
+ * Returns the point in time of Molad as a Instant Object. For the traditional day of week, hour,
+ * minute and chalakim, {@link JewishCalendar#getMoladAsInstant()} and the not yet completed
* {@link com.kosherjava.zmanim.hebrewcalendar.HebrewDateFormatter} that will have formatting for this.
*
- * @return the Date representing the moment of the molad. If the molad does not occur on this day, a
+ * @return the Instant representing the moment of the molad. If the molad does not occur on this day, a
* null will be returned.
*
* @see #getTchilasZmanKidushLevana3Days()
- * @see #getTchilasZmanKidushLevana7Days(Date, Date)
- * @see JewishCalendar#getMoladAsDate()
+ * @see #getTchilasZmanKidushLevana7Days(Instant, Instant)
+ * @see JewishCalendar#getMoladAsInstant()
*/
- public Date getZmanMolad() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
+ public Instant getZmanMolad() {
+ JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate());
// Optimize to not calculate for impossible dates, but account for extreme cases. The molad in the extreme case of Rapa
// Iti in French Polynesia on Dec 2027 occurs on the night of the 27th of Kislev. In the case of Anadyr, Russia on
@@ -3475,50 +3275,20 @@ public Date getZmanMolad() {
if (jewishCalendar.getJewishDayOfMonth() > 2 && jewishCalendar.getJewishDayOfMonth() < 27) {
return null;
}
- Date molad = getMoladBasedTime(jewishCalendar.getMoladAsDate(), null, null, true);
+ Instant molad = getMoladBasedTime(jewishCalendar.getMoladAsInstant(), null, null, true);
// deal with molad that happens on the end of the previous month
if (molad == null && jewishCalendar.getJewishDayOfMonth() > 26) {
- jewishCalendar.forward(Calendar.MONTH, 1);
- molad = getMoladBasedTime(jewishCalendar.getMoladAsDate(), null, null, true);
+ jewishCalendar.plusMonths(1);
+ molad = getMoladBasedTime(jewishCalendar.getMoladAsInstant(), null, null, true);
}
return molad;
}
-
- /**
- * Used by Molad based zmanim to determine if zmanim occur during the current day.
- * @see #getMoladBasedTime(Date, Date, Date, boolean)
- * @return previous midnight
- */
- private Date getMidnightLastNight() {
- Calendar midnight = (Calendar)getCalendar().clone();
- // reset hour, minutes, seconds and millis
- midnight.set(Calendar.HOUR_OF_DAY, 0);
- midnight.set(Calendar.MINUTE, 0);
- midnight.set(Calendar.SECOND, 0);
- midnight.set(Calendar.MILLISECOND, 0);
- return midnight.getTime();
- }
-
- /**
- * Used by Molad based zmanim to determine if zmanim occur during the current day.
- * @see #getMoladBasedTime(Date, Date, Date, boolean)
- * @return following midnight
- */
- private Date getMidnightTonight() {
- Calendar midnight = (Calendar)getCalendar().clone();
- midnight.add(Calendar.DAY_OF_YEAR, 1);//roll to tonight
- midnight.set(Calendar.HOUR_OF_DAY, 0);
- midnight.set(Calendar.MINUTE, 0);
- midnight.set(Calendar.SECOND, 0);
- midnight.set(Calendar.MILLISECOND, 0);
- return midnight.getTime();
- }
/**
* Returns the earliest time of Kiddush Levana according to the opinions that it should not be said until 7
* days after the molad. If the time of tchilas zman Kiddush Levana occurs during the day (between
- * {@link ZmanimCalendar#getAlos72() alos} and {@link ZmanimCalendar#getTzais72() tzais}) it
+ * {@link #getAlos72Minutes() alos} and {@link #getTzais72Minutes() tzais}) it
* return the next tzais.
*
* @param alos
@@ -3530,17 +3300,15 @@ private Date getMidnightTonight() {
* ending at tzais), the time returned will be tzais. If either the alos or
* tzais parameters are null, no daytime adjustment will be made.
*
- * @return the Date representing the moment 7 days after the molad. If the time occurs between alos and
+ * @return the Instant representing the moment 7 days after the molad. If the time occurs between alos and
* tzais, tzais will be returned. If the zman will not occur on this day, a
* null will be returned.
- * @see #getTchilasZmanKidushLevana3Days(Date, Date)
+ * @see #getTchilasZmanKidushLevana3Days(Instant, Instant)
* @see #getTchilasZmanKidushLevana7Days()
* @see JewishCalendar#getTchilasZmanKidushLevana7Days()
*/
- public Date getTchilasZmanKidushLevana7Days(Date alos, Date tzais) {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
+ public Instant getTchilasZmanKidushLevana7Days(Instant alos, Instant tzais) {
+ JewishCalendar jewishCalendar = new JewishCalendar(getLocalDate());
// Optimize to not calculate for impossible dates, but account for extreme cases. Tchilas zman kiddush Levana 7 days for
// the extreme case of Rapa Iti in French Polynesia on Jan 2028 (when kiddush Levana 3 days can be said on the evening
@@ -3557,15 +3325,15 @@ public Date getTchilasZmanKidushLevana7Days(Date alos, Date tzais) {
/**
* Returns the earliest time of Kiddush Levana according to the opinions that it should not be said until 7
* days after the molad. The time will be returned even if it occurs during the day when Kiddush Levana
- * can't be recited. Use {@link #getTchilasZmanKidushLevana7Days(Date, Date)} if you want to limit the time to night hours.
+ * can't be recited. Use {@link #getTchilasZmanKidushLevana7Days(Instant, Instant)} if you want to limit the time to night hours.
*
- * @return the Date representing the moment 7 days after the molad regardless of it is day or night. If the zman
+ * @return the Instant representing the moment 7 days after the molad regardless of it is day or night. If the zman
* will not occur on this day, a null will be returned.
- * @see #getTchilasZmanKidushLevana7Days(Date, Date)
+ * @see #getTchilasZmanKidushLevana7Days(Instant, Instant)
* @see JewishCalendar#getTchilasZmanKidushLevana7Days()
* @see #getTchilasZmanKidushLevana3Days()
*/
- public Date getTchilasZmanKidushLevana7Days() {
+ public Instant getTchilasZmanKidushLevana7Days() {
return getTchilasZmanKidushLevana7Days(null, null);
}
@@ -3575,201 +3343,156 @@ public Date getTchilasZmanKidushLevana7Days() {
* #getSofZmanTfilaGRA() Sof zman tfilah GRA} and is provided as a convenience method for those who are
* unaware how this zman is calculated. This time is 4 hours into the day based on the opinion of the
* GRA that the day is calculated from sunrise to sunset.
- * This returns the time 4 * {@link #getShaahZmanisGra()} after {@link #getSeaLevelSunrise() sea level sunrise}. If it
+ * This returns the time 4 * {@link #getShaahZmanisGRA()} after {@link #getSeaLevelSunrise() sea level sunrise}. If it
* is not erev Pesach, a null will be returned.
- *
- * @see ZmanimCalendar#getShaahZmanisGra()
- * @see ZmanimCalendar#getSofZmanTfilaGRA()
- * @return the Date one is allowed eating chametz on Erev Pesach. If it is not erev
+ * @return the Instant one is allowed eating 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 #getSofZmanTfilaGRA()
+ * @see #getSofZmanAchilasChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanAchilasChametzGRA() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getSofZmanTfilaGRA();
- } else {
- return null;
- }
+ public Instant getSofZmanAchilasChametzGRA() {
+ return getSofZmanAchilasChametz(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true);
}
/**
* This method returns the latest time one is allowed eating chametz on Erev Pesach according to the
* opinion of the Magen Avraham (MGA) based on alos
- * being {@link #getAlos72() 72} minutes before {@link #getSunrise() sunrise}. This time is identical to the
- * {@link #getSofZmanTfilaMGA72Minutes() Sof zman tfilah MGA 72 minutes}. This time is 4 {@link #getShaahZmanisMGA()
- * shaos zmaniyos} (temporal hours) after {@link #getAlos72() dawn} based on the opinion of the MGA that the day is
- * calculated from a {@link #getAlos72() dawn} of 72 minutes before sunrise to {@link #getTzais72() nightfall} of 72 minutes
- * after sunset. This returns the time of 4 * {@link #getShaahZmanisMGA()} after {@link #getAlos72() dawn}. If it is not
- * erev Pesach, a null will be returned.
- *
- * @return the Date of the latest time of eating chametz. If it is not erev Pesach or the
+ * being {@link #getAlos72Minutes() 72} minutes before {@link #getSunset() sunrise}. This time is identical to the
+ * {@link #getSofZmanTfilaMGA72Minutes() Sof zman tfilah MGA 72 minutes}. This time is 4 {@link
+ * #getShaahZmanis72Minutes() shaos zmaniyos} (temporal 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 4 * {@link #getShaahZmanis72Minutes()}
+ * after {@link #getAlos72Minutes() dawn}. If it is not erev Pesach, a null will be returned.
+ *
+ * @return the Instant of the latest time of eating chametz. 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 #getShaahZmanisMGA()
- * @see #getAlos72()
+ * @see #getShaahZmanis72Minutes()
+ * @see #getAlos72Minutes()
* @see #getSofZmanTfilaMGA72Minutes()
+ * @see #getSofZmanAchilasChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanAchilasChametzMGA72Minutes() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getSofZmanTfilaMGA72Minutes();
- } else {
- return null;
- }
+ public Instant getSofZmanAchilasChametzMGA72Minutes() {
+ return getSofZmanAchilasChametz(getAlos72Minutes(), getTzais72Minutes(), true);
}
/**
- * This method returns the latest time one is allowed eating chametz on Erev Pesach according to the
- * opinion of the Magen Avraham (MGA) based on alos
- * being {@link #getAlos72Zmanis() 72 zmaniyos} minutes before {@link #getSunrise() sunrise}. This time is identical to the
- * {@link #getSofZmanTfilaMGA72MinutesZmanis() Sof zman tfilah MGA 72 minutes zmanis}. This time is 4 {@link #getShaahZmanis72MinutesZmanis()
- * shaos zmaniyos} (temporal hours) after {@link #getAlos72() dawn} based on the opinion of the MGA that the day is
- * calculated from a {@link #getAlos72Zmanis() dawn} of 72 minutes zmanis before sunrise to {@link #getTzais72Zmanis() nightfall} of 72 minutes zmanis
- * after sunset. This returns the time of 4 * {@link #getShaahZmanis72MinutesZmanis()} after {@link #getAlos72Zmanis() dawn}. If it is not
- * erev Pesach, a null will be returned.
+ * This method returns the latest time one is allowed eating chametz on Erev Pesach according to the opinion
+ * of the Magen Avraham (MGA) based on alos being {@link
+ * #getAlos72Zmanis() 72 zmaniyos} minutes before {@link #getSunset() sunrise}. This time is identical to the
+ * {@link #getSofZmanTfilaMGA72MinutesZmanis() Sof zman tfilah MGA 72 minutes zmanis}. This time is 4 {@link
+ * #getShaahZmanis72MinutesZmanis() shaos zmaniyos} (temporal hours) after {@link #getAlos72Minutes() dawn} based on the
+ * opinion of the MGA that the day is calculated from a {@link #getAlos72Zmanis() dawn} of 72 minutes zmanis before sunrise to
+ * {@link #getTzais72Zmanis() nightfall} of 72 minutes zmanis after sunset. This returns the time of 4 * {@link
+ * #getShaahZmanis72MinutesZmanis()} after {@link #getAlos72Zmanis() dawn}. If it is not erev Pesach, a null will be
+ * returned.
*
- * @return the Date of the latest time of eating chametz. If it is not erev Pesach or the
+ * @return the Instant of the latest time of eating chametz. 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 #getShaahZmanis72MinutesZmanis()
* @see #getAlos72Zmanis()
* @see #getSofZmanTfilaMGA72MinutesZmanis()
+ * @see #getSofZmanAchilasChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanAchilasChametzMGA72MinutesZmanis() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getSofZmanTfilaMGA72MinutesZmanis();
- } else {
- return null;
- }
+ public Instant getSofZmanAchilasChametzMGA72MinutesZmanis() {
+ return getSofZmanAchilasChametz(getAlos72Zmanis(), getTzais72Zmanis(), true);
}
/**
* This method returns the latest time one is allowed eating chametz on Erev Pesach according to the
* opinion of the Magen Avraham (MGA) based on alos
- * being {@link #getAlos16Point1Degrees() 16.1°} before {@link #getSunrise() sunrise}. This time is 4 {@link
- * #getShaahZmanis16Point1Degrees() shaos zmaniyos} (solar hours) after {@link #getAlos16Point1Degrees() dawn}
- * based on the opinion of the MGA that the day is calculated from dawn to nightfall with both being 16.1°
- * below sunrise or sunset. This returns the time of 4 {@link #getShaahZmanis16Point1Degrees()} after
- * {@link #getAlos16Point1Degrees() dawn}. If it is not erev Pesach, a null will be returned.
- *
- * @return the Date of the latest time of eating chametz. If it is not erev Pesach or 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
+ * being {@link #getAlos16Point1Degrees() 16.1°} before {@link #getSunset() sunrise}. This time is 4 {@link
+ * #getShaahZmanis16Point1Degrees() shaos zmaniyos} (solar hours) after {@link #getAlos16Point1Degrees() dawn} based
+ * on the opinion of the MGA that the day is calculated from dawn to nightfall with both being 16.1° below sunrise or
+ * sunset. This returns the time of 4 {@link #getShaahZmanis16Point1Degrees()} after {@link #getAlos16Point1Degrees() dawn}.
+ * If it is not erev Pesach, a null will be returned.
+ *
+ * @return the Instant of the latest time of eating chametz. If it is not erev Pesach or 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 #getShaahZmanis16Point1Degrees()
* @see #getAlos16Point1Degrees()
* @see #getSofZmanTfilaMGA16Point1Degrees()
+ * @see #getSofZmanAchilasChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanAchilasChametzMGA16Point1Degrees() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getSofZmanTfilaMGA16Point1Degrees();
- } else {
- return null;
- }
+ public Instant getSofZmanAchilasChametzMGA16Point1Degrees() {
+ return getSofZmanAchilasChametz(getAlos16Point1Degrees(), getTzais16Point1Degrees(), true);
}
/**
- * FIXME adjust for 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
+ * 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.
- * @see ZmanimCalendar#getShaahZmanisGra()
- * @return the Date of the latest time for burning chametz on Erev Pesach. If it is not
+ * @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)
*/
- public Date getSofZmanBiurChametzGRA() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getTimeOffset(getElevationAdjustedSunrise(), getShaahZmanisGra() * 5);
- } else {
- return null;
- }
+ public Instant getSofZmanBiurChametzGRA() {
+ return getSofZmanBiurChametz(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true);
}
/**
- * FIXME adjust for synchronous
- * This method returns the latest time for burning chametz on Erev Pesach according to the opinion of
- * the Magen Avraham (MGA) based on alos
- * being {@link #getAlos72() 72} minutes before {@link #getSunrise() sunrise}. This time is 5 {@link
- * #getShaahZmanisMGA() shaos zmaniyos} (temporal hours) after {@link #getAlos72() dawn} based on the opinion of
- * the MGA that the day is calculated from a {@link #getAlos72() dawn} of 72 minutes before sunrise to {@link
- * #getTzais72() nightfall} of 72 minutes after sunset. This returns the time of 5 * {@link #getShaahZmanisMGA()} after
- * {@link #getAlos72() dawn}. If it is not erev Pesach, a null will be returned.
- * @return the Date of the latest time for burning chametz on Erev Pesach. If it is not
+ * This method returns the latest time for burning chametz on Erev Pesach according to the opinion of the
+ * Magen Avraham (MGA) based on alos being {@link
+ * #getAlos72Minutes() 72} minutes before {@link #getSunset() sunrise}. This time is 5 {@link
+ * #getShaahZmanis72Minutes() shaos zmaniyos} (temporal 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 5 * {@link #getShaahZmanis72Minutes()}
+ * after {@link #getAlos72Minutes() dawn}. 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 #getShaahZmanisMGA()
- * @see #getAlos72()
- */
- public Date getSofZmanBiurChametzMGA72Minutes() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getTimeOffset(getAlos72(), getShaahZmanisMGA() * 5);
- } else {
- return null;
- }
+ * @see #getShaahZmanis72Minutes()
+ * @see #getAlos72Minutes()
+ * @see #getSofZmanBiurChametz(Instant, Instant, boolean)
+ */
+ public Instant getSofZmanBiurChametzMGA72Minutes() {
+ return getSofZmanBiurChametz(getAlos72Minutes(), getTzais72Minutes(), true);
}
/**
- * FIXME adjust for synchronous
- * This method returns the latest time for burning chametz on Erev Pesach according to the opinion of
- * the Magen Avraham (MGA) based on alos
- * being {@link #getAlos72Zmanis() 72} minutes zmanis before {@link #getSunrise() sunrise}. This time is 5 {@link
- * #getShaahZmanis72MinutesZmanis() shaos zmaniyos} (temporal hours) after {@link #getAlos72Zmanis() dawn} based on the opinion of
- * the MGA that the day is calculated from a {@link #getAlos72Zmanis() dawn} of 72 minutes zmanis before sunrise to {@link
- * #getTzais72Zmanis() nightfall} of 72 minutes zmanis after sunset. This returns the time of 5 * {@link #getShaahZmanis72MinutesZmanis()} after
- * {@link #getAlos72Zmanis() dawn}. If it is not erev Pesach, a null will be returned.
- * @return the Date of the latest time for burning chametz on Erev Pesach. If it is not
+ * This method returns the latest time for burning chametz on Erev Pesach according to the opinion of the
+ * Magen Avraham (MGA) based on alos being {@link
+ * #getAlos72Zmanis() 72} minutes zmanis before {@link #getSunset() sunrise}. This time is 5 {@link
+ * #getShaahZmanis72MinutesZmanis() shaos zmaniyos} (temporal hours) after {@link #getAlos72Zmanis() dawn} based on the
+ * opinion of the MGA that the day is calculated from a {@link #getAlos72Zmanis() dawn} of 72 minutes zmanis before sunrise to
+ * {@link #getTzais72Zmanis() nightfall} of 72 minutes zmanis after sunset. This returns the time of 5 * {@link
+ * #getShaahZmanis72MinutesZmanis()} after {@link #getAlos72Zmanis() dawn}. 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 #getShaahZmanis72MinutesZmanis()
* @see #getAlos72Zmanis()
+ * @see #getSofZmanBiurChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanBiurChametzMGA72MinutesZmanis() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getTimeOffset(getAlos72Zmanis(), getShaahZmanis72MinutesZmanis() * 5);
- } else {
- return null;
- }
+ public Instant getSofZmanBiurChametzMGA72MinutesZmanis() {
+ return getSofZmanBiurChametz(getAlos72Zmanis(), getTzais72Zmanis(), true);
}
/**
- * FIXME adjust for synchronous
* This method returns the latest time for burning chametz on Erev Pesach according to the opinion
* of the Magen Avraham (MGA) based on alos
- * being {@link #getAlos16Point1Degrees() 16.1°} before {@link #getSunrise() sunrise}. This time is 5
+ * being {@link #getAlos16Point1Degrees() 16.1°} before {@link #getSunset() sunrise}. This time is 5
* {@link #getShaahZmanis16Point1Degrees() shaos zmaniyos} (solar hours) after {@link #getAlos16Point1Degrees()
* dawn} based on the opinion of the MGA that the day is calculated from dawn to nightfall with both being 16.1°
* below sunrise or sunset. This returns the time of 5 {@link #getShaahZmanis16Point1Degrees()} after
* {@link #getAlos16Point1Degrees() dawn}. If it is not erev Pesach, a null will be returned.
- * @return the Date of the latest time for burning chametz on Erev Pesach. If it is not
+ * @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 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
@@ -3777,95 +3500,20 @@ public Date getSofZmanBiurChametzMGA72MinutesZmanis() {
*
* @see #getShaahZmanis16Point1Degrees()
* @see #getAlos16Point1Degrees()
+ * @see #getSofZmanBiurChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanBiurChametzMGA16Point1Degrees() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getTimeOffset(getAlos16Point1Degrees(), getShaahZmanis16Point1Degrees() * 5);
- } else {
- return null;
- }
+ public Instant getSofZmanBiurChametzMGA16Point1Degrees() {
+ return getSofZmanBiurChametz(getAlos16Point1Degrees(), getTzais16Point1Degrees(), true);
}
/**
* 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 Date 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 #getSunrise()
- * @see #getSeaLevelSunrise()
- * @see #getSunsetBaalHatanya()
- * @see #ZENITH_1_POINT_583
- */
- private Date 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 Date 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 #getSunset()
- * @see #getSeaLevelSunset()
- * @see #getSunriseBaalHatanya()
- * @see #ZENITH_1_POINT_583
- */
- private Date getSunsetBaalHatanya() {
- return getSunsetOffsetByDegrees(ZENITH_1_POINT_583);
- }
-
- /**
- * A method that returns the Baal Hatanya's
- * a shaah zmanis ({@link #getTemporalHour(Date, Date) temporal hour}). This forms the base for the
+ * a shaah zmanis ({@link #getTemporalHour(Instant, Instant) temporal hour}). This forms the base for the
* Baal Hatanya's day based calculations that are calculated as a 1.583° 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.
- * A method that returns a shaah zmanis ({@link #getTemporalHour(Date, Date) temporal hour}) calculated
+ * A method that returns a shaah zmanis ({@link #getTemporalHour(Instant, Instant) temporal hour}) calculated
* based on the Baal Hatanya's netz
* amiti and shkiah amiti using a dip of 1.583° below the sea level horizon. This calculation divides
* the day based on the opinion of the Baal Hatanya that the day runs from {@link #getSunriseBaalHatanya() netz amiti}
@@ -3879,10 +3527,10 @@ private Date getSunsetBaalHatanya() {
* 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 #getTemporalHour(Instant, Instant)
* @see #getSunriseBaalHatanya()
* @see #getSunsetBaalHatanya()
- * @see #ZENITH_1_POINT_583
+ * @see ZENITH_1_POINT_583
*/
public long getShaahZmanisBaalHatanya() {
return getTemporalHour(getSunriseBaalHatanya(), getSunsetBaalHatanya());
@@ -3890,16 +3538,20 @@ public long getShaahZmanisBaalHatanya() {
/**
* Returns the Baal Hatanya's alos
- * (dawn) calculated as the time when the sun is 16.9° below the eastern {@link #GEOMETRIC_ZENITH geometric horizon}
- * before {@link #getSunrise() sunrise}. For more information the source of 16.9° see {@link #ZENITH_16_POINT_9}.
+ * (dawn) calculated as the time when the sun is 16.9° below the eastern {@link GEOMETRIC_ZENITH geometric horizon}
+ * before {@link #getSunset() sunrise}. It is based on the calculation that the time between dawn and
+ * netz amiti (sunrise) is 72 minutes, the time that is takes to walk 4 mil at 18 minutes
+ * a mil (Rambam and others). The sun's position at 72
+ * minutes before {@link #getSunriseBaalHatanya netz amiti (sunrise)} in Jerusalem around the equinox / equilux is
+ * 16.9° below {@link GEOMETRIC_ZENITH geometric zenith}.
*
- * @see #ZENITH_16_POINT_9
- * @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 getAlosBaalHatanya() {
+ public Instant getAlosBaalHatanya() {
return getSunriseOffsetByDegrees(ZENITH_16_POINT_9);
}
@@ -3910,14 +3562,14 @@ public Date getAlosBaalHatanya() {
* sunrise to sunset. This returns the time 3 * {@link #getShaahZmanisBaalHatanya()} after {@link #getSunriseBaalHatanya()
* netz amiti (sunrise)}.
*
- * @see ZmanimCalendar#getSofZmanShma(Date, Date)
+ * @see #getSofZmanShma(Instant, Instant)
* @see #getShaahZmanisBaalHatanya()
- * @return the Date of the latest zman shema according to the Baal Hatanya. If the calculation
+ * @return the Instant of the latest zman shema according to the Baal Hatanya. 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 getSofZmanShmaBaalHatanya() {
+ public Instant getSofZmanShmaBaalHatanya() {
return getSofZmanShma(getSunriseBaalHatanya(), getSunsetBaalHatanya(), true);
}
@@ -3927,14 +3579,14 @@ public Date getSofZmanShmaBaalHatanya() {
* calculated from sunrise to sunset. This returns the time 4 * {@link #getShaahZmanisBaalHatanya()} after
* {@link #getSunriseBaalHatanya() netz amiti (sunrise)}.
*
- * @see ZmanimCalendar#getSofZmanTfila(Date, Date)
+ * @see #getSofZmanTfila(Instant, Instant)
* @see #getShaahZmanisBaalHatanya()
- * @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 getSofZmanTfilaBaalHatanya() {
+ public Instant getSofZmanTfilaBaalHatanya() {
return getSofZmanTfila(getSunriseBaalHatanya(), getSunsetBaalHatanya(), true);
}
@@ -3945,22 +3597,16 @@ public Date getSofZmanTfilaBaalHatanya() {
* is calculated from sunrise to sunset. This returns the time 4 {@link #getShaahZmanisBaalHatanya()} after
* {@link #getSunriseBaalHatanya() netz amiti (sunrise)}. If it is not erev Pesach, a null will be
* returned.
- * @see #getShaahZmanisBaalHatanya()
- * @see #getSofZmanTfilaBaalHatanya()
- * @return the Date one is allowed eating chametz on Erev Pesach. If it is not erev
+ * @return the Instant one is allowed eating 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 #getShaahZmanisBaalHatanya()
+ * @see #getSofZmanTfilaBaalHatanya()
+ * @see #getSofZmanAchilasChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanAchilasChametzBaalHatanya() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getSofZmanTfilaBaalHatanya();
- } else {
- return null;
- }
+ public Instant getSofZmanAchilasChametzBaalHatanya() {
+ return getSofZmanAchilasChametz(getSunriseBaalHatanya(), getSunsetBaalHatanya(), true);
}
/**
@@ -3968,21 +3614,15 @@ public Date getSofZmanAchilasChametzBaalHatanya() {
* the Baal Hatanya. This time is 5 hours into the day based on the opinion of the Baal Hatanya that the day is calculated
* from sunrise to sunset. This returns the time 5 * {@link #getShaahZmanisBaalHatanya()} after
* {@link #getSunriseBaalHatanya() netz amiti (sunrise)}. If it is not erev Pesach, a null will be returned.
- * @see #getShaahZmanisBaalHatanya()
- * @return the Date of the latest time for burning chametz on Erev Pesach. If it is not
+ * @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 #getShaahZmanisBaalHatanya()
+ * @see #getSofZmanBiurChametz(Instant, Instant, boolean)
*/
- public Date getSofZmanBiurChametzBaalHatanya() {
- JewishCalendar jewishCalendar = new JewishCalendar();
- jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH),
- getCalendar().get(Calendar.DAY_OF_MONTH));
- if (jewishCalendar.getJewishMonth() == JewishCalendar.NISSAN && jewishCalendar.getJewishDayOfMonth() == 14) {
- return getTimeOffset(getSunriseBaalHatanya(), getShaahZmanisBaalHatanya() * 5);
- } else {
- return null;
- }
+ public Instant getSofZmanBiurChametzBaalHatanya() {
+ return getSofZmanBiurChametz(getSunriseBaalHatanya(), getSunsetBaalHatanya(), true);
}
/**
@@ -3997,43 +3637,20 @@ public Date getSofZmanBiurChametzBaalHatanya() {
* on the opinion of the Baal Hatanya that the day is calculated from sunrise to sunset. This returns the time 6.5
* * {@link #getShaahZmanisBaalHatanya()} after {@link #getSunriseBaalHatanya() netz amiti ("real" sunrise)}.
* @todo Consider adjusting this to calculate the time as 30 clock or zmaniyos minutes 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()}.
- * @see #getMinchaGedola(Date, Date)
+ * getSunTransit() astronomical chatzos} or {@link #getChatzosHayomAsHalfDay() chatzos as half a
+ * day} for {@link AstronomicalCalculator calculators} that support it, based on {@link #isUseAstronomicalChatzos()}.
+ * @see #getMinchaGedola(Instant, Instant)
* @see #getShaahZmanisBaalHatanya()
* @see #getMinchaKetanaBaalHatanya()
- * @return the Date of the time of mincha gedola according to the Baal Hatanya. If the calculation
+ * @return the Instant of the time of mincha gedola according to the Baal Hatanya. 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 getMinchaGedolaBaalHatanya() {
+ public Instant getMinchaGedolaBaalHatanya() {
return getMinchaGedola(getSunriseBaalHatanya(), getSunsetBaalHatanya(), true);
}
- /**
- * FIXME synchronous
- * This is a convenience method that returns the later of {@link #getMinchaGedolaBaalHatanya()} and
- * {@link #getMinchaGedola30Minutes()}. In the winter when 1/2 of a {@link #getShaahZmanisBaalHatanya()
- * shaah zmanis} is less than 30 minutes {@link #getMinchaGedola30Minutes()} will be returned, otherwise
- * {@link #getMinchaGedolaBaalHatanya()} will be returned.
- * @todo Consider adjusting this to calculate the time as 30 clock or zmaniyos minutes 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()}.
- * @return the Date of the later of {@link #getMinchaGedolaBaalHatanya()} and {@link #getMinchaGedola30Minutes()}.
- * 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 getMinchaGedolaBaalHatanyaGreaterThan30() {
- if (getMinchaGedola30Minutes() == null || getMinchaGedolaBaalHatanya() == null) {
- return null;
- } else {
- return getMinchaGedola30Minutes().compareTo(getMinchaGedolaBaalHatanya()) > 0 ? getMinchaGedola30Minutes()
- : getMinchaGedolaBaalHatanya();
- }
- }
-
/**
* This method returns the time of mincha ketana. This is the preferred earliest time to pray
* mincha in the opinion of the Rambam and others.
@@ -4043,46 +3660,58 @@ public Date getMinchaGedolaBaalHatanyaGreaterThan30() {
* day is calculated from sunrise to sunset. This returns the time 9.5 * {@link #getShaahZmanisBaalHatanya()} after {@link
* #getSunriseBaalHatanya() netz amiti (sunrise)}.
*
- * @see #getMinchaKetana(Date, Date)
+ * @see #getMinchaKetana(Instant, Instant)
* @see #getShaahZmanisBaalHatanya()
* @see #getMinchaGedolaBaalHatanya()
- * @return the Date of the time of mincha ketana. If the calculation can't be computed such as
+ * @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 getMinchaKetanaBaalHatanya() {
+ public Instant getMinchaKetanaBaalHatanya() {
return getMinchaKetana(getSunriseBaalHatanya(), getSunsetBaalHatanya(), true);
}
/**
- * This method returns the time of plag hamincha. This is calculated as 10.75 hours after sunrise. This
- * calculation is based on the opinion of the Baal Hatanya that the day is calculated
- * from sunrise to sunset. This returns the time 10.75 * {@link #getShaahZmanisBaalHatanya()} after
- * {@link #getSunriseBaalHatanya() netz amiti (sunrise)}.
+ * This method returns the time of plag hamincha. This is calculated as 10.75 hours after sunrise. This calculation
+ * is based on the opinion of the Baal Hatanya that the day is calculated from sunrise to sunset. This returns the time
+ * 10.75 * {@link #getShaahZmanisBaalHatanya()} after {@link #getSunriseBaalHatanya() netz amiti (sunrise)}. See
+ * About Our
+ * Zmanim Calculations @ Chabad.org for more details on this calculation.
*
- * @see #getPlagHamincha(Date, Date)
- * @return the Date of the time of plag hamincha. If the calculation can't be computed such as
+ * @see #getPlagHamincha(Instant, Instant)
+ * @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 getPlagHaminchaBaalHatanya() {
+ public Instant getPlagHaminchaBaalHatanya() {
return getPlagHamincha(getSunriseBaalHatanya(), getSunsetBaalHatanya(), true);
}
/**
- * A method that returns tzais (nightfall) when the sun is 6° below the western geometric horizon
- * (90°) after {@link #getSunset() sunset}. For information on the source of this calculation see
- * {@link #ZENITH_6_DEGREES}.
- *
- * @return The Date of nightfall. If the calculation can't be computed such as northern and southern
+ * A method that returns tzais (nightfall) when the sun is 6° below the western geometric horizon (90°)
+ * after {@link #getSunset() sunset}. This tzais / nightfall based on the opinion of the Baal Hatanya. This calculation is based on the position of the
+ * sun about 24 minutes after {@link #getSeaLevelSunset() sunset} in Jerusalem around the equinox / equilux, which
+ * is 6° below {@link GEOMETRIC_ZENITH geometric zenith}. See About Our Zmanim
+ * Calculations @ Chabad.org that is based on {@link #getSunsetBaalHatanya() shkiah amitis as
+ * 1.583° below the horizon} calculated around the equinox / equilux that computes 3.516 minutes after sunset. To this, 18 minutes of 3/4 of a 24-minute mil and
+ * two minutes for bain hashmashos of Rav Yosi is added. This calculation computes the the sun being 5.83° below
+ * the horizon (very close to the slightly later {@link #getTzaisGeonim5Point95Degrees()} that was calculated based on 4 fixed
+ * minutes) and it is rounded up to 6°.
+ *
+ * @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_6_DEGREES
+ * @see #getTzaisGeonim5Point95Degrees()
+ * @see #getSunsetBaalHatanya()
*/
- public Date getTzaisBaalHatanya() {
+ public Instant getTzaisBaalHatanya() {
return getSunsetOffsetByDegrees(ZENITH_6_DEGREES);
}
@@ -4091,39 +3720,39 @@ public Date getTzaisBaalHatanya() {
* calculation of sof zman krias shema (latest time to recite Shema in the morning) according to the
* opinion of the Magen Avraham (MGA) that the
* day is calculated from dawn to nightfall, but calculated using the first half of the day only. The half a day starts
- * at alos defined as {@link #getAlos18Degrees() 18°} and ends at {@link #getFixedLocalChatzos() fixed local
+ * at alos defined as {@link #getAlos18Degrees() 18°} and ends at {@link #getFixedLocalChatzosHayom() fixed local
* chatzos}. Sof Zman Shema is 3 shaos zmaniyos (solar hours) after alos or half of this half-day.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getAlos18Degrees()
- * @see #getFixedLocalChatzos()
- * @see ZmanimCalendar#getHalfDayBasedZman(Date, Date, double)
+ * @see #getFixedLocalChatzosHayom()
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getSofZmanShmaMGA18DegreesToFixedLocalChatzos() {
- return getHalfDayBasedZman(getAlos18Degrees(), getFixedLocalChatzos(), 3);
+ public Instant getSofZmanShmaMGA18DegreesToFixedLocalChatzos() {
+ return getHalfDayBasedZman(getAlos18Degrees(), getFixedLocalChatzosHayom(), 3);
}
/**
* This method returns Rav Moshe Feinstein's opinion of the
* calculation of sof zman krias shema (latest time to recite Shema in the morning) according to the
- * opinion of the Magen Avraham (MGA) that the
- * day is calculated from dawn to nightfall, but calculated using the first half of the day only. The half a day starts
- * at alos defined as {@link #getAlos16Point1Degrees() 16.1°} and ends at {@link #getFixedLocalChatzos() fixed local
- * chatzos}. Sof Zman Shema is 3 shaos zmaniyos (solar hours) after this alos or half of this half-day.
+ * opinion of the Magen Avraham (MGA) that the day is calculated
+ * from dawn to nightfall, but calculated using the first half of the day only. The half a day starts at alos defined
+ * as {@link #getAlos16Point1Degrees() 16.1°} and ends at {@link #getFixedLocalChatzosHayom() fixed local chatzos}. Sof Zman
+ * Shema is 3 shaos zmaniyos (solar hours) after this alos or half of this half-day.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getAlos16Point1Degrees()
- * @see #getFixedLocalChatzos()
- * @see #getHalfDayBasedZman(Date, Date, double)
+ * @see #getFixedLocalChatzosHayom()
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos() {
- return getHalfDayBasedZman(getAlos16Point1Degrees(), getFixedLocalChatzos(), 3);
+ public Instant getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos() {
+ return getHalfDayBasedZman(getAlos16Point1Degrees(), getFixedLocalChatzosHayom(), 3);
}
/**
@@ -4131,20 +3760,20 @@ public Date getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos() {
* calculation of sof zman krias shema (latest time to recite Shema in the morning) according to the
* opinion of the Magen Avraham (MGA) that the
* day is calculated from dawn to nightfall, but calculated using the first half of the day only. The half a day starts
- * at alos defined as {@link #getAlos90() 90 minutes before sunrise} and ends at {@link #getFixedLocalChatzos()
+ * at alos defined as {@link #getAlos90Minutes() 90 minutes before sunrise} and ends at {@link #getFixedLocalChatzosHayom()
* fixed local chatzos}. Sof Zman Shema is 3 shaos zmaniyos (solar hours) after this alos or
* half of this half-day.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getAlos90()
- * @see #getFixedLocalChatzos()
- * @see #getHalfDayBasedZman(Date, Date, double)
+ * @see #getAlos90Minutes()
+ * @see #getFixedLocalChatzosHayom()
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getSofZmanShmaMGA90MinutesToFixedLocalChatzos() {
- return getHalfDayBasedZman(getAlos90(), getFixedLocalChatzos(), 3);
+ public Instant getSofZmanShmaMGA90MinutesToFixedLocalChatzos() {
+ return getHalfDayBasedZman(getAlos90Minutes(), getFixedLocalChatzosHayom(), 3);
}
/**
@@ -4152,40 +3781,40 @@ public Date getSofZmanShmaMGA90MinutesToFixedLocalChatzos() {
* calculation of sof zman krias shema (latest time to recite Shema in the morning) according to the
* opinion of the Magen Avraham (MGA) that the
* day is calculated from dawn to nightfall, but calculated using the first half of the day only. The half a day starts
- * at alos defined as {@link #getAlos72() 72 minutes before sunrise} and ends at {@link #getFixedLocalChatzos()
+ * at alos defined as {@link #getAlos72Minutes() 72 minutes before sunrise} and ends at {@link #getFixedLocalChatzosHayom()
* fixed local chatzos}. Sof Zman Shema is 3 shaos zmaniyos (solar hours) after this alos or
* half of this half-day.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getAlos72()
- * @see #getFixedLocalChatzos()
- * @see #getHalfDayBasedZman(Date, Date, double)
+ * @see #getAlos72Minutes()
+ * @see #getFixedLocalChatzosHayom()
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getSofZmanShmaMGA72MinutesToFixedLocalChatzos() {
- return getHalfDayBasedZman(getAlos72(), getFixedLocalChatzos(), 3);
+ public Instant getSofZmanShmaMGA72MinutesToFixedLocalChatzos() {
+ return getHalfDayBasedZman(getAlos72Minutes(), getFixedLocalChatzosHayom(), 3);
}
/**
* This method returns Rav Moshe Feinstein's opinion of the
- * calculation of sof zman krias shema (latest time to recite Shema in the morning) according to the
- * opinion of the GRA that the day is calculated from
- * sunrise to sunset, but calculated using the first half of the day only. The half a day starts at {@link #getSunrise()
- * sunrise} and ends at {@link #getFixedLocalChatzos() fixed local chatzos}. Sof zman Shema is 3 shaos
- * zmaniyos (solar hours) after sunrise or half of this half-day.
+ * calculation of sof zman krias shema (latest time to recite Shema in the morning) according to the opinion
+ * of the GRA that the day is calculated from sunrise to sunset, but
+ * calculated using the first half of the day only. The half a day starts at {@link #getSunset() sunrise} and
+ * ends at {@link #getFixedLocalChatzosHayom() fixed local chatzos}. Sof zman Shema is 3 shaos zmaniyos (solar
+ * hours) after sunrise or half of this half-day.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getSunrise()
- * @see #getFixedLocalChatzos()
- * @see #getHalfDayBasedZman(Date, Date, double)
+ * @see #getSunset()
+ * @see #getFixedLocalChatzosHayom()
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getSofZmanShmaGRASunriseToFixedLocalChatzos() {
- return getHalfDayBasedZman(getElevationAdjustedSunrise(), getFixedLocalChatzos(), 3);
+ public Instant getSofZmanShmaGRASunriseToFixedLocalChatzos() {
+ return getHalfDayBasedZman(getSunriseBasedOnElevationSetting(), getFixedLocalChatzosHayom(), 3);
}
/**
@@ -4193,38 +3822,38 @@ public Date getSofZmanShmaGRASunriseToFixedLocalChatzos() {
* calculation of sof zman tfila (zman tfilah (the latest time to recite the morning prayers))
* according to the opinion of the GRA that the day is
* calculated from sunrise to sunset, but calculated using the first half of the day only. The half a day starts at
- * {@link #getSunrise() sunrise} and ends at {@link #getFixedLocalChatzos() fixed local chatzos}. Sof zman tefila
- * is 4 shaos zmaniyos (solar hours) after sunrise or 2/3 of this half-day.
+ * {@link #getSunset() sunrise} and ends at {@link #getFixedLocalChatzosHayom() fixed local chatzos}. Sof zman
+ * tefila is 4 shaos zmaniyos (solar hours) after sunrise or 2/3 of this half-day.
*
- * @return the Date of the latest zman krias shema. If the calculation can't be computed such
+ * @return the Instant of the latest zman krias shema. 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 #getSunrise()
- * @see #getFixedLocalChatzos()
- * @see #getHalfDayBasedZman(Date, Date, double)
+ * @see #getSunset()
+ * @see #getFixedLocalChatzosHayom()
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getSofZmanTfilaGRASunriseToFixedLocalChatzos() {
- return getHalfDayBasedZman(getElevationAdjustedSunrise(), getFixedLocalChatzos(), 4);
+ public Instant getSofZmanTfilaGRASunriseToFixedLocalChatzos() {
+ return getHalfDayBasedZman(getSunriseBasedOnElevationSetting(), getFixedLocalChatzosHayom(), 4);
}
/**
* This method returns Rav Moshe Feinstein's opinion of
* the calculation of mincha gedola, the earliest time one can pray mincha according to theGRA calculated as 30 minutes after {@link #getFixedLocalChatzos() fixed
+ * "https://en.wikipedia.org/wiki/Vilna_Gaon">GRA calculated as 30 minutes after {@link #getFixedLocalChatzosHayom() fixed
* local chatzos}.
*
- * @return the Date of the time of mincha gedola. If the calculation can't be computed such as
+ * @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.
*
- * @see #getMinchaGedola()
- * @see #getFixedLocalChatzos()
+ * @see #getMinchaGedolaGRA()
+ * @see #getFixedLocalChatzosHayom()
* @see #getMinchaKetanaGRAFixedLocalChatzosToSunset
*/
- public Date getMinchaGedolaGRAFixedLocalChatzos30Minutes() {
- return getTimeOffset(getFixedLocalChatzos(), MINUTE_MILLIS * 30);
+ public Instant getMinchaGedolaGRAFixedLocalChatzos30Minutes() {
+ return getTimeOffset(getFixedLocalChatzosHayom(), MINUTE_MILLIS * 30);
}
/**
@@ -4232,41 +3861,41 @@ public Date getMinchaGedolaGRAFixedLocalChatzos30Minutes() {
* of the calculation of mincha ketana (the preferred time to recite the mincha prayers according to
* the opinion of the Rambam and others) calculated according
* to the GRA that is 3.5 shaos zmaniyos (solar
- * hours) after {@link #getFixedLocalChatzos() fixed local chatzos}.
+ * hours) after {@link #getFixedLocalChatzosHayom() fixed local chatzos}.
*
- * @return the Date of the time of mincha gedola. If the calculation can't be computed such as
+ * @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.
*
- * @see #getMinchaGedola()
- * @see #getFixedLocalChatzos()
+ * @see #getMinchaGedolaGRA()
+ * @see #getFixedLocalChatzosHayom()
* @see #getMinchaGedolaGRAFixedLocalChatzos30Minutes
- * @see ZmanimCalendar#getHalfDayBasedZman(Date, Date, double)
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getMinchaKetanaGRAFixedLocalChatzosToSunset() {
- return getHalfDayBasedZman(getFixedLocalChatzos(), getElevationAdjustedSunset(), 3.5);
+ public Instant getMinchaKetanaGRAFixedLocalChatzosToSunset() {
+ return getHalfDayBasedZman(getFixedLocalChatzosHayom(), getSunsetBasedOnElevationSetting(), 3.5);
}
/**
* This method returns Rav Moshe Feinstein's opinion
* of the calculation of plag hamincha. This method returns plag hamincha calculated according to the
* GRA that the day ends at sunset and is 4.75 shaos
- * zmaniyos (solar hours) after {@link #getFixedLocalChatzos() fixed local chatzos}.
+ * zmaniyos (solar hours) after {@link #getFixedLocalChatzosHayom() fixed local chatzos}.
*
- * @return the Date of the time of mincha gedola. If the calculation can't be computed such as
+ * @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.
*
- * @see #getPlagHamincha()
- * @see #getFixedLocalChatzos()
+ * @see #getPlagHaminchaGRA()
+ * @see #getFixedLocalChatzosHayom()
* @see #getMinchaKetanaGRAFixedLocalChatzosToSunset
* @see #getMinchaGedolaGRAFixedLocalChatzos30Minutes
- * @see ZmanimCalendar#getHalfDayBasedZman(Date, Date, double)
+ * @see #getHalfDayBasedZman(Instant, Instant, double)
*/
- public Date getPlagHaminchaGRAFixedLocalChatzosToSunset() {
- return getHalfDayBasedZman(getFixedLocalChatzos(), getElevationAdjustedSunset(), 4.75);
+ public Instant getPlagHaminchaGRAFixedLocalChatzosToSunset() {
+ return getHalfDayBasedZman(getFixedLocalChatzosHayom(), getSunsetBasedOnElevationSetting(), 4.75);
}
/**
@@ -4275,76 +3904,143 @@ public Date getPlagHaminchaGRAFixedLocalChatzosToSunset() {
* tzais (nightfall) based on the opinion of Rabbi Moshe Feinstein for the New York area. This time should
* not be used for latitudes other than ones similar to the latitude of the NY area.
*
- * @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 getTzais50() {
- return getTimeOffset(getElevationAdjustedSunset(), 50 * MINUTE_MILLIS);
+ public Instant getTzais50Minutes() {
+ return getTimeOffset(getSunsetBasedOnElevationSetting(), 50 * MINUTE_MILLIS);
}
/**
* A method for calculating samuch lemincha ketana, / near mincha ketana time that is half an hour before
- * {@link #getMinchaKetana()} or is 9 * shaos zmaniyos (solar hours) after the start of
+ * {@link #getMinchaKetanaGRA()} or is 9 * shaos zmaniyos (solar hours) after the start of
* the day, calculated according to the GRA using a day starting at
* sunrise and ending at sunset. This is the time that eating or other activity can't begin prior to praying mincha.
- * The calculation used is 9 * {@link #getShaahZmanisGra()} after {@link #getSunrise() sunrise} or {@link
- * #getElevationAdjustedSunrise() elevation adjusted sunrise} (depending on the {@link #isUseElevation()} setting). See the
+ * The calculation used is 9 * {@link #getShaahZmanisGRA()} after {@link #getSunset() sunrise} or {@link
+ * #getSunriseBasedOnElevationSetting() elevation adjusted sunrise} (depending on the {@link #isUseElevation()} setting). See the
* Mechaber and Mishna Berurah 232 and 249:2.
*
- * @see #getShaahZmanisGra()
- * @see #getSamuchLeMinchaKetana(Date, Date, boolean)
+ * @see #getShaahZmanisGRA()
+ * @see #getSamuchLeMinchaKetana(Instant, Instant, boolean)
* @see #isUseAstronomicalChatzosForOtherZmanim()
- * @return the Date of the time of samuch lemincha ketana. If the calculation can't be computed such
+ * @return the Instant of the time of samuch lemincha ketana. 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 getSamuchLeMinchaKetanaGRA() {
- return getSamuchLeMinchaKetana(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true);
+ public Instant getSamuchLeMinchaKetanaGRA() {
+ return getSamuchLeMinchaKetana(getSunriseBasedOnElevationSetting(), getSunsetBasedOnElevationSetting(), true);
}
/**
*
* A method for calculating samuch lemincha ketana, / near mincha ketana time that is half an hour before
- * {@link #getMinchaKetana()} or is 9 * shaos zmaniyos (solar hours) after the start of the day, calculated based
+ * {@link #getMinchaKetanaGRA()} or is 9 * shaos zmaniyos (solar hours) after the start of the day, calculated based
* on a day from and ending a day starting at {@link #getMinchaGedola16Point1Degrees() alos 16.1°} and ending
- * at {@link #getTzais72() tzais 16.1°}. This is the time that eating or other activity can't begin prior to praying
- * mincha. The calculation used is 9 * {@link #getShaahZmanis16Point1Degrees()} after {@link #getAlos16Point1Degrees()
- * alos 16.1°}. See the Mechaber and Mishna
- * Berurah 232 and 249:2.
+ * at {@link #getTzais72Minutes() tzais 16.1°}. This is the time that eating or other activity can't begin prior to
+ * praying mincha. The calculation used is 9 * {@link #getShaahZmanis16Point1Degrees()} after {@link
+ * #getAlos16Point1Degrees() alos 16.1°}. See the Mechaber and Mishna Berurah 232 and 249:2.
*
- * @see #getSamuchLeMinchaKetana(Date, Date, boolean)
+ * @see #getSamuchLeMinchaKetana(Instant, Instant, boolean)
* @see #getShaahZmanis16Point1Degrees()
- * @return the Date of the time of samuch lemincha ketana. If the calculation can't be computed such
+ * @return the Instant of the time of samuch lemincha ketana. 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 getSamuchLeMinchaKetana16Point1Degrees() {
+ public Instant getSamuchLeMinchaKetana16Point1Degrees() {
return getSamuchLeMinchaKetana(getAlos16Point1Degrees(), getTzais16Point1Degrees(), true);
}
/**
*
* A method for calculating samuch lemincha ketana, / near mincha ketana time that is half an hour before
- * {@link #getMinchaKetana()} or is 9 * shaos zmaniyos (solar hours) after the start of the day, calculated based
- * on a day from and ending a day starting at {@link #getAlos72() alos 72 minutes} and ending at {@link #getTzais72()
- * tzais 72 minutes}. This is the time that eating or other activity can't begin prior to praying mincha.
- * The calculation used is 9 * {@link #getShaahZmanis72Minutes()} after {@link #getAlos72() alos 72 minutes}. See the Mechaber and Mishna Berurah 232 and 249:2.
- *
- * @see #getSamuchLeMinchaKetana(Date, Date, boolean)
+ * {@link #getMinchaKetanaGRA()} or is 9 * shaos zmaniyos (solar hours) after the start of the day, calculated based
+ * on a day from and ending a day starting at {@link #getAlos72Minutes() alos 72 minutes} and ending at {@link
+ * #getTzais72Minutes() tzais 72 minutes}. This is the time that eating or other activity can't begin prior to praying
+ * mincha. The calculation used is 9 * {@link #getShaahZmanis72Minutes()} after {@link #getAlos72Minutes() alos
+ * 72 minutes}. See the Mechaber and Mishna Berurah
+ * 232 and 249:2.
+ *
+ * @see #getSamuchLeMinchaKetana(Instant, Instant, boolean)
* @see #getShaahZmanis72Minutes()
- * @return the Date of the time of samuch lemincha ketana. If the calculation can't be computed such
+ * @return the Instant of the time of samuch lemincha ketana. 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 getSamuchLeMinchaKetana72Minutes() {
- return getSamuchLeMinchaKetana(getAlos72(), getTzais72(), true);
+ public Instant getSamuchLeMinchaKetana72Minutes() {
+ return getSamuchLeMinchaKetana(getAlos72Minutes(), getTzais72Minutes(), true);
+ }
+
+ /**
+ * A method that returns sunset if it occurs, or the time that the sun is at its westernmost position (azimuth of 270°), if
+ * sunset will not occur on that day, such as in the Arctic or Antarctic circles. There are some opinions that in Polar regions
+ * where there are days of no sunrise or sunset, that the definition of a day during this period is a 24-hour day, and the
+ * day-night boundary is when the sun is at its westernmost position. sunrise in this opinion is when the sun is at its
+ * easternmost position.
+ * FIXME link opinions of the Ben Ish chai etc.
+ * @return sunset if it occurs, or the time that the sun will reach its westernmost position (azimuth 270°), if sunset will
+ * not occur that day. If there is no sunset this day, and the azimuth 270 will not occur, a null will be returned.
+ * @see #getSunriseOrEasternmostSolarAzimuth()
+ * @see #getTimeAtAzimuth(double)
+ * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getTimeAtAzimuth(LocalDate, GeoLocation, double)
+ */
+ public Instant getSunsetOrWesternmostSolarAzimuth() {
+ Instant sunset = getSunsetBasedOnElevationSetting();
+ if(sunset != null) {
+ return sunset;
+ }
+ return getTimeAtAzimuth(270);
+ }
+
+ /**
+ * A method that returns sunrise if it occurs, or the time that the sun is at its easternmost position (azimuth of 900°), if
+ * sunset will not occur on that day, such as in the Arctic or Antarctic circles. There are some opinions that in Polar regions
+ * where there are days of no sunrise or sunset, that the definition of a day during this period is a 24-hour day, and the
+ * day-night boundary is when the sun is at its easternmost position. Sunset in this opinion is when the sun is at its
+ * westernmost position.
+ * FIXME link opinions of the Ben Ish chai etc.
+ * @return sunrise if it occurs, or the time that the sun will reach its easternmost position (azimuth 90°), if sunrise will
+ * not occur that day. If there is no sunrise this day, and the azimuth 90 will not occur, a null will be returned.
+ * @see #getSunsetOrWesternmostSolarAzimuth()
+ * @see #getTimeAtAzimuth(double)
+ * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getTimeAtAzimuth(LocalDate, GeoLocation, double)
+ */
+ public Instant getSunriseOrEasternmostSolarAzimuth() {
+ Instant sunrise = getSunriseBasedOnElevationSetting();
+ if(sunrise != null) {
+ return sunrise;
+ }
+ return getTimeAtAzimuth(90);
+ }
+
+ /**
+ * @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;
+ }
+ ComprehensiveZmanimCalendar that = (ComprehensiveZmanimCalendar) object;
+ return ateretTorahSunsetOffset == that.ateretTorahSunsetOffset;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return 37 * super.hashCode() + Double.hashCode(ateretTorahSunsetOffset);
}
}
diff --git a/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java b/src/main/java/com/kosherjava/zmanim/ZmanimCalendar.java
index be75d52e..3a0c4b58 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 getSunrise()}, {@link getSunset()}, {@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:
* 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
+ * a solar day / night calculation for chatzos.
+ * @see isUseAstronomicalChatzos()
+ * @see setUseAstronomicalChatzos(boolean)
+ * @see getChatzosHayom()
+ * @see getChatzosHalayla()
+ * @see getSunTransit()
+ * @see getChatzosHayomAsHalfDay()
+ * @see useAstronomicalChatzosForOtherZmanim
*/
private boolean useAstronomicalChatzos = true;
/**
- * 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()
+ * Is {@link getSunTransit() astronomical chatzos} used for {@link getChatzosHayom()} and {@link getChatzosHalayla()}
+ * 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()
* 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 getChatzosHayom()
+ * @see getChatzosHalayla()
+ * @see getSunTransit()
+ * @see getChatzosHayomAsHalfDay()
+ * @see isUseAstronomicalChatzosForOtherZmanim()
*/
public boolean isUseAstronomicalChatzos() {
return useAstronomicalChatzos;
@@ -156,12 +157,13 @@ 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 getChatzosHayom()
+ * @see getChatzosHalayla()
+ * @see getSunTransit()
+ * @see getChatzosHayomAsHalfDay()
+ * @see setUseAstronomicalChatzosForOtherZmanim(boolean)
*/
public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) {
this.useAstronomicalChatzos = useAstronomicalChatzos;
@@ -171,11 +173,12 @@ 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 getChatzosHayom()
+ * @see getChatzosHalayla()
*/
private boolean useAstronomicalChatzosForOtherZmanim = false;
@@ -185,20 +188,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 +210,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,35 +232,34 @@ 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 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 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 getSunrise()} if it is true.
+ * @see getSunrise()
*/
- protected Date getElevationAdjustedSunrise() {
+ protected Instant getSunriseBasedOnElevationSetting() {
if (isUseElevation()) {
return super.getSunrise();
}
@@ -274,15 +267,15 @@ protected Date getElevationAdjustedSunrise() {
}
/**
- * 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 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 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 getSunset()} if it is true.
+ * @see getSunset()
*/
- protected Date getElevationAdjustedSunset() {
+ protected Instant getSunsetBasedOnElevationSetting() {
if (isUseElevation()) {
return super.getSunset();
}
@@ -290,93 +283,92 @@ protected Date getElevationAdjustedSunset() {
}
/**
- * 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 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. 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 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 #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 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 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 hayom} 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 getChatzosHayomAsHalfDay()
* 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 getChatzosHayomAsHalfDay()
+ * @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) {
- return getSunTransit(); // can be null of the calculator does not support astronomical chatzos
+ public Instant getChatzosHayom() {
+ if (isUseAstronomicalChatzos()) {
+ return getSunTransit(); // can be null if the calculator does not support astronomical chatzos
} else {
- Date halfDayChatzos = getChatzosAsHalfDay();
+ Instant halfDayChatzos = getChatzosHayomAsHalfDay();
if (halfDayChatzos == null) {
return getSunTransit(); // can be null if the calculator does not support astronomical chatzos
} else {
@@ -385,10 +377,94 @@ public Date getChatzos() {
}
}
+ /**
+ * A method that returns chatzos halayla at the end of the day (the last zman of the day
+ * returned by the calendar, that may actually be after midnight of the day it is being calculated for). For example, if
+ * calculating it for the date of Erev Pesach, the calculation will be for Lail Pesach to allow you to use the
+ * zman as sof zman achilas chametz. {@link getSolarMidnight() Astronomical chatzos halayla} will be
+ * returned if the {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculator} class used supports it and {@link
+ * isUseAstronomicalChatzos() isUseAstronomicalChatzos()} is set to true. Otherwise the {@link #getChatzos(Instant,
+ * Instant) halfway point} between sunset and the following day's sunrise, 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 halayla as
+ * halfway between sunset and the following day's sunrise (identical to six shaos zmaniyos after sunset), while the
+ * NOAACalculator calculates it more accurately as {@link getSolarMidnight() astronomical chatzos halayla}. See The Definition of Chatzos for a detailed explanation
+ * of the ways to calculate Chatzos. Since half-night chatzos can be null in the Arctic on a day
+ * when either sunset or the following day's sunrise did not happen and astronomical chatzos halayla 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 getSolarMidnight()
+ * @see getChatzos(Instant, Instant)
+ * @see isUseAstronomicalChatzos()
+ * @see setUseAstronomicalChatzos(boolean)
+ * @return the Instant of chatzos halayla at the end of the current day. 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 getChatzosHalayla() {
+ if (isUseAstronomicalChatzos()) {
+ return getSolarMidnight(); // can be null if the calculator does not support astronomical chatzos
+ } else {
+ ZmanimCalendar clonedCalendar = (ZmanimCalendar)this.clone();
+ clonedCalendar.setLocalDate(getLocalDate().plusDays(1));
+ Instant halfNightChatzos = getChatzos(getSeaLevelSunset(), clonedCalendar.getSeaLevelSunrise());
+ if (halfNightChatzos == null) {
+ return getSolarMidnight(); // can be null if the calculator does not support astronomical chatzos
+ } else {
+ return halfNightChatzos;
+ }
+ }
+ }
+
+ /**
+ * 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,
+ * the zman returned will be close to, but not exactly, when the Sun is transiting the celestial meridian due to changes in declination (the
+ * lengthening or shortening day). 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)}. A practical example of using this would be
+ * calculating chatzos halayla for the for the end of zman achilas afikoman on Pesach night, where
+ * Rav Shlomo Zalman Auerbach in the Halichos Shlomo,
+ * Moadim Nisan - Av, ch. 9, no. 44, pages 289-292, questioned the common practice of considering chatzos halayla as
+ * astronomical chatzos halayla, and felt that for this it should be at chatzi halayla, halfway between sunset
+ * and alos or bedieved from an early tzais that is lower (degree-wise) than alos the next
+ * morning, thus making this zman significantly earlier. Rav
+ * Moshe Sternbuch in Teshuvos Vehanhagos v. VII, ch 1, p.
+ * 3, agreed to this calculation for chatzos halayla on Pesach night.
+ *
+ * @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 getChatzosHayomAsHalfDay()
+ * @see getChatzosHayom()
+ * @see getChatzosHalayla()
+ */
+ 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 +477,23 @@ 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 getChatzosHayom()
+ * @see getChatzosHalayla()
+ * @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 getChatzosHayomAsHalfDay() {
+ return getChatzos(getSeaLevelSunrise(), getSeaLevelSunset());
}
/**
@@ -423,15 +501,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 getSunrise() sunrise} and {@link getSunset() 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,24 +519,24 @@ 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);
+ return getHalfDayBasedZman(startOfDay, getChatzosHayom(), 3);
} else {
return getShaahZmanisBasedZman(startOfDay, endOfDay, 3);
}
}
/**
- * 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 +545,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 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 #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 getSunrise() sunrise} to {@link getSunset() 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 getSunrise() 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 +607,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 getSunset() 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 +645,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 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(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,23 +664,124 @@ 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);
+ return getHalfDayBasedZman(startOfDay, getChatzosHayom(), 4);
} else {
return getShaahZmanisBasedZman(startOfDay, endOfDay, 4);
}
}
+
/**
- * A generic method for calculating the latest zman tfila that calls {@link #getSofZmanTfila(Date, Date, boolean)}
+ * 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, getChatzosHayom(), 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)}
* 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 +790,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 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 #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 getSunrise() sunrise} to {@link getSunset() 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, Instant, boolean)
+ * @see getShaahZmanis72Minutes()
+ * @see getAlos72Minutes()
*/
- public Date getSofZmanTfilaMGA() {
- return getSofZmanTfila(getAlos72(), getTzais72(), true);
+ public Instant getSofZmanTfilaMGA72Minutes() {
+ return getSofZmanTfila(getAlos72Minutes(), getTzais72Minutes(), true);
}
/**
@@ -665,18 +846,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 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 getChatzosHayomAsHalfDay() 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,28 +869,29 @@ 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 getChatzosHayomAsHalfDay()
+ * @see getChatzosHayom()
+ * @see getChatzosHalayla()
+ * @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);
+ return getHalfDayBasedZman(getChatzosHayom(), endOfDay, 0.5);
} else {
return getShaahZmanisBasedZman(startOfDay, endOfDay, 6.5);
}
}
/**
- * 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 +901,53 @@ 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 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 #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 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()}.
+ * @todo Consider adjusting this to calculate the time as half an hour zmaniyos after {@link getChatzosHayom()}
+ * that uses {@link isUseAstronomicalChatzos()} to determine the type of chatzos to utilize (if the
+ * {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculator} support astronomical chatzos),
+ * based on the {@link isUseAstronomicalChatzos()} setting.
*
- * @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 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 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,16 +972,16 @@ 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);
+ return getHalfDayBasedZman(getChatzosHayom(), endOfDay, 3);
} else {
return getShaahZmanisBasedZman(startOfDay, endOfDay, 9);
}
}
/**
- * 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 +990,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 +1007,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 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(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,23 +1026,23 @@ 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);
+ return getHalfDayBasedZman(getChatzosHayom(), endOfDay, 3.5);
} else {
return getShaahZmanisBasedZman(startOfDay, endOfDay, 9.5);
}
}
/**
- * 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 +1051,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 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 #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 getSunrise() sunrise} to {@link getSunset() 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 +1091,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 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(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,87 +1110,119 @@ 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);
+ return getHalfDayBasedZman(getChatzosHayom(), endOfDay, 4.75);
} else {
return getShaahZmanisBasedZman(startOfDay, endOfDay, 10.75);
}
}
/**
- * 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 haminchaDate 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 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(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 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}.
*
@@ -1016,8 +1231,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 +1256,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 +1299,97 @@ public void setCandleLightingOffset(double candleLightingOffset) {
* @see JewishCalendar#hasCandleLighting()
* @see JewishCalendar#setInIsrael(boolean)
*/
- public boolean isAssurBemlacha(Date currentTime, Date tzais, boolean inIsrael) {
+ public boolean isAssurBemelacha(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 getSunrise()
+ * @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 getSunset()
+ * @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 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
@@ -1115,15 +1399,18 @@ 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);
+ if (shaahZmanis == Long.MIN_VALUE) { //defensive, should not be needed
+ return null;
+ }
+ return getTimeOffset(startOfDay, Math.round(shaahZmanis * hours));
}
/**
@@ -1145,9 +1432,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 +1443,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 +1476,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()
+ * @see ComprehensiveZmanimCalendar#getFixedLocalChatzosHayom()
*/
- 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 +1508,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));
}
}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java
index 71fa8f12..d11da217 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2011 - 2024 Eliyahu Hershfeld
+ * Copyright (C) 2011 - 2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,7 +15,7 @@
*/
package com.kosherjava.zmanim.hebrewcalendar;
-import java.text.SimpleDateFormat;
+import java.time.format.DateTimeFormatter;
import java.util.EnumMap;
/**
@@ -23,8 +23,8 @@
*
* The class formats Jewish dates, numbers, Daf Yomi (Bavli and Yerushalmi), the Omer,
* Parshas Hashavua (including the special parshiyos of Shekalim, Zachor, Parah
- * and Hachodesh), Yomim Tovim and the Molad (experimental) in Hebrew or Latin chars, and has various settings.
- * Sample full date output includes (using various options):
+ * and Hachodesh), Yomim Tovim in Hebrew or Latin chars, and has various settings. Sample full date output
+ * includes (using various options):
* "בראשית, נח, לך לך,
- * וירא, חיי שרה,
- * תולדות, ויצא, וישלח,
- * וישב, מקץ, ויגש, ויחי,
- * שמות, וארא, בא, בשלח,
- * יתרו, משפטים, תרומה,
- * תצוה, כי תשא, ויקהל,
- * פקודי, ויקרא, צו,
- * שמיני, תזריע, מצרע,
- * אחרי מות, קדושים,
- * אמור, בהר, בחקתי,
- * במדבר, נשא, בהעלתך,
- * שלח לך, קרח, חוקת, בלק,
- * פינחס, מטות, מסעי,
- * דברים, ואתחנן, עקב,
- * ראה, שופטים, כי תצא,
- * כי תבוא, נצבים, וילך,
- * האזינו, וזאת הברכה,
- * ויקהל פקודי, תזריע
- * מצרע, אחרי מות
- * קדושים, בהר בחקתי,
- * חוקת בלק, מטות מסעי,
- * נצבים וילך, שקלים,
- * זכור, פרה, החדש,
- * שובה,שירה,הגדול,
- * חזון,נחמו"
+ * An {@link EnumMap} of Hebrew parshiyos. The list includes double and special parshiyos and
+ * contains בראשית, נח, לך לך,
+ * וירא, חיי שרה,
+ * תולדות, ויצא, וישלח,
+ * וישב, מקץ, ויגש, ויחי,
+ * שמות, וארא, בא, בשלח,
+ * יתרו, משפטים, תרומה,
+ * תצוה, כי תשא, ויקהל,
+ * פקודי, ויקרא, צו,
+ * שמיני, תזריע, מצרע,
+ * אחרי מות, קדושים,
+ * אמור, בהר, בחקתי,
+ * במדבר, נשא, בהעלתך,
+ * שלח לך, קרח, חוקת, בלק,
+ * פינחס, מטות, מסעי,
+ * דברים, ואתחנן, עקב,
+ * ראה, שופטים, כי תצא,
+ * כי תבוא, נצבים, וילך,
+ * האזינו, וזאת הברכה,
+ * ויקהל פקודי, תזריע
+ * מצרע, אחרי מות
+ * קדושים, בהר בחקתי,
+ * חוקת בלק, מטות מסעי,
+ * נצבים וילך, שקלים,
+ * זכור, פרה, החדש,
+ * שובה,שירה,הגדול,
+ * חזון,נחמו
*/
private final EnumMap["Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan",
+ * "Kislev", "Teves", "Shevat", "Adar", "Adar II", "Adar I" ].
* @see #getTransliteratedMonthList()
* @see #setTransliteratedMonthList(String[])
*/
@@ -330,7 +323,7 @@ public void setLongWeekFormat(boolean longWeekFormat) {
private String hebrewOmerPrefix = "\u05D1";
/**
- * The default value for formatting Shabbos (Saturday). Defaults to Shabbos.
+ * The default value for formatting "Shabbos" (Saturday) when transliterated.
* @see #getTransliteratedShabbosDayOfWeek()
* @see #setTransliteratedShabbosDayOfWeek(String)
*/
@@ -338,7 +331,8 @@ public void setLongWeekFormat(boolean longWeekFormat) {
/**
* Returns the day of Shabbos transliterated into Latin chars. The default uses Ashkenazi pronunciation "Shabbos".
- * This can be overwritten using the {@link #setTransliteratedShabbosDayOfWeek(String)}
+ * This can be overwritten using the {@link #setTransliteratedShabbosDayOfWeek(String)}. It is uesd by {@link
+ * #formatDayOfWeek(JewishDate)}.
*
* @return the transliteratedShabbos. The default list of months uses Ashkenazi pronunciation "Shabbos".
* @see #setTransliteratedShabbosDayOfWeek(String)
@@ -350,7 +344,7 @@ public String getTransliteratedShabbosDayOfWeek() {
/**
* Setter to override the default transliterated name of "Shabbos" to alternate spelling such as "Shabbat" used by
- * the {@link #formatDayOfWeek(JewishDate)}
+ * the {@link #formatDayOfWeek(JewishDate)}.
*
* @param transliteratedShabbos
* the transliteratedShabbos to set
@@ -370,21 +364,20 @@ public void setTransliteratedShabbosDayOfWeek(String transliteratedShabbos) {
"Rosh Hashana", "Fast of Gedalyah", "Erev Yom Kippur", "Yom Kippur", "Erev Succos", "Succos",
"Chol Hamoed Succos", "Hoshana Rabbah", "Shemini Atzeres", "Simchas Torah", "Erev Chanukah", "Chanukah",
"Tenth of Teves", "Tu B'Shvat", "Fast of Esther", "Purim", "Shushan Purim", "Purim Katan", "Rosh Chodesh",
- "Yom HaShoah", "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim", "Lag B'Omer","Shushan Purim Katan",
+ "Yom HaShoah", "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim", "Lag B'Omer", "Shushan Purim Katan",
"Isru Chag"};
/**
- * Returns the array of holidays transliterated into Latin chars. This is used by the
- * {@link #formatYomTov(JewishCalendar)} when formatting the Yom Tov String. The default list of months uses
- * Ashkenazi pronunciation in typical American English spelling.
+ * Returns the array of Yomim Tovim (holidays) transliterated into Latin chars. This is used by the {@link
+ * #formatYomTov(JewishCalendar)} when formatting the Yom Tov String. The default list of months usesnAshkenazi
+ * pronunciation in typical American English spelling. The default list is currently
+ * ["Erev Pesach", "Pesach", "Chol Hamoed Pesach", "Pesach Sheni", "Erev Shavuos", "Shavuos", "Seventeenth of Tammuz",
+ * "Tishah B'Av", "Tu B'Av", "Erev Rosh Hashana", "Rosh Hashana", "Fast of Gedalyah", "Erev Yom Kippur", "Yom Kippur", "Erev
+ * Succos", "Succos", "Chol Hamoed Succos", "Hoshana Rabbah", "Shemini Atzeres", "Simchas Torah", "Erev Chanukah", "Chanukah",
+ * "Tenth of Teves", "Tu B'Shvat", "Fast of Esther", "Purim", "Shushan Purim",m"Purim Katan", "Rosh Chodesh", "Yom HaShoah",
+ * "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim", "Lag B'Omer", "Shushan Purim Katan", "Isru Chag"].
*
- * @return the array of transliterated holidays. The default list is currently ["Erev Pesach", "Pesach",
- * "Chol Hamoed Pesach", "Pesach Sheni", "Erev Shavuos", "Shavuos", "Seventeenth of Tammuz", "Tishah B'Av",
- * "Tu B'Av", "Erev Rosh Hashana", "Rosh Hashana", "Fast of Gedalyah", "Erev Yom Kippur", "Yom Kippur",
- * "Erev Succos", "Succos", "Chol Hamoed Succos", "Hoshana Rabbah", "Shemini Atzeres", "Simchas Torah",
- * "Erev Chanukah", "Chanukah", "Tenth of Teves", "Tu B'Shvat", "Fast of Esther", "Purim", "Shushan Purim",
- * "Purim Katan", "Rosh Chodesh", "Yom HaShoah", "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim",
- * "Lag B'Omer","Shushan Purim Katan","Isru Chag"].
+ * @return the array of transliterated Yomim Tovim (holidays).
*
* @see #setTransliteratedMonthList(String[])
* @see #formatYomTov(JewishCalendar)
@@ -395,8 +388,14 @@ public String[] getTransliteratedHolidayList() {
}
/**
- * Sets the array of holidays transliterated into Latin chars. This is used by the
- * {@link #formatYomTov(JewishCalendar)} when formatting the Yom Tov String.
+ * Sets the array of Yomim Tovim (holidays) transliterated into Latin chars. This is used by the
+ * {@link #formatYomTov(JewishCalendar)} when formatting the Yom Tov String. The list uses the following order and uses
+ * the spelling as follows.
+ * ["Erev Pesach", "Pesach", "Chol Hamoed Pesach", "Pesach Sheni", "Erev Shavuos", "Shavuos", "Seventeenth of Tammuz",
+ * "Tishah B'Av", "Tu B'Av", "Erev Rosh Hashana", "Rosh Hashana", "Fast of Gedalyah", "Erev Yom Kippur", "Yom Kippur", "Erev
+ * Succos", "Succos", "Chol Hamoed Succos", "Hoshana Rabbah", "Shemini Atzeres", "Simchas Torah", "Erev Chanukah", "Chanukah",
+ * "Tenth of Teves", "Tu B'Shvat", "Fast of Esther", "Purim", "Shushan Purim", "Purim Katan", "Rosh Chodesh", "Yom HaShoah",
+ * "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim", "Lag B'Omer", "Shushan Purim Katan", "Isru Chag"].
*
* @param transliteratedHolidays
* the transliteratedHolidays to set. Ensure that the sequence exactly matches the list returned by the
@@ -407,7 +406,8 @@ public void setTransliteratedHolidayList(String[] transliteratedHolidays) {
}
/**
- * Hebrew holiday array in the following format.["ערב פסח",
+ * Hebrew Yomim Tovim (holidays) array in the following format.
+ * ["ערב פסח",
* "פסח", "חול המועד
* פסח", "פסח שני", "ערב
* שבועות", "שבועות",
@@ -468,10 +468,10 @@ public void setTransliteratedHolidayList(String[] transliteratedHolidays) {
"\u05D0\u05E1\u05E8\u05D5 \u05D7\u05D2"};
/**
- * Formats the Yom Tov (holiday) in Hebrew or transliterated Latin characters.
+ * Formats the Yom Tov (holiday) in Hebrew or transliterated Latin characters.
*
* @param jewishCalendar the JewishCalendar
- * @return the formatted holiday or an empty String if the day is not a holiday.
+ * @return the formatted Yom Tov (holiday) or an empty String if the day is not a Yom Tov (holiday).
* @see #isHebrewFormat()
*/
public String formatYomTov(JewishCalendar jewishCalendar) {
@@ -547,12 +547,11 @@ public void setHebrewFormat(boolean hebrewFormat) {
}
/**
- * Returns the Hebrew Omer prefix. By default it is the letter ב producing
- * בעומר, but it can be set to ל to produce
- * לעומר (or any other prefix) using the {@link #setHebrewOmerPrefix(String)}.
+ * Returns the Hebrew Omer prefix. By default it is the letter ב producing בעומר,
+ * but it can be set to ל to produce לעומר (or any other prefix) using the
+ * {@link #setHebrewOmerPrefix(String)}.
*
* @return the hebrewOmerPrefix
- *
* @see #hebrewOmerPrefix
* @see #setHebrewOmerPrefix(String)
* @see #formatOmer(JewishCalendar)
@@ -562,9 +561,8 @@ public String getHebrewOmerPrefix() {
}
/**
- * Method to set the Hebrew Omer prefix. By default it is the letter ב producing
- * בעומר, but it can be set to ל to produce
- * לעומר (or any other prefix)
+ * Method to set the Hebrew Omer prefix. By default it is the letter ב producing בעומר,
+ * but it can be set to ל to produce לעומר (or any other prefix).
* @param hebrewOmerPrefix
* the hebrewOmerPrefix to set. You can use the Unicode \u05DC to set it to ל.
* @see #hebrewOmerPrefix
@@ -574,15 +572,47 @@ public String getHebrewOmerPrefix() {
public void setHebrewOmerPrefix(String hebrewOmerPrefix) {
this.hebrewOmerPrefix = hebrewOmerPrefix;
}
+
+ /**
+ * Returns the Hebrew array of months in the order of ["\u05E0\u05D9\u05E1\u05DF", "\u05D0\u05D9\u05D9\u05E8",
+ * "\u05E1\u05D9\u05D5\u05DF", "\u05EA\u05DE\u05D5\u05D6", "\u05D0\u05D1", "\u05D0\u05DC\u05D5\u05DC",
+ * "\u05EA\u05E9\u05E8\u05D9", "\u05D7\u05E9\u05D5\u05DF", "\u05DB\u05E1\u05DC\u05D5", "\u05D8\u05D1\u05EA",
+ * "\u05E9\u05D1\u05D8", "\u05D0\u05D3\u05E8", "\u05D0\u05D3\u05E8 \u05D1", "\u05D0\u05D3\u05E8 \u05D0"]. This list has
+ * a length of 14 starting with "ניסן" and ending with 3 variations of Adar -
+ * "אדר", "אדר ב", "אדר א".
+ * @return the array of Hebrew months.
+ * @see #hebrewMonths
+ * @see #setHebrewMonthList(String[])
+ */
+ public String[] getHebrewMonthList() {
+ return hebrewMonths;
+ }
+
+ /**
+ * Setter method to allow overriding of the default list of Hebrew month names. This allows changing things such as the default
+ * month name of חשון to מרחשון, etc. This list expects a
+ * length of 14 starting with "ניסן" and ending with 3 variations of Adar -
+ * "אדר", "אדר ב", "אדר".
+ *
+ * @param hebrewMonths the array of Hebrew months beginning in "ניסן" and ending in
+ * "אדר", "אדר ב", "אדר א"
+ * @see #getHebrewMonthList()
+ */
+ public void setHebrewMonthList(String[] hebrewMonths) {
+ if(hebrewMonths.length !=14) {
+ throw new IllegalArgumentException("The Hebrew month array must have a length of 14.");
+ }
+ this.hebrewMonths = hebrewMonths;
+ }
/**
- * Returns the array of months transliterated into Latin chars. The default list of months uses Ashkenazi
- * pronunciation in typical American English spelling. This list has a length of 14 with 3 variations for Adar -
- * "Adar", "Adar II", "Adar I"
+ * Returns the array of months transliterated into Latin chars. The default list of months uses Ashkenazi pronunciation in
+ * typical American English spelling. This list has a length of 14 with 3 variations for Adar - "Adar", "Adar II", "Adar I".
+ * The array of months beginn in Nissan and end in "Adar", "Adar II", "Adar I". The default list is
+ * ["Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan", "Kislev", "Teves", "Shevat", "Adar",
+ * "Adar II", "Adar I"].
*
- * @return the array of months beginning in Nissan and ending in "Adar", "Adar II", "Adar I". The default list is
- * currently ["Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan", "Kislev", "Teves",
- * "Shevat", "Adar", "Adar II", "Adar I"].
+ * @return the array of 14 month names beginning in Nissan and ending in "Adar", "Adar II", "Adar I".
* @see #setTransliteratedMonthList(String[])
*/
public String[] getTransliteratedMonthList() {
@@ -590,36 +620,40 @@ public String[] getTransliteratedMonthList() {
}
/**
- * Setter method to allow overriding of the default list of months transliterated into Latin chars. The default
- * uses Ashkenazi American English transliteration.
+ * Setter method to allow overriding of the default list of months transliterated into Latin chars. The default list uses
+ * Ashkenazi American English transliteration. The array of 14 transliterated month names begin in "Nissan" and end in the
+ * 3 Adar variations - "Adar", "Adar II", "Adar I". The default list is
+ * ["Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan", "Kislev", "Teves", "Shevat", "Adar",
+ * "Adar II", "Adar I"].
*
- * @param transliteratedMonths
- * an array of 14 month names that defaults to ["Nissan", "Iyar", "Sivan", "Tamuz", "Av", "Elul", "Tishrei",
- * "Heshvan", "Kislev", "Tevet", "Shevat", "Adar", "Adar II", "Adar I"].
+ * @param transliteratedMonths the array of 14 month names beginning in Nissan and ending in "Adar", "Adar II", "Adar I".
* @see #getTransliteratedMonthList()
*/
public void setTransliteratedMonthList(String[] transliteratedMonths) {
+ if(transliteratedHolidays.length !=14) {
+ throw new IllegalArgumentException("The transliterated month array must have a length of 14.");
+ }
this.transliteratedMonths = transliteratedMonths;
}
/**
- * Unicode list of Hebrew months in the following format ["\u05E0\u05D9\u05E1\u05DF","\u05D0\u05D9\u05D9\u05E8",
- * "\u05E1\u05D9\u05D5\u05DF","\u05EA\u05DE\u05D5\u05D6","\u05D0\u05D1","\u05D0\u05DC\u05D5\u05DC",
- * "\u05EA\u05E9\u05E8\u05D9","\u05D7\u05E9\u05D5\u05DF","\u05DB\u05E1\u05DC\u05D5","\u05D8\u05D1\u05EA",
- * "\u05E9\u05D1\u05D8","\u05D0\u05D3\u05E8","\u05D0\u05D3\u05E8 \u05D1","\u05D0\u05D3\u05E8 \u05D0"]
+ * List of Hebrew months. The list has* a length of 14 starting with "ניסן" and ending with the
+ * 3 variations of Adar - "אדר", "אדר ב", "אדר א".
*
+ * @see #getHebrewMonthList()
+ * @see #setHebrewMonthList(String[])
* @see #formatMonth(JewishDate)
*/
- private static final String[] hebrewMonths = { "\u05E0\u05D9\u05E1\u05DF", "\u05D0\u05D9\u05D9\u05E8",
+ private String[] hebrewMonths = { "\u05E0\u05D9\u05E1\u05DF", "\u05D0\u05D9\u05D9\u05E8",
"\u05E1\u05D9\u05D5\u05DF", "\u05EA\u05DE\u05D5\u05D6", "\u05D0\u05D1", "\u05D0\u05DC\u05D5\u05DC",
"\u05EA\u05E9\u05E8\u05D9", "\u05D7\u05E9\u05D5\u05DF", "\u05DB\u05E1\u05DC\u05D5",
"\u05D8\u05D1\u05EA", "\u05E9\u05D1\u05D8", "\u05D0\u05D3\u05E8", "\u05D0\u05D3\u05E8 \u05D1",
"\u05D0\u05D3\u05E8 \u05D0" };
/**
- * Unicode list of Hebrew days of week in the format of ["ראשון",
- * "שני","שלישי","רביעי",
- * "חמישי","ששי","שבת"]
+ * Unicode list of Hebrew days of week in the format of ["ראשון",
+ * "שני", "שלישי", "רביעי",
+ * "חמישי", "ששי", "שבת"]
*/
private static final String[] hebrewDaysOfWeek = { "\u05E8\u05D0\u05E9\u05D5\u05DF", "\u05E9\u05E0\u05D9",
"\u05E9\u05DC\u05D9\u05E9\u05D9", "\u05E8\u05D1\u05D9\u05E2\u05D9", "\u05D7\u05DE\u05D9\u05E9\u05D9",
@@ -654,7 +688,7 @@ public String formatDayOfWeek(JewishDate jewishDate) {
return getTransliteratedShabbosDayOfWeek().substring(0,3);
}
} else {
- return weekFormat.format(jewishDate.getGregorianCalendar().getTime());
+ return weekFormat.format(jewishDate.getLocalDate());
}
}
}
@@ -818,31 +852,6 @@ public String formatOmer(JewishCalendar jewishCalendar) {
}
}
- /**
- * Formats a molad.
- * @todo Experimental and incomplete.
- *
- * @param moladChalakim the chalakim of the molad
- * @return the formatted molad. FIXME: define proper format in English and Hebrew.
- */
- private static String formatMolad(long moladChalakim) {
- long adjustedChalakim = moladChalakim;
- int MINUTE_CHALAKIM = 18;
- int HOUR_CHALAKIM = 1080;
- int DAY_CHALAKIM = 24 * HOUR_CHALAKIM;
-
- long days = adjustedChalakim / DAY_CHALAKIM;
- adjustedChalakim = adjustedChalakim - (days * DAY_CHALAKIM);
- int hours = (int) ((adjustedChalakim / HOUR_CHALAKIM));
- if (hours >= 6) {
- days += 1;
- }
- adjustedChalakim = adjustedChalakim - (hours * (long) HOUR_CHALAKIM);
- int minutes = (int) (adjustedChalakim / MINUTE_CHALAKIM);
- adjustedChalakim = adjustedChalakim - minutes * (long) MINUTE_CHALAKIM;
- return "Day: " + days % 7 + " hours: " + hours + ", minutes " + minutes + ", chalakim: " + adjustedChalakim;
- }
-
/**
* Returns the kviah in the traditional 3 letter Hebrew format where the first letter represents the day of week of
* Rosh Hashana, the second letter represents the lengths of Cheshvan and Kislev ({@link JewishDate#SHELAIMIM
@@ -1015,9 +1024,20 @@ public String formatHebrewNumber(int number) {
}
/**
- * Returns the map of transliterated parshiyos used by this formatter.
+ * Returns the map of transliterated parshiyos used by this formatter. This list using the default Ashkenazi
+ * pronunciation. This list can be overridden (for Sephardi English transliteration for example) by setting the
+ * {@link #setTransliteratedParshiosList(EnumMap)}. The list includes double and special parshiyos in the following
+ * order and spelling "Bereshis, Noach, Lech Lecha, Vayera, Chayei Sara, Toldos, Vayetzei, Vayishlach, Vayeshev, Miketz,
+ * Vayigash, Vayechi, Shemos, Vaera, Bo, Beshalach, Yisro, Mishpatim, Terumah, Tetzaveh, Ki Sisa, Vayakhel, Pekudei, Vayikra,
+ * Tzav, Shmini, Tazria, Metzora, Achrei Mos, Kedoshim, Emor, Behar, Bechukosai, Bamidbar, Nasso, Beha'aloscha, Sh'lach,
+ * Korach, Chukas, Balak, Pinchas, Matos, Masei, Devarim, Vaeschanan, Eikev, Re'eh, Shoftim, Ki Seitzei, Ki Savo, Nitzavim,
+ * Vayeilech, Ha'Azinu, Vezos Habracha, Vayakhel Pekudei, Tazria Metzora, Achrei Mos Kedoshim, Behar Bechukosai, Chukas Balak,
+ * Matos Masei, Nitzavim Vayeilech, Shekalim, Zachor, Parah, Hachodesh,Shuva, Shira, Hagadol, Chazon, Nachamu".
*
* @return the map of transliterated Parshios
+ * @see #setTransliteratedParshiosList(EnumMap)
+ * @see #formatParsha(JewishCalendar)
+ * @see #formatParsha(JewishCalendar.Parsha)
*/
public EnumMap getTransliteratedParshiosList() {
return transliteratedParshaMap;
@@ -1029,7 +1049,7 @@ public EnumMap getTransliteratedParshiosList() {
*
* @param transliteratedParshaMap
* the transliterated Parshios as an EnumMap to set
- * @see #getTransliteratedParshiosList()
+ * @see #getTransliteratedParshiosList() for information on the format.
*/
public void setTransliteratedParshiosList(EnumMap transliteratedParshaMap) {
this.transliteratedParshaMap = transliteratedParshaMap;
@@ -1063,9 +1083,9 @@ public String formatParsha(JewishCalendar jewishCalendar) {
}
/**
- * Returns a String with the name of the current parsha(ios). This method overloads {@link
- * HebrewDateFormatter#formatParsha(JewishCalendar)} and unlike that method, it will format the parsha passed
- * to this method regardless of the day of week. This is the way to format a parsha retrieved from calling
+ * Returns a String with the name of the current parsha(ios). This method overloads {@link #formatParsha(JewishCalendar)} and
+ * unlike that method, it will format the parsha passed to this method regardless of the day of week. This is the way
+ * to format a parsha retrieved from calling
* {@link JewishCalendar#getUpcomingParshah()}.
*
* @param parsha a JewishCalendar.Parsha object
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java
index 8f05041a..8d8e7c92 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java
@@ -3,6 +3,7 @@
* Copyright (C) 2011 - 2026 Eliyahu Hershfeld
* Copyright (C) September 2002 Avrom Finkelstien
* Copyright (C) 2019 - 2022 Y Paritcher
+ * Copyright (C) 2026 Moshe Dicker
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -17,12 +18,13 @@
*/
package com.kosherjava.zmanim.hebrewcalendar;
-import com.kosherjava.zmanim.util.GeoLocation;
-
+import java.time.Duration;
+import java.time.Instant;
import java.time.LocalDate;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Calendar; // We still use the old Calendar.WEEKDAY constants
/**
* The JewishCalendar extends the JewishDate class and adds calendar methods.
@@ -42,7 +44,8 @@
* @see java.util.Calendar
* @author © Y. Paritcher 2019 - 2022
* @author © Avrom Finkelstien 2002
- * @author © Eliyahu Hershfeld 2011 - 2024
+ * @author © Moshe Dicker 2026
+ * @author © Eliyahu Hershfeld 2011 - 2026
*/
public class JewishCalendar extends JewishDate {
/** The 14th day of Nissan, the day before Pesach (Passover).*/
@@ -253,24 +256,14 @@ public JewishCalendar() {
super();
}
- /**
- * A constructor that initializes the date to the {@link java.util.Date Date} parameter.
- *
- * @param date
- * the Date to set the calendar to
- */
- public JewishCalendar(Date date) {
- super(date);
- }
-
/**
* A constructor that initializes the date to the {@link java.util.Calendar Calendar} parameter.
*
- * @param calendar
- * the Calendar to set the calendar to
+ * @param zonedDateTime
+ * the ZonedDateTime to set the calendar to
*/
- public JewishCalendar(Calendar calendar) {
- super(calendar);
+ public JewishCalendar(ZonedDateTime zonedDateTime) {
+ super(zonedDateTime);
}
/**
@@ -489,7 +482,7 @@ private int getParshaYearType() {
*
* @return the current parsha.
*/
- public Parsha getParshah() {
+ public synchronized Parsha getParshah() {
if (getDayOfWeek() != Calendar.SATURDAY) {
return Parsha.NONE;
}
@@ -516,12 +509,12 @@ public Parsha getUpcomingParshah() {
JewishCalendar clone = (JewishCalendar) clone();
int daysToShabbos = (Calendar.SATURDAY - getDayOfWeek() + 7) % 7;
if (getDayOfWeek() != Calendar.SATURDAY) {
- clone.forward(Calendar.DATE, daysToShabbos);
+ clone.plusDays(daysToShabbos);
} else {
- clone.forward(Calendar.DATE, 7);
+ clone.plusDays( 7);
}
while(clone.getParshah() == Parsha.NONE) { //Yom Kippur / Sukkos or Pesach with 2 potential non-parsha Shabbosim in a row
- clone.forward(Calendar.DATE, 7);
+ clone.plusDays(7);
}
return clone.getParshah();
}
@@ -539,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) {
@@ -600,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();
@@ -1230,27 +1223,30 @@ public boolean isTishaBav() {
*
* @return the Date representing the moment of the molad in Yerushalayim standard time (GMT + 2)
*/
- public Date getMoladAsDate() {
- JewishDate molad = getMolad();
- String locationName = "Jerusalem, Israel";
+ public Instant getMoladAsInstant() {
+ JewishDate molad = getMolad();
- double latitude = 31.778; // Har Habayis latitude
- double longitude = 35.2354; // Har Habayis longitude
+ // Standard time offset for Jerusalem: GMT+2
+ // The raw molad Date (point in time) must be generated using standard time. Using "Asia/Jerusalem" timezone will
+ // result in the time being incorrectly off by an hour in the summer due to DST. Proper adjustment for the actual
+ // time in DST will be done by the date formatter class used to display the Date.
+ ZoneId jerusalemStandardOffset = ZoneId.of("GMT+2");
- // The raw molad Date (point in time) must be generated using standard time. Using "Asia/Jerusalem" timezone will result in the time
- // being incorrectly off by an hour in the summer due to DST. Proper adjustment for the actual time in DST will be done by the date
- // formatter class used to display the Date.
- TimeZone yerushalayimStandardTZ = TimeZone.getTimeZone("GMT+2");
- GeoLocation geo = new GeoLocation(locationName, latitude, longitude, yerushalayimStandardTZ);
- Calendar cal = Calendar.getInstance(geo.getTimeZone());
- cal.clear();
- double moladSeconds = molad.getMoladChalakim() * 10 / (double) 3;
- cal.set(molad.getGregorianYear(), molad.getGregorianMonth(), molad.getGregorianDayOfMonth(),
- molad.getMoladHours(), molad.getMoladMinutes(), (int) moladSeconds);
- cal.set(Calendar.MILLISECOND, (int) (1000 * (moladSeconds - (int) moladSeconds)));
- // subtract local time difference of 20.94 minutes (20 minutes and 56.496 seconds) to get to Standard time
- cal.add(Calendar.MILLISECOND, -1 * (int) geo.getLocalMeanTimeOffset());
- return cal.getTime();
+ double moladSeconds = molad.getMoladChalakim() * 10.0 / 3.0; // Compute molad seconds from chalakim
+ int seconds = (int) moladSeconds;
+ int nanos = (int) ((moladSeconds - seconds) * 1_000_000_000); // convert remainder to nanos
+
+ LocalTime time = LocalTime.of(molad.getMoladHours(),molad.getMoladMinutes(),seconds,nanos);
+
+ ZonedDateTime moladZdt = ZonedDateTime.of(molad.getLocalDate(),time,jerusalemStandardOffset);
+
+ // Har Habayis at a longitude of 35.2354 offset vs longitude 35 in standard time, so we subtract the time difference
+ // of 20.94 minutes (20 minutes and 56 seconds and 496 millis) to get to Standard time from local mean time
+ Duration jerusalemStandardTimeOffset = Duration.ofMinutes(20)
+ .plusSeconds(56)
+ .plusMillis(496);
+
+ return moladZdt.toInstant().minus(jerusalemStandardTimeOffset);
}
/**
@@ -1261,14 +1257,10 @@ public Date getMoladAsDate() {
* @return the Date representing the moment 3 days after the molad.
*
* @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getTchilasZmanKidushLevana3Days()
- * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getTchilasZmanKidushLevana3Days(Date, Date)
- */
- public Date getTchilasZmanKidushLevana3Days() {
- Date molad = getMoladAsDate();
- Calendar cal = Calendar.getInstance();
- cal.setTime(molad);
- cal.add(Calendar.HOUR, 72); // 3 days after the molad
- return cal.getTime();
+ * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getTchilasZmanKidushLevana3Days(Instant, Instant)
+ */
+ public Instant getTchilasZmanKidushLevana3Days() {
+ return getMoladAsInstant().plus(Duration.ofHours(72)); // 3 days after the molad
}
/**
@@ -1281,14 +1273,10 @@ public Date getTchilasZmanKidushLevana3Days() {
* @return the Date representing the moment 7 days after the molad.
*
* @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getTchilasZmanKidushLevana7Days()
- * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getTchilasZmanKidushLevana7Days(Date, Date)
- */
- public Date getTchilasZmanKidushLevana7Days() {
- Date molad = getMoladAsDate();
- Calendar cal = Calendar.getInstance();
- cal.setTime(molad);
- cal.add(Calendar.HOUR, 168); // 7 days after the molad
- return cal.getTime();
+ * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getTchilasZmanKidushLevana7Days(Instant, Instant)
+ */
+ public Instant getTchilasZmanKidushLevana7Days() {
+ return getMoladAsInstant().plus(Duration.ofHours(168)); // 7 days after the molad
}
/**
@@ -1304,20 +1292,20 @@ public Date getTchilasZmanKidushLevana7Days() {
*
* @see #getSofZmanKidushLevana15Days()
* @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getSofZmanKidushLevanaBetweenMoldos()
- * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getSofZmanKidushLevanaBetweenMoldos(Date, Date)
- */
- public Date getSofZmanKidushLevanaBetweenMoldos() {
- Date molad = getMoladAsDate();
- Calendar cal = Calendar.getInstance();
- cal.setTime(molad);
- // add half the time between molad and molad (half of 29 days, 12 hours and 793 chalakim (44 minutes, 3.3
- // seconds), or 14 days, 18 hours, 22 minutes and 666 milliseconds). Add it as hours, not days, to avoid
- // DST/ST crossover issues.
- cal.add(Calendar.HOUR, (24 * 14) + 18);
- cal.add(Calendar.MINUTE, 22);
- cal.add(Calendar.SECOND, 1);
- cal.add(Calendar.MILLISECOND, 666);
- return cal.getTime();
+ * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getSofZmanKidushLevanaBetweenMoldos(Instant, Instant)
+ */
+ public Instant getSofZmanKidushLevanaBetweenMoldos() {
+ Instant molad = getMoladAsInstant();
+
+ // Duration for half of the lunar month:
+ // 14 days, 18 hours, 22 minutes, 1 second, 666 milliseconds
+ Duration halfLunarMonth = Duration.ofDays(14)
+ .plusHours(18)
+ .plusMinutes(22)
+ .plusSeconds(1)
+ .plusMillis(666);
+
+ return molad.plus(halfLunarMonth);
}
/**
@@ -1335,14 +1323,10 @@ public Date getSofZmanKidushLevanaBetweenMoldos() {
* @return the Date representing the moment 15 days after the molad.
* @see #getSofZmanKidushLevanaBetweenMoldos()
* @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getSofZmanKidushLevana15Days()
- * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getSofZmanKidushLevana15Days(Date, Date)
- */
- public Date getSofZmanKidushLevana15Days() {
- Date molad = getMoladAsDate();
- Calendar cal = Calendar.getInstance();
- cal.setTime(molad);
- cal.add(Calendar.HOUR, 24 * 15); //15 days after the molad. Add it as hours, not days, to avoid DST/ST crossover issues.
- return cal.getTime();
+ * @see com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getSofZmanKidushLevana15Days(Instant, Instant)
+ */
+ public Instant getSofZmanKidushLevana15Days() {
+ return getMoladAsInstant().plus(Duration.ofHours(24 * 15));
}
/**
@@ -1381,9 +1365,9 @@ public Daf getDafYomiYerushalmi() {
*
* @return the number of elapsed days since tekufas Tishrei.
*
- * @see #isVeseinTalUmatarStartDate()
- * @see #isVeseinTalUmatarStartingTonight()
- * @see #isVeseinTalUmatarRecited()
+ * @see com.kosherjava.zmanim.hebrewcalendar.TefilaRules#isVeseinTalUmatarStartDate(JewishCalendar)
+ * @see com.kosherjava.zmanim.hebrewcalendar.TefilaRules#isVeseinTalUmatarStartingTonight(JewishCalendar)
+ * @see com.kosherjava.zmanim.hebrewcalendar.TefilaRules#isYaalehVeyavoRecited(JewishCalendar)
*/
public int getTekufasTishreiElapsedDays() {
// Days since Rosh Hashana year 1. Add 1/2 day as the first tekufas tishrei was 9 hours into the day. This allows all
@@ -1393,185 +1377,6 @@ public int getTekufasTishreiElapsedDays() {
double solar = (getJewishYear() - 1) * 365.25;
return (int) Math.floor(days - solar);
}
-
- /**
- * Returns if it is the Jewish day (starting the evening before) to start reciting Vesein Tal Umatar
- * Livracha (Sheailas Geshamim). In Israel this is the 7th day of Marcheshvan. Outside
- * Israel recitation starts on the evening of December 4th (or 5th if it is the year before a civil leap year)
- * in the 21st century and shifts a day forward every century not evenly divisible by 400. This method will
- * return true if vesein tal umatar on the current Jewish date that starts on the previous night, so
- * Dec 5/6 will be returned by this method in the 21st century. vesein tal umatar is not recited on
- * Shabbos and the start date will be delayed a day when the start day is on a Shabbos (this
- * can only occur out of Israel).
- *
- * @deprecated Use {@link TefilaRules#isVeseinTalUmatarStartDate(JewishCalendar)} instead. This method will be
- * removed in the v3.0 release.
- *
- * @return true if it is the first Jewish day (starting the prior evening of reciting Vesein Tal Umatar
- * Livracha (Sheailas Geshamim)).
- *
- * @see #isVeseinTalUmatarStartingTonight()
- * @see #isVeseinTalUmatarRecited()
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isVeseinTalUmatarStartDate() {
- if (inIsrael) {
- // The 7th Cheshvan can't occur on Shabbos, so always return true for 7 Cheshvan
- return getJewishMonth() == CHESHVAN && getJewishDayOfMonth() == 7;
- } else {
- if (getDayOfWeek() == Calendar.SATURDAY) { //Not recited on Friday night
- return false;
- }
- if (getDayOfWeek() == Calendar.SUNDAY) { // When starting on Sunday, it can be the start date or delayed from Shabbos
- return getTekufasTishreiElapsedDays() == 48 || getTekufasTishreiElapsedDays() == 47;
- } else {
- return getTekufasTishreiElapsedDays() == 47;
- }
- }
- }
-
- /**
- * Returns true if tonight is the first night to start reciting Vesein Tal Umatar Livracha (
- * Sheailas Geshamim). In Israel this is the 7th day of Marcheshvan (so the 6th will return
- * true). Outside Israel recitation starts on the evening of December 4th (or 5th if it is the year before a
- * civil leap year) in the 21st century and shifts a day forward every century not evenly divisible by 400.
- * Vesein tal umatar is not recited on Shabbos and the start date will be delayed a day when
- * the start day is on a Shabbos (this can only occur out of Israel).
- *
- * @deprecated Use {@link TefilaRules#isVeseinTalUmatarStartingTonight(JewishCalendar)} instead. This method
- * will be removed in the v3.0 release.
- *
- * @return true if it is the first Jewish day (starting the prior evening of reciting Vesein Tal Umatar
- * Livracha (Sheailas Geshamim)).
- *
- * @see #isVeseinTalUmatarStartDate()
- * @see #isVeseinTalUmatarRecited()
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isVeseinTalUmatarStartingTonight() {
- if (inIsrael) {
- // The 7th Cheshvan can't occur on Shabbos, so always return true for 6 Cheshvan
- return getJewishMonth() == CHESHVAN && getJewishDayOfMonth() == 6;
- } else {
- if (getDayOfWeek() == Calendar.FRIDAY) { //Not recited on Friday night
- return false;
- }
- if (getDayOfWeek() == Calendar.SATURDAY) { // When starting on motzai Shabbos, it can be the start date or delayed from Friday night
- return getTekufasTishreiElapsedDays() == 47 || getTekufasTishreiElapsedDays() == 46;
- } else {
- return getTekufasTishreiElapsedDays() == 46;
- }
- }
- }
-
- /**
- * Returns if Vesein Tal Umatar Livracha (Sheailas Geshamim) is recited. This will return
- * true for the entire season, even on Shabbos when it is not recited.
- *
- * @deprecated Use {@link TefilaRules#isVeseinTalUmatarRecited(JewishCalendar)} instead. This method will
- * be removed in the v3.0 release.
- *
- * @return true if Vesein Tal Umatar Livracha (Sheailas Geshamim) is recited.
- *
- * @see #isVeseinTalUmatarStartDate()
- * @see #isVeseinTalUmatarStartingTonight()
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isVeseinTalUmatarRecited() {
- if (getJewishMonth() == NISSAN && getJewishDayOfMonth() < 15) {
- return true;
- }
- if (getJewishMonth() < CHESHVAN) {
- return false;
- }
- if (inIsrael) {
- return getJewishMonth() != CHESHVAN || getJewishDayOfMonth() >= 7;
- } else {
- return getTekufasTishreiElapsedDays() >= 47;
- }
- }
-
- /**
- * Returns if Vesein Beracha is recited. It is recited from 15 Nissan to the point that {@link
- * #isVeseinTalUmatarRecited() vesein tal umatar is recited}.
- *
- * @deprecated Use {@link TefilaRules#isVeseinBerachaRecited(JewishCalendar)} instead. This method will be
- * removed in the v3.0 release.
- *
- * @return true if Vesein Beracha is recited.
- *
- * @see #isVeseinTalUmatarRecited()
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isVeseinBerachaRecited() {
- return !isVeseinTalUmatarRecited();
- }
-
- /**
- * Returns if the date is the start date for reciting Mashiv Haruach Umorid Hageshem. The date is 22 Tishrei.
- *
- * @deprecated Use {@link TefilaRules#isMashivHaruachStartDate(JewishCalendar)} instead. This method will be
- * removed in the v3.0 release.
- *
- * @return true if the date is the start date for reciting Mashiv Haruach Umorid Hageshem.
- *
- * @see #isMashivHaruachEndDate()
- * @see #isMashivHaruachRecited()
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isMashivHaruachStartDate() {
- return getJewishMonth() == TISHREI && getJewishDayOfMonth() == 22;
- }
-
- /**
- * Returns if the date is the end date for reciting Mashiv Haruach Umorid Hageshem. The date is 15 Nissan.
- *
- * @deprecated Use {@link TefilaRules#isMashivHaruachEndDate(JewishCalendar)} instead. This method will be
- * removed in the v3.0 release.
- *
- * @return true if the date is the end date for reciting Mashiv Haruach Umorid Hageshem.
- *
- * @see #isMashivHaruachStartDate()
- * @see #isMashivHaruachRecited()
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isMashivHaruachEndDate() {
- return getJewishMonth() == NISSAN && getJewishDayOfMonth() == 15;
- }
-
- /**
- * Returns if Mashiv Haruach Umorid Hageshem is recited. This period starts on 22 Tishrei and ends
- * on the 15th day of Nissan.
- *
- * @deprecated Use {@link TefilaRules#isMashivHaruachRecited(JewishCalendar)} instead. This method will be
- * removed in the v3.0 release.
- *
- * @return true if Mashiv Haruach Umorid Hageshem is recited.
- *
- * @see #isMashivHaruachStartDate()
- * @see #isMashivHaruachEndDate()
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isMashivHaruachRecited() {
- JewishDate startDate = new JewishDate(getJewishYear(), TISHREI, 22);
- JewishDate endDate = new JewishDate(getJewishYear(), NISSAN, 15);
- return compareTo(startDate) > 0 && compareTo(endDate) < 0;
- }
-
- /**
- * Returns if Morid Hatal (or the lack of reciting Mashiv Haruach following nussach Ashkenaz) is recited.
- * This period starts on 22 Tishrei and ends on the 15th day of
- * Nissan.
- *
- * @deprecated Use {@link TefilaRules#isMoridHatalRecited(JewishCalendar)} instead. This method will be
- * removed in the v3.0 release.
- *
- * @return true if Morid Hatal (or the lack of reciting Mashiv Haruach following nussach Ashkenaz) is recited.
- */
- @Deprecated // (forRemoval=true) // add back once Java 9 is the minimum supported version
- public boolean isMoridHatalRecited() {
- return !isMashivHaruachRecited() || isMashivHaruachStartDate() || isMashivHaruachEndDate();
- }
/**
* Returns true if the current day is Isru Chag. The method returns true for the day following Pesach
@@ -1593,9 +1398,9 @@ public boolean equals(Object object) {
if (this == object) {
return true;
}
- if (!(object instanceof JewishCalendar)) {
- return false;
- }
+ if (object == null || getClass() != object.getClass()) {
+ return false;
+ }
JewishCalendar jewishCalendar = (JewishCalendar) object;
return getAbsDate() == jewishCalendar.getAbsDate() && getInIsrael() == jewishCalendar.getInIsrael();
}
@@ -1605,9 +1410,8 @@ public boolean equals(Object object) {
* @see Object#hashCode()
*/
public int hashCode() {
- int result = 17;
- result = 37 * result + getClass().hashCode(); // needed or this and subclasses will return identical hash
- result += 37 * result + getAbsDate() + (getInIsrael() ? 1 : 3);
- return result;
+ int result = Integer.hashCode(getAbsDate());
+ result = 31 * result + Boolean.hashCode(getInIsrael());
+ return result;
}
}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java
index eb47d309..d3d0df44 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java
@@ -1,7 +1,8 @@
/*
* Zmanim Java API
- * Copyright (C) 2011 - 2024 Eliyahu Hershfeld
+ * Copyright (C) 2011 - 2026 Eliyahu Hershfeld
* Copyright (C) September 2002 Avrom Finkelstien
+ * Copyright (C) 2026 Moshe Dicker
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -17,12 +18,11 @@
package com.kosherjava.zmanim.hebrewcalendar;
import java.time.LocalDate;
-import java.util.Date;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
+import java.time.YearMonth;
+import java.time.ZonedDateTime;
/**
- * The JewishDate is the base calendar class, that supports maintenance of a {@link java.util.GregorianCalendar}
+ * The JewishDate is the base calendar class, that supports maintenance of a {@link LocalDate}
* instance along with the corresponding Jewish date. This class can use the standard Java Date and Calendar
* classes for setting and maintaining the dates, but it does not subclass these classes or use them internally
* in any calculations. This class also does not have a concept of a time (which the Date class does). Please
@@ -32,1538 +32,1254 @@
* href="http://en.wikipedia.org/wiki/Hillel_II">Hillel II's (Hakatan's) calendar (4119 in the Jewish Calendar / 359
* CE Julian as recorded by Rav Hai Gaon) would be just an
* approximation.
- *
+ *
* This open source Java code was written by Avrom Finkelstien from his C++
* code. It was refactored to fit the KosherJava Zmanim API with simplification of the code, enhancements and some bug
* fixing.
- *
+ *
* Some of Avrom's original C++ code was translated from
* C/C++ code in
* Calendrical Calculations by Nachum Dershowitz and Edward M.
* Reingold, Software-- Practice & Experience, vol. 20, no. 9 (September, 1990), pp. 899- 928. Any method with the mark
* "ND+ER" indicates that the method was taken from this source with minor modifications.
- *
+ *
* If you are looking for a class that implements a Jewish calendar version of the Calendar class, one is available from
* the ICU (International Components for Unicode) project, formerly part of
* IBM's DeveloperWorks.
- *
+ *
* @see JewishCalendar
* @see HebrewDateFormatter
* @see java.util.Date
* @see java.util.Calendar
* @author © Avrom Finkelstien 2002
- * @author © Eliyahu Hershfeld 2011 - 2024
+ * @author © Moshe Dicker 2026
+ * @author © Eliyahu Hershfeld 2011 - 2026
*/
public class JewishDate implements Comparable, Cloneable {
- /**
- * Value of the month field indicating Nissan, the first numeric month of the year in the Jewish calendar. With the
- * year starting at {@link #TISHREI}, it would actually be the 7th (or 8th in a {@link #isJewishLeapYear() leap
- * year}) month of the year.
- */
- public static final int NISSAN = 1;
-
- /**
- * Value of the month field indicating Iyar, the second numeric month of the year in the Jewish calendar. With the
- * year starting at {@link #TISHREI}, it would actually be the 8th (or 9th in a {@link #isJewishLeapYear() leap
- * year}) month of the year.
- */
- public static final int IYAR = 2;
-
- /**
- * Value of the month field indicating Sivan, the third numeric month of the year in the Jewish calendar. With the
- * year starting at {@link #TISHREI}, it would actually be the 9th (or 10th in a {@link #isJewishLeapYear() leap
- * year}) month of the year.
- */
- public static final int SIVAN = 3;
-
- /**
- * Value of the month field indicating Tammuz, the fourth numeric month of the year in the Jewish calendar. With the
- * year starting at {@link #TISHREI}, it would actually be the 10th (or 11th in a {@link #isJewishLeapYear() leap
- * year}) month of the year.
- */
- public static final int TAMMUZ = 4;
-
- /**
- * Value of the month field indicating Av, the fifth numeric month of the year in the Jewish calendar. With the year
- * starting at {@link #TISHREI}, it would actually be the 11th (or 12th in a {@link #isJewishLeapYear() leap year})
- * month of the year.
- */
- public static final int AV = 5;
-
- /**
- * Value of the month field indicating Elul, the sixth numeric month of the year in the Jewish calendar. With the
- * year starting at {@link #TISHREI}, it would actually be the 12th (or 13th in a {@link #isJewishLeapYear() leap
- * year}) month of the year.
- */
- public static final int ELUL = 6;
-
- /**
- * Value of the month field indicating Tishrei, the seventh numeric month of the year in the Jewish calendar. With
- * the year starting at this month, it would actually be the 1st month of the year.
- */
- public static final int TISHREI = 7;
-
- /**
- * Value of the month field indicating Cheshvan/marcheshvan, the eighth numeric month of the year in the Jewish
- * calendar. With the year starting at {@link #TISHREI}, it would actually be the 2nd month of the year.
- */
- public static final int CHESHVAN = 8;
-
- /**
- * Value of the month field indicating Kislev, the ninth numeric month of the year in the Jewish calendar. With the
- * year starting at {@link #TISHREI}, it would actually be the 3rd month of the year.
- */
- public static final int KISLEV = 9;
-
- /**
- * Value of the month field indicating Teves, the tenth numeric month of the year in the Jewish calendar. With the
- * year starting at {@link #TISHREI}, it would actually be the 4th month of the year.
- */
- public static final int TEVES = 10;
-
- /**
- * Value of the month field indicating Shevat, the eleventh numeric month of the year in the Jewish calendar. With
- * the year starting at {@link #TISHREI}, it would actually be the 5th month of the year.
- */
- public static final int SHEVAT = 11;
-
- /**
- * Value of the month field indicating Adar (or Adar I in a {@link #isJewishLeapYear() leap year}), the twelfth
- * numeric month of the year in the Jewish calendar. With the year starting at {@link #TISHREI}, it would actually
- * be the 6th month of the year.
- */
- public static final int ADAR = 12;
-
- /**
- * Value of the month field indicating Adar II, the leap (intercalary or embolismic) thirteenth (Undecimber) numeric
- * month of the year added in Jewish {@link #isJewishLeapYear() leap year}). The leap years are years 3, 6, 8, 11,
- * 14, 17 and 19 of a 19-year cycle. With the year starting at {@link #TISHREI}, it would actually be the 7th month
- * of the year.
- */
- public static final int ADAR_II = 13;
-
- /**
- * the Jewish epoch using the RD (Rata Die/Fixed Date or Reingold Dershowitz) day used in Calendrical Calculations.
- * Day 1 is January 1, 0001 of the Gregorian calendar
- */
- private static final int JEWISH_EPOCH = -1373429;
-
- /** The number of chalakim (18) in a minute.*/
- private static final int CHALAKIM_PER_MINUTE = 18;
- /** The number of chalakim (1080) in an hour.*/
- private static final int CHALAKIM_PER_HOUR = 1080;
- /** The number of chalakim (25,920) in a 24-hour day .*/
- private static final int CHALAKIM_PER_DAY = 25920; // 24 * 1080
- /** The number of chalakim in an average Jewish month. A month has 29 days, 12 hours and 793
- * chalakim (44 minutes and 3.3 seconds) for a total of 765,433 chalakim*/
- private static final long CHALAKIM_PER_MONTH = 765433; // (29 * 24 + 12) * 1080 + 793
- /**
- * Days from the beginning of Sunday till molad BaHaRaD. Calculated as 1 day, 5 hours and 204 chalakim =
- * (24 + 5) * 1080 + 204 = 31524
- */
- private static final int CHALAKIM_MOLAD_TOHU = 31524;
-
- /**
- * A short year where both {@link #CHESHVAN} and {@link #KISLEV} are 29 days.
- *
- * @see #getCheshvanKislevKviah()
- * @see HebrewDateFormatter#getFormattedKviah(int)
- */
- public static final int CHASERIM = 0;
-
- /**
- * An ordered year where {@link #CHESHVAN} is 29 days and {@link #KISLEV} is 30 days.
- *
- * @see #getCheshvanKislevKviah()
- * @see HebrewDateFormatter#getFormattedKviah(int)
- */
- public static final int KESIDRAN = 1;
-
- /**
- * A long year where both {@link #CHESHVAN} and {@link #KISLEV} are 30 days.
- *
- * @see #getCheshvanKislevKviah()
- * @see HebrewDateFormatter#getFormattedKviah(int)
- */
- public static final int SHELAIMIM = 2;
-
- /** the internal Jewish month.*/
- private int jewishMonth;
- /** the internal Jewish day.*/
- private int jewishDay;
- /** the internal Jewish year.*/
- private int jewishYear;
- /** the internal count of molad hours.*/
- private int moladHours;
- /** the internal count of molad minutes.*/
- private int moladMinutes;
- /** the internal count of molad chalakim.*/
- private int moladChalakim;
-
- /**
- * Returns the molad hours. Only a JewishDate object populated with {@link #getMolad()},
- * {@link #setJewishDate(int, int, int, int, int, int)} or {@link #setMoladHours(int)} will have this field
- * populated. A regular JewishDate object will have this field set to 0.
- *
- * @return the molad hours
- * @see #setMoladHours(int)
- * @see #getMolad()
- * @see #setJewishDate(int, int, int, int, int, int)
- */
- public int getMoladHours() {
- return moladHours;
- }
-
- /**
- * Sets the molad hours.
- *
- * @param moladHours
- * the molad hours to set
- * @see #getMoladHours()
- * @see #getMolad()
- * @see #setJewishDate(int, int, int, int, int, int)
- *
- */
- public void setMoladHours(int moladHours) {
- this.moladHours = moladHours;
- }
-
- /**
- * Returns the molad minutes. Only an object populated with {@link #getMolad()},
- * {@link #setJewishDate(int, int, int, int, int, int)} or or {@link #setMoladMinutes(int)} will have these fields
- * populated. A regular JewishDate object will have this field set to 0.
- *
- * @return the molad minutes
- * @see #setMoladMinutes(int)
- * @see #getMolad()
- * @see #setJewishDate(int, int, int, int, int, int)
- */
- public int getMoladMinutes() {
- return moladMinutes;
- }
-
- /**
- * Sets the molad minutes. The expectation is that the traditional minute-less chalakim will be broken out to
- * minutes and {@link #setMoladChalakim(int) chalakim / parts} , so 793 (TaShTZaG) parts would have the minutes set to
- * 44 and chalakim to 1.
- *
- * @param moladMinutes
- * the molad minutes to set
- * @see #getMoladMinutes()
- * @see #setMoladChalakim(int)
- * @see #getMolad()
- * @see #setJewishDate(int, int, int, int, int, int)
- *
- */
- public void setMoladMinutes(int moladMinutes) {
- this.moladMinutes = moladMinutes;
- }
-
- /**
- * Sets the molad chalakim/parts. The expectation is that the traditional minute-less chalakim will be broken
- * out to {@link #setMoladMinutes(int) minutes} and chalakim, so 793 (TaShTZaG) parts would have the minutes set to 44 and
- * chalakim to 1.
- *
- * @param moladChalakim
- * the molad chalakim / parts to set
- * @see #getMoladChalakim()
- * @see #setMoladMinutes(int)
- * @see #getMolad()
- * @see #setJewishDate(int, int, int, int, int, int)
- *
- */
- public void setMoladChalakim(int moladChalakim) {
- this.moladChalakim = moladChalakim;
- }
-
- /**
- * Returns the molad chalakim / parts. Only an object populated with {@link #getMolad()},
- * {@link #setJewishDate(int, int, int, int, int, int)} or or {@link #setMoladChalakim(int)} will have these fields
- * populated. A regular JewishDate object will have this field set to 0.
- *
- * @return the molad chalakim / parts
- * @see #setMoladChalakim(int)
- * @see #getMolad()
- * @see #setJewishDate(int, int, int, int, int, int)
- */
- public int getMoladChalakim() {
- return moladChalakim;
- }
-
- /**
- * Returns the last day in a gregorian month
- *
- * @param month
- * the Gregorian month
- * @return the last day of the Gregorian month
- */
- int getLastDayOfGregorianMonth(int month) {
- return getLastDayOfGregorianMonth(month, gregorianYear);
- }
-
- /**
- * Returns is the year passed in is a Gregorian leap year.
- * @param year the Gregorian year
- * @return if the year in question is a leap year.
- */
- boolean isGregorianLeapYear(int year) {
- return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
- }
-
- /**
- * The month, where 1 == January, 2 == February, etc... Note that this is different than Java's Calendar class
- * where January == 0.
- */
- private int gregorianMonth;
-
- /** The day of the Gregorian month */
- private int gregorianDayOfMonth;
-
- /** The Gregorian year */
- private int gregorianYear;
-
- /** 1 == Sunday, 2 == Monday, etc... */
- private int dayOfWeek;
-
- /** Returns the absolute date (days since January 1, 0001 of the Gregorian calendar).
- * @see #getAbsDate()
- * @see #absDateToJewishDate()
- */
- private int gregorianAbsDate;
-
- /**
- * Returns the number of days in a given month in a given month and year.
- *
- * @param month
- * the month. As with other cases in this class, this is 1-based, not zero-based.
- * @param year
- * the year (only impacts February)
- * @return the number of days in the month in the given year
- */
- private static int getLastDayOfGregorianMonth(int month, int year) {
- switch (month) {
- case 2:
- if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
- return 29;
- } else {
- return 28;
- }
- case 4:
- case 6:
- case 9:
- case 11:
- return 30;
- default:
- return 31;
- }
- }
-
- /**
- * Computes the Gregorian date from the absolute date. ND+ER
- * @param absDate the absolute date
- */
- private void absDateToDate(int absDate) {
- int year = absDate / 366; // Search forward year by year from approximate year
- while (absDate >= gregorianDateToAbsDate(year + 1, 1, 1)) {
- year++;
- }
-
- int month = 1; // Search forward month by month from January
- while (absDate > gregorianDateToAbsDate(year, month, getLastDayOfGregorianMonth(month, year))) {
- month++;
- }
-
- int dayOfMonth = absDate - gregorianDateToAbsDate(year, month, 1) + 1;
- setInternalGregorianDate(year, month, dayOfMonth);
- }
-
- /**
- * Returns the absolute date (days since January 1, 0001 of the Gregorian calendar).
- *
- * @return the number of days since January 1, 1
- */
- public int getAbsDate() {
- return gregorianAbsDate;
- }
-
- /**
- * Computes the absolute date from a Gregorian date. ND+ER
- *
- * @param year
- * the Gregorian year
- * @param month
- * the Gregorian month. Unlike the Java Calendar where January has the value of 0,This expects a 1 for
- * January
- * @param dayOfMonth
- * the day of the month (1st, 2nd, etc...)
- * @return the absolute Gregorian day
- */
- private static int gregorianDateToAbsDate(int year, int month, int dayOfMonth) {
- int absDate = dayOfMonth;
- for (int m = month - 1; m > 0; m--) {
- absDate += getLastDayOfGregorianMonth(m, year); // days in prior months of the year
- }
- return (absDate // days this year
- + 365 * (year - 1) // days in previous years ignoring leap days
- + (year - 1) / 4 // Julian leap days before this year
- - (year - 1) / 100 // minus prior century years
- + (year - 1) / 400); // plus prior years divisible by 400
- }
-
- /**
- * Returns if the year is a Jewish leap year. Years 3, 6, 8, 11, 14, 17 and 19 in the 19-year cycle are leap years.
- *
- * @param year
- * the Jewish year.
- * @return true if it is a leap year
- * @see #isJewishLeapYear()
- */
- private static boolean isJewishLeapYear(int year) {
- return ((7 * year) + 1) % 19 < 7;
- }
-
- /**
- * Returns if the year the calendar is set to is a Jewish leap year. Years 3, 6, 8, 11, 14, 17 and 19 in the 19-year
- * cycle are leap years.
- *
- * @return true if it is a leap year
- * @see #isJewishLeapYear(int)
- */
- public boolean isJewishLeapYear() {
- return isJewishLeapYear(getJewishYear());
- }
-
- /**
- * Returns the last month of a given Jewish year. This will be 12 on a non {@link #isJewishLeapYear(int) leap year}
- * or 13 on a leap year.
- *
- * @param year
- * the Jewish year.
- * @return 12 on a non leap year or 13 on a leap year
- * @see #isJewishLeapYear(int)
- */
- private static int getLastMonthOfJewishYear(int year) {
- return isJewishLeapYear(year) ? ADAR_II : ADAR;
- }
-
- /**
- * Returns the number of days elapsed from the Sunday prior to the start of the Jewish calendar to the mean
- * conjunction of Tishri of the Jewish year.
- *
- * @param year
- * the Jewish year
- * @return the number of days elapsed from prior to the molad Tohu BaHaRaD (Be = Monday, Ha = 5
- * hours and RaD = 204 chalakim / parts) prior to the start of the Jewish calendar, to
- * the mean conjunction of Tishri of the Jewish year. BeHaRaD is 23:11:20 on Sunday night(5 hours 204/1080
- * chalakim after sunset on Sunday evening).
- */
- public static int getJewishCalendarElapsedDays(int year) {
- long chalakimSince = getChalakimSinceMoladTohu(year, TISHREI);
- int moladDay = (int) (chalakimSince / (long) CHALAKIM_PER_DAY);
- int moladParts = (int) (chalakimSince - moladDay * (long) CHALAKIM_PER_DAY);
- // delay Rosh Hashana for the 4 dechiyos
- return addDechiyos(year, moladDay, moladParts);
- }
-
- /**
- * Adds the 4 dechiyos for molad Tishrei. These are:
- *
- * - Lo ADU Rosh - Rosh Hashana can't fall on a Sunday, Wednesday or Friday. If the molad fell on one
- * of these days, Rosh Hashana is delayed to the following day.
- * - Molad Zaken - If the molad of Tishrei falls after 12 noon, Rosh Hashana is delayed to the following
- * day. If the following day is ADU, it will be delayed an additional day.
- * - GaTRaD - If on a non leap year the molad of Tishrei falls on a Tuesday (Ga) on or after 9 hours
- * (T) and (RaD 204 chalakim it is delayed till Thursday (one day delay, plus one day for
- * Lo ADU Rosh)
- * - BeTuTaKPaT - if the year following a leap year falls on a Monday (Be) on or after 15 hours
- * (Tu) and 589 chalakim (TaKPaT) it is delayed till Tuesday
- *
- *
- * @param year the year
- * @param moladDay the molad day
- * @param moladParts the molad parts
- * @return the number of elapsed days in the JewishCalendar adjusted for the 4 dechiyos.
- */
- private static int addDechiyos(int year, int moladDay, int moladParts) {
- int roshHashanaDay = moladDay; // if no dechiyos
- // delay Rosh Hashana for the dechiyos of the Molad - new moon 1 - Molad Zaken, 2- GaTRaD 3- BeTuTaKPaT
- if ((moladParts >= 19440) // Dechiya of Molad Zaken - molad is >= midday (18 hours * 1080 chalakim)
- || (((moladDay % 7) == 2) // start Dechiya of GaTRaD - Ga = is a Tuesday
- && (moladParts >= 9924) // TRaD = 9 hours, 204 parts or later (9 * 1080 + 204)
- && !isJewishLeapYear(year)) // of a non-leap year - end Dechiya of GaTRaD
- || (((moladDay % 7) == 1) // start Dechiya of BeTuTaKPaT - Be = is on a Monday
- && (moladParts >= 16789) // TUTaKPaT part of BeTuTaKPaT = 15 hours, 589 parts or later (15 * 1080 + 589)
- && (isJewishLeapYear(year - 1)))) { // in a year following a leap year - end Dechiya of BeTuTaKPaT
- roshHashanaDay += 1; // Then postpone Rosh HaShanah one day
- }
- // start 4th Dechiya - Lo ADU Rosh - Rosh Hashana can't occur on A- sunday, D- Wednesday, U - Friday
- if (((roshHashanaDay % 7) == 0)// If Rosh HaShanah would occur on Sunday,
- || ((roshHashanaDay % 7) == 3) // or Wednesday,
- || ((roshHashanaDay % 7) == 5)) { // or Friday - end 4th Dechiya - Lo ADU Rosh
- roshHashanaDay = roshHashanaDay + 1; // Then postpone it one (more) day
- }
- return roshHashanaDay;
- }
-
- /**
- * Returns the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
- * to the year and month passed in.
- *
- * @param year
- * the Jewish year
- * @param month
- * the Jewish month the Jewish month, with the month numbers starting from Nissan. Use the JewishDate
- * constants such as {@link JewishDate#TISHREI}.
- * @return the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
- */
- private static long getChalakimSinceMoladTohu(int year, int month) {
- // Jewish lunar month = 29 days, 12 hours and 793 chalakim
- // chalakim since Molad Tohu BeHaRaD - 1 day, 5 hours and 204 chalakim
- int monthOfYear = getJewishMonthOfYear(year, month);
- int monthsElapsed = (235 * ((year - 1) / 19)) // Months in complete 19-year lunar (Metonic) cycles so far
- + (12 * ((year - 1) % 19)) // Regular months in this cycle
- + ((7 * ((year - 1) % 19) + 1) / 19) // Leap months this cycle
- + (monthOfYear - 1); // add elapsed months till the start of the molad of the month
- // return chalakim prior to BeHaRaD + number of chalakim since
- return CHALAKIM_MOLAD_TOHU + (CHALAKIM_PER_MONTH * monthsElapsed);
- }
-
- /**
- * Returns the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
- * to the Jewish year and month that this Object is set to.
- *
- * @return the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
- */
- public long getChalakimSinceMoladTohu() {
- return getChalakimSinceMoladTohu(jewishYear, jewishMonth);
- }
-
- /**
- * Converts the {@link JewishDate#NISSAN} based constants used by this class to numeric month starting from
- * {@link JewishDate#TISHREI}. This is required for molad calculations.
- *
- * @param year
- * The Jewish year
- * @param month
- * The Jewish Month
- * @return the Jewish month of the year starting with Tishrei
- */
- private static int getJewishMonthOfYear(int year, int month) {
- boolean isLeapYear = isJewishLeapYear(year);
- return (month + (isLeapYear ? 6 : 5)) % (isLeapYear ? 13 : 12) + 1;
- }
-
- /**
- * Validates the components of a Jewish date for validity. It will throw an {@link IllegalArgumentException} if the Jewish
- * date is earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a {@link #isJewishLeapYear(int)
- * leap year}), the day of month is < 1 or > 30, an hour < 0 or > 23, a minute < 0 or > 59 or
- * chalakim < 0 or > 17. For 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).
- *
- * @param year
- * the Jewish year to validate. It will reject any year <= 3761 (lower than the year 1 Gregorian).
- * @param month
- * the Jewish month to validate. It will reject a month < 1 or > 12 (or 13 on a leap year) .
- * @param dayOfMonth
- * the day of the Jewish month to validate. It will reject any value < 1 or > 30 TODO: check calling
- * methods to see if there is any reason that the class can validate that 30 is invalid for some months.
- * @param hours
- * the hours (for molad calculations). It will reject an hour < 0 or > 23
- * @param minutes
- * the minutes (for molad calculations). It will reject a minute < 0 or > 59
- * @param chalakim
- * the chalakim / parts (for molad calculations). It will reject a chalakim < 0 or >
- * 17. For larger numbers 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)
- *
- * @throws IllegalArgumentException
- * if a Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a leap year),
- * the day of month is < 1 or > 30, an hour < 0 or > 23, a minute < 0 or > 59 or chalakim
- * < 0 or > 17. For 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).
- */
- private static void validateJewishDate(int year, int month, int dayOfMonth, int hours, int minutes, int chalakim) {
- if (month < NISSAN || month > getLastMonthOfJewishYear(year)) {
- throw new IllegalArgumentException("The Jewish month has to be between 1 and 12 (or 13 on a leap year). "
- + month + " is invalid for the year " + year + ".");
- }
- if (dayOfMonth < 1 || dayOfMonth > 30) {
- throw new IllegalArgumentException("The Jewish day of month can't be < 1 or > 30. " + dayOfMonth
- + " is invalid.");
- }
- // reject dates prior to 18 Teves, 3761 (1/1/1 AD). This restriction can be relaxed if the date coding is
- // changed/corrected
- if ((year < 3761) || (year == 3761 && (month >= TISHREI && month < TEVES))
- || (year == 3761 && month == TEVES && dayOfMonth < 18)) {
- throw new IllegalArgumentException(
- "A Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian) can't be set. " + year + ", " + month
- + ", " + dayOfMonth + " is invalid.");
- }
- if (hours < 0 || hours > 23) {
- throw new IllegalArgumentException("Hours < 0 or > 23 can't be set. " + hours + " is invalid.");
- }
-
- if (minutes < 0 || minutes > 59) {
- throw new IllegalArgumentException("Minutes < 0 or > 59 can't be set. " + minutes + " is invalid.");
- }
-
- if (chalakim < 0 || chalakim > 17) {
- throw new IllegalArgumentException(
- "Chalakim/parts < 0 or > 17 can't be set. "
- + chalakim
- + " is invalid. For larger numbers 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)");
- }
- }
-
- /**
- * Validates the components of a Gregorian date for validity. It will throw an {@link IllegalArgumentException} if a
- * year of < 1, a month < 0 or > 11 or a day of month < 1 is passed in.
- *
- * @param year
- * the Gregorian year to validate. It will reject any year < 1.
- * @param month
- * the Gregorian month number to validate. It will enforce that the month is between 0 - 11 like a
- * {@link GregorianCalendar}, where {@link Calendar#JANUARY} has a value of 0.
- * @param dayOfMonth
- * the day of the Gregorian month to validate. It will reject any value < 1, but will allow values > 31
- * since calling methods will simply set it to the maximum for that month. TODO: check calling methods to
- * see if there is any reason that the class needs days > the maximum.
- * @throws IllegalArgumentException
- * if a year of < 1, a month < 0 or > 11 or a day of month < 1 is passed in
- * @see #validateGregorianYear(int)
- * @see #validateGregorianMonth(int)
- * @see #validateGregorianDayOfMonth(int)
- */
- private static void validateGregorianDate(int year, int month, int dayOfMonth) {
- validateGregorianMonth(month);
- validateGregorianDayOfMonth(dayOfMonth);
- validateGregorianYear(year);
- }
-
- /**
- * Validates a Gregorian month for validity.
- *
- * @param month
- * the Gregorian month number to validate. It will enforce that the month is between 0 - 11 like a
- * {@link GregorianCalendar}, where {@link Calendar#JANUARY} has a value of 0.
- */
- private static void validateGregorianMonth(int month) {
- if (month > 11 || month < 0) {
- throw new IllegalArgumentException("The Gregorian month has to be between 0 - 11. " + month
- + " is invalid.");
- }
- }
-
- /**
- * Validates a Gregorian day of month for validity.
- *
- * @param dayOfMonth
- * the day of the Gregorian month to validate. It will reject any value < 1, but will allow values > 31
- * since calling methods will simply set it to the maximum for that month. TODO: check calling methods to
- * see if there is any reason that the class needs days > the maximum.
- */
- private static void validateGregorianDayOfMonth(int dayOfMonth) {
- if (dayOfMonth <= 0) {
- throw new IllegalArgumentException("The day of month can't be less than 1. " + dayOfMonth + " is invalid.");
- }
- }
-
- /**
- * Validates a Gregorian year for validity.
- *
- * @param year
- * the Gregorian year to validate. It will reject any year < 1.
- */
- private static void validateGregorianYear(int year) {
- if (year < 1) {
- throw new IllegalArgumentException("Years < 1 can't be calculated. " + year + " is invalid.");
- }
- }
-
- /**
- * Returns the number of days for a given Jewish year. ND+ER
- *
- * @param year
- * the Jewish year
- * @return the number of days for a given Jewish year.
- * @see #isCheshvanLong()
- * @see #isKislevShort()
- */
- public static int getDaysInJewishYear(int year) {
- return getJewishCalendarElapsedDays(year + 1) - getJewishCalendarElapsedDays(year);
- }
-
- /**
- * Returns the number of days for the current year that the calendar is set to.
- *
- * @return the number of days for the Object's current Jewish year.
- * @see #isCheshvanLong()
- * @see #isKislevShort()
- * @see #isJewishLeapYear()
- */
- public int getDaysInJewishYear() {
- return getDaysInJewishYear(getJewishYear());
- }
-
- /**
- * Returns if Cheshvan is long in a given Jewish year. The method name isLong is done since in a Kesidran (ordered)
- * year Cheshvan is short. ND+ER
- *
- * @param year
- * the year
- * @return true if Cheshvan is long in Jewish year.
- * @see #isCheshvanLong()
- * @see #getCheshvanKislevKviah()
- */
- private static boolean isCheshvanLong(int year) {
- return getDaysInJewishYear(year) % 10 == 5;
- }
-
- /**
- * Returns if Cheshvan is long (30 days VS 29 days) for the current year that the calendar is set to. The method
- * name isLong is done since in a Kesidran (ordered) year Cheshvan is short.
- *
- * @return true if Cheshvan is long for the current year that the calendar is set to
- * @see #isCheshvanLong()
- */
- public boolean isCheshvanLong() {
- return isCheshvanLong(getJewishYear());
- }
-
- /**
- * Returns if Kislev is short (29 days VS 30 days) in a given Jewish year. The method name isShort is done since in
- * a Kesidran (ordered) year Kislev is long. ND+ER
- *
- * @param year
- * the Jewish year
- * @return true if Kislev is short for the given Jewish year.
- * @see #isKislevShort()
- * @see #getCheshvanKislevKviah()
- */
- private static boolean isKislevShort(int year) {
- return getDaysInJewishYear(year) % 10 == 3;
- }
-
- /**
- * Returns if the Kislev is short for the year that this class is set to. The method name isShort is done since in a
- * Kesidran (ordered) year Kislev is long.
- *
- * @return true if Kislev is short for the year that this class is set to
- */
- public boolean isKislevShort() {
- return isKislevShort(getJewishYear());
- }
-
- /**
- * Returns the Cheshvan and Kislev kviah (whether a Jewish year is short, regular or long). It will return
- * {@link #SHELAIMIM} if both cheshvan and kislev are 30 days, {@link #KESIDRAN} if Cheshvan is 29 days and Kislev
- * is 30 days and {@link #CHASERIM} if both are 29 days.
- *
- * @return {@link #SHELAIMIM} if both cheshvan and kislev are 30 days, {@link #KESIDRAN} if Cheshvan is 29 days and
- * Kislev is 30 days and {@link #CHASERIM} if both are 29 days.
- * @see #isCheshvanLong()
- * @see #isKislevShort()
- */
- public int getCheshvanKislevKviah() {
- if (isCheshvanLong() && !isKislevShort()) {
- return SHELAIMIM;
- } else if (!isCheshvanLong() && isKislevShort()) {
- return CHASERIM;
- } else {
- return KESIDRAN;
- }
- }
-
- /**
- * Returns the number of days of a Jewish month for a given month and year.
- *
- * @param month
- * the Jewish month
- * @param year
- * the Jewish Year
- * @return the number of days for a given Jewish month
- */
- private static int getDaysInJewishMonth(int month, int year) {
- if ((month == IYAR) || (month == TAMMUZ) || (month == ELUL) || ((month == CHESHVAN) && !(isCheshvanLong(year)))
- || ((month == KISLEV) && isKislevShort(year)) || (month == TEVES)
- || ((month == ADAR) && !(isJewishLeapYear(year))) || (month == ADAR_II)) {
- return 29;
- } else {
- return 30;
- }
- }
-
- /**
- * Returns the number of days of the Jewish month that the calendar is currently set to.
- *
- * @return the number of days for the Jewish month that the calendar is currently set to.
- */
- public int getDaysInJewishMonth() {
- return getDaysInJewishMonth(getJewishMonth(), getJewishYear());
- }
-
- /**
- * Computes the Jewish date from the absolute date.
- */
- private void absDateToJewishDate() {
- // Approximation from below
- jewishYear = (gregorianAbsDate - JEWISH_EPOCH) / 366;
- // Search forward for year from the approximation
- while (gregorianAbsDate >= jewishDateToAbsDate(jewishYear + 1, TISHREI, 1)) {
- jewishYear++;
- }
- // Search forward for month from either Tishri or Nissan.
- if (gregorianAbsDate < jewishDateToAbsDate(jewishYear, NISSAN, 1)) {
- jewishMonth = TISHREI;// Start at Tishri
- } else {
- jewishMonth = NISSAN;// Start at Nissan
- }
- while (gregorianAbsDate > jewishDateToAbsDate(jewishYear, jewishMonth, getDaysInJewishMonth())) {
- jewishMonth++;
- }
- // Calculate the day by subtraction
- jewishDay = gregorianAbsDate - jewishDateToAbsDate(jewishYear, jewishMonth, 1) + 1;
- }
-
- /**
- * Returns the absolute date of Jewish date. ND+ER
- *
- * @param year
- * the Jewish year. The year can't be negative
- * @param month
- * the Jewish month starting with Nissan. Nissan expects a value of 1 etc. until Adar with a value of 12.
- * For a leap year, 13 will be the expected value for Adar II. Use the constants {@link JewishDate#NISSAN}
- * etc.
- * @param dayOfMonth
- * the Jewish day of month. valid values are 1-30. If the day of month is set to 30 for a month that only
- * has 29 days, the day will be set as 29.
- * @return the absolute date of the Jewish date.
- */
- private static int jewishDateToAbsDate(int year, int month, int dayOfMonth) {
- int elapsed = getDaysSinceStartOfJewishYear(year, month, dayOfMonth);
- // add elapsed days this year + Days in prior years + Days elapsed before absolute year 1
- return elapsed + getJewishCalendarElapsedDays(year) + JEWISH_EPOCH;
- }
-
- /**
- * Returns the molad for a given year and month. Returns a JewishDate {@link Object} set to the date of the molad
- * with the {@link #getMoladHours() hours}, {@link #getMoladMinutes() minutes} and {@link #getMoladChalakim()
- * chalakim} set. In the current implementation, it sets the molad time based on a midnight date rollover. This
- * means that Rosh Chodesh Adar II, 5771 with a molad of 7 chalakim past midnight on Shabbos 29 Adar I / March 5,
- * 2011 12:00 AM and 7 chalakim, will have the following values: hours: 0, minutes: 0, Chalakim: 7.
- *
- * @return a JewishDate {@link Object} set to the date of the molad with the {@link #getMoladHours() hours},
- * {@link #getMoladMinutes() minutes} and {@link #getMoladChalakim() chalakim} set.
- */
- public JewishDate getMolad() {
- JewishDate moladDate = new JewishDate(getChalakimSinceMoladTohu());
- if (moladDate.getMoladHours() >= 6) {
- moladDate.forward(Calendar.DATE, 1);
- }
- moladDate.setMoladHours((moladDate.getMoladHours() + 18) % 24);
- return moladDate;
- }
-
- /**
- * Returns the number of days from the Jewish epoch from the number of chalakim from the epoch passed in.
- *
- * @param chalakim
- * the number of chalakim since the beginning of Sunday prior to BaHaRaD
- * @return the number of days from the Jewish epoch
- */
- private static int moladToAbsDate(long chalakim) {
- return (int) (chalakim / CHALAKIM_PER_DAY) + JEWISH_EPOCH;
- }
-
- /**
- * Constructor that creates a JewishDate based on a molad passed in. The molad would be the number of
- * chalakim / parts starting at the beginning of Sunday prior to the Molad Tohu BeHaRaD (Be =
- * Monday, Ha = 5 hours and RaD = 204 chalakim / parts) - prior to the start of the Jewish
- * calendar. BeHaRaD is 23:11:20 on Sunday night(5 hours 204/1080 chalakim after sunset on Sunday evening).
- *
- * @param molad the number of chalakim since the beginning of Sunday prior to BaHaRaD
- */
- public JewishDate(long molad) {
- absDateToDate(moladToAbsDate(molad));
- int conjunctionDay = (int) (molad / (long) CHALAKIM_PER_DAY);
- int conjunctionParts = (int) (molad - conjunctionDay * (long) CHALAKIM_PER_DAY);
- setMoladTime(conjunctionParts);
- }
-
- /**
- * Sets the molad time (hours minutes and chalakim) based on the number of chalakim since the start of the day.
- *
- * @param chalakim
- * the number of chalakim since the start of the day.
- */
- private void setMoladTime(int chalakim) {
- int adjustedChalakim = chalakim;
- setMoladHours(adjustedChalakim / CHALAKIM_PER_HOUR);
- adjustedChalakim = adjustedChalakim - (getMoladHours() * CHALAKIM_PER_HOUR);
- setMoladMinutes(adjustedChalakim / CHALAKIM_PER_MINUTE);
- setMoladChalakim(adjustedChalakim - moladMinutes * CHALAKIM_PER_MINUTE);
- }
-
- /**
- * returns the number of days from Rosh Hashana of the date passed in, to the full date passed in.
- *
- * @param year
- * the Jewish year
- * @param month
- * the Jewish month
- * @param dayOfMonth
- * the day in the Jewish month
- * @return the number of days
- */
- private static int getDaysSinceStartOfJewishYear(int year, int month, int dayOfMonth) {
- int elapsedDays = dayOfMonth;
- // Before Tishrei (from Nissan to Tishrei), add days in prior months
- if (month < TISHREI) {
- // this year before and after Nissan.
- for (int m = TISHREI; m <= getLastMonthOfJewishYear(year); m++) {
- elapsedDays += getDaysInJewishMonth(m, year);
- }
- for (int m = NISSAN; m < month; m++) {
- elapsedDays += getDaysInJewishMonth(m, year);
- }
- } else { // Add days in prior months this year
- for (int m = TISHREI; m < month; m++) {
- elapsedDays += getDaysInJewishMonth(m, year);
- }
- }
- return elapsedDays;
- }
-
- /**
- * returns the number of days from Rosh Hashana of the date passed in, to the full date passed in.
- *
- * @return the number of days
- */
- public int getDaysSinceStartOfJewishYear() {
- return getDaysSinceStartOfJewishYear(getJewishYear(), getJewishMonth(), getJewishDayOfMonth());
- }
-
- /**
- * Creates a Jewish date based on a Jewish year, month and day of month.
- *
- * @param jewishYear
- * the Jewish year
- * @param jewishMonth
- * the Jewish month. The method expects a 1 for Nissan ... 12 for Adar and 13 for Adar II. Use the
- * constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar II) to avoid any
- * confusion.
- * @param jewishDayOfMonth
- * the Jewish day of month. If 30 is passed in for a month with only 29 days (for example {@link #IYAR},
- * or {@link #KISLEV} in a year that {@link #isKislevShort()}), the 29th (last valid date of the month)
- * will be set
- * @throws IllegalArgumentException
- * if the day of month is < 1 or > 30, or a year of < 0 is passed in.
- */
- public JewishDate(int jewishYear, int jewishMonth, int jewishDayOfMonth) {
- setJewishDate(jewishYear, jewishMonth, jewishDayOfMonth);
- }
-
- /**
- * Default constructor will set a default date to the current system date.
- */
- public JewishDate() {
- resetDate();
- }
-
- /**
- * A constructor that initializes the date to the {@link java.util.Date Date} parameter.
- *
- * @param date
- * the Date to set the calendar to
- * @throws IllegalArgumentException
- * if the date would fall prior to the January 1, 1 AD
- */
- public JewishDate(Date date) {
- setDate(date);
- }
-
- /**
- * A constructor that initializes the date to the {@link java.util.Calendar Calendar} parameter.
- *
- * @param calendar
- * the Calendar to set the calendar to
- * @throws IllegalArgumentException
- * if the {@link Calendar#ERA} is {@link GregorianCalendar#BC}
- */
- public JewishDate(Calendar calendar) {
- setDate(calendar);
- }
-
- /**
- * A constructor that initializes the date to the {@link java.time.LocalDate LocalDate} parameter.
- *
- * @param localDate
- * the LocalDate to set the calendar to
- * @throws IllegalArgumentException
- * if the {@link Calendar#ERA} is {@link GregorianCalendar#BC}
- */
- public JewishDate(LocalDate localDate) {
- setDate(localDate);
- }
-
- /**
- * Sets the date based on a {@link java.util.Calendar Calendar} object. Modifies the Jewish date as well.
- *
- * @param calendar
- * the Calendar to set the calendar to
- * @throws IllegalArgumentException
- * if the {@link Calendar#ERA} is {@link GregorianCalendar#BC}
- */
- public void setDate(Calendar calendar) {
- if (calendar.get(Calendar.ERA) == GregorianCalendar.BC) {
- throw new IllegalArgumentException("Calendars with a BC era are not supported. The year "
- + calendar.get(Calendar.YEAR) + " BC is invalid.");
- }
- gregorianMonth = calendar.get(Calendar.MONTH) + 1;
- gregorianDayOfMonth = calendar.get(Calendar.DATE);
- gregorianYear = calendar.get(Calendar.YEAR);
- gregorianAbsDate = gregorianDateToAbsDate(gregorianYear, gregorianMonth, gregorianDayOfMonth); // init the date
- absDateToJewishDate();
-
- dayOfWeek = Math.abs(gregorianAbsDate % 7) + 1; // set day of week
- }
-
- /**
- * Sets the date based on a {@link java.util.Date Date} object. Modifies the Jewish date as well.
- *
- * @param date
- * the Date to set the calendar to
- * @throws IllegalArgumentException
- * if the date would fall prior to the year 1 AD
- */
- public void setDate(Date date) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(date);
- setDate(cal);
- }
-
- /**
- * Sets the date based on a {@link java.time.LocalDate LocalDate} object. Modifies the Jewish date as well.
- *
- * @param localDate
- * the LocalDate to set the calendar to
- * @throws IllegalArgumentException
- * if the date would fall prior to the year 1 AD
- */
- public void setDate(LocalDate localDate) {
- Calendar cal = Calendar.getInstance();
- cal.set(localDate.getYear(), localDate.getMonthValue() - 1, localDate.getDayOfMonth());
- setDate(cal);
- }
-
- /**
- * Sets the Gregorian Date, and updates the Jewish date accordingly. Like the Java Calendar A value of 0 is expected
- * for January.
- *
- * @param year
- * the Gregorian year
- * @param month
- * the Gregorian month. Like the Java Calendar, this class expects 0 for January
- * @param dayOfMonth
- * the Gregorian day of month. If this is > the number of days in the month/year, the last valid date of
- * the month will be set
- * @throws IllegalArgumentException
- * if a year of < 1, a month < 0 or > 11 or a day of month < 1 is passed in
- */
- public void setGregorianDate(int year, int month, int dayOfMonth) {
- validateGregorianDate(year, month, dayOfMonth);
- setInternalGregorianDate(year, month + 1, dayOfMonth);
- }
-
- /**
- * Sets the hidden internal representation of the Gregorian date , and updates the Jewish date accordingly. While
- * public getters and setters have 0 based months matching the Java Calendar classes, This class internally
- * represents the Gregorian month starting at 1. When this is called it will not adjust the month to match the Java
- * Calendar classes.
- *
- * @param year the year
- * @param month the month
- * @param dayOfMonth the day of month
- */
- private void setInternalGregorianDate(int year, int month, int dayOfMonth) {
- // make sure date is a valid date for the given month, if not, set to last day of month
- if (dayOfMonth > getLastDayOfGregorianMonth(month, year)) {
- dayOfMonth = getLastDayOfGregorianMonth(month, year);
- }
- // init month, date, year
- gregorianMonth = month;
- gregorianDayOfMonth = dayOfMonth;
- gregorianYear = year;
-
- gregorianAbsDate = gregorianDateToAbsDate(gregorianYear, gregorianMonth, gregorianDayOfMonth); // init date
- absDateToJewishDate();
-
- dayOfWeek = Math.abs(gregorianAbsDate % 7) + 1; // set day of week
- }
-
- /**
- * Sets the Jewish Date and updates the Gregorian date accordingly.
- *
- * @param year
- * the Jewish year. The year can't be negative
- * @param month
- * the Jewish month starting with Nissan. A value of 1 is expected for Nissan ... 12 for Adar and 13 for
- * Adar II. Use the constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar
- * II) to avoid any confusion.
- * @param dayOfMonth
- * the Jewish day of month. valid values are 1-30. If the day of month is set to 30 for a month that only
- * has 29 days, the day will be set as 29.
- * @throws IllegalArgumentException
- * if a Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a
- * leap year) or the day of month is < 1 or > 30 is passed in
- */
- public void setJewishDate(int year, int month, int dayOfMonth) {
- setJewishDate(year, month, dayOfMonth, 0, 0, 0);
- }
-
- /**
- * Sets the Jewish Date and updates the Gregorian date accordingly.
- *
- * @param year
- * the Jewish year. The year can't be negative
- * @param month
- * the Jewish month starting with Nissan. A value of 1 is expected for Nissan ... 12 for Adar and 13 for
- * Adar II. Use the constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar
- * II) to avoid any confusion.
- * @param dayOfMonth
- * the Jewish day of month. valid values are 1-30. If the day of month is set to 30 for a month that only
- * has 29 days, the day will be set as 29.
- *
- * @param hours
- * the hour of the day. Used for molad calculations
- * @param minutes
- * the minutes. Used for molad calculations
- * @param chalakim
- * the chalakim / parts. Used for molad calculations. The chalakim should not
- * exceed 17. Minutes should be used for larger numbers.
- *
- * @throws IllegalArgumentException
- * if a Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a leap year), the day
- * of month is < 1 or > 30, an hour < 0 or > 23, a minute < 0 > 59 or chalakim < 0 > 17. For
- * 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) {
- validateJewishDate(year, month, dayOfMonth, hours, minutes, chalakim);
-
- // if 30 is passed for a month that only has 29 days (for example by rolling the month from a month that had 30
- // days to a month that only has 29) set the date to 29th
- if (dayOfMonth > getDaysInJewishMonth(month, year)) {
- dayOfMonth = getDaysInJewishMonth(month, year);
- }
-
- jewishMonth = month;
- jewishDay = dayOfMonth;
- jewishYear = year;
- moladHours = hours;
- moladMinutes = minutes;
- moladChalakim = chalakim;
-
- gregorianAbsDate = jewishDateToAbsDate(jewishYear, jewishMonth, jewishDay); // reset Gregorian date
- absDateToDate(gregorianAbsDate);
-
- dayOfWeek = Math.abs(gregorianAbsDate % 7) + 1; // reset day of week
- }
-
- /**
- * Returns this object's date as a {@link java.util.Calendar} object.
- *
- * @return The {@link java.util.Calendar}
- */
- public Calendar getGregorianCalendar() {
- Calendar calendar = Calendar.getInstance();
- calendar.set(getGregorianYear(), getGregorianMonth(), getGregorianDayOfMonth());
- return calendar;
- }
-
- /**
- * Returns this object's date as a {@link java.time.LocalDate} object.
- *
- * @return The {@link java.time.LocalDate}
- */
- public LocalDate getLocalDate() {
- return LocalDate.of(getGregorianYear(), getGregorianMonth() + 1, getGregorianDayOfMonth());
- }
-
- /**
- * Resets this date to the current system date.
- */
- public void resetDate() {
- Calendar calendar = Calendar.getInstance();
- setDate(calendar);
- }
-
- /**
- * Returns a string containing the Jewish date in the form, "day Month, year" e.g. "21 Shevat, 5729". For more
- * complex formatting, use the formatter classes.
- *
- * @return the Jewish date in the form "day Month, year" e.g. "21 Shevat, 5729"
- * @see HebrewDateFormatter#format(JewishDate)
- */
- public String toString() {
- return new HebrewDateFormatter().format(this);
- }
-
- /**
- * Rolls the date, month or year forward by the amount passed in. It modifies both the Gregorian and Jewish dates accordingly.
- * If manipulation beyond the fields supported here is required, use the {@link Calendar} class {@link Calendar#add(int, int)}
- * or {@link Calendar#roll(int, int)} methods in the following manner.
- *
- *
- *
- * Calendar cal = jewishDate.getTime(); // get a java.util.Calendar representation of the JewishDate
- * cal.add(Calendar.MONTH, 3); // add 3 Gregorian months
- * jewishDate.setDate(cal); // set the updated calendar back to this class
- *
- *
- *
- * @param field the calendar field to be forwarded. The must be {@link Calendar#DATE}, {@link Calendar#MONTH} or {@link Calendar#YEAR}
- * @param amount the positive amount to move forward
- * @throws IllegalArgumentException if the field is anything besides {@link Calendar#DATE}, {@link Calendar#MONTH} or {@link Calendar#YEAR}
- * or if the amount is less than 1
- *
- * @see #back()
- * @see Calendar#add(int, int)
- * @see Calendar#roll(int, int)
- */
- public void forward(int field, int amount) {
- if (field != Calendar.DATE && field != Calendar.MONTH && field != Calendar.YEAR) {
- throw new IllegalArgumentException("Unsupported field was passed to Forward. Only Calendar.DATE, Calendar.MONTH or Calendar.YEAR are supported.");
- }
- if (amount < 1) {
- throw new IllegalArgumentException("JewishDate.forward() does not support amounts less than 1. See JewishDate.back()");
- }
- if (field == Calendar.DATE) {
- // Change Gregorian date
- for (int i = 0; i < amount; i++) {
- if (gregorianDayOfMonth == getLastDayOfGregorianMonth(gregorianMonth, gregorianYear)) {
- gregorianDayOfMonth = 1;
- // if last day of year
- if (gregorianMonth == 12) {
- gregorianYear++;
- gregorianMonth = 1;
- } else {
- gregorianMonth++;
- }
- } else { // if not last day of month
- gregorianDayOfMonth++;
- }
-
- // Change the Jewish Date
- if (jewishDay == getDaysInJewishMonth()) {
- // if it last day of elul (i.e. last day of Jewish year)
- if (jewishMonth == ELUL) {
- jewishYear++;
- jewishMonth++;
- jewishDay = 1;
- } else if (jewishMonth == getLastMonthOfJewishYear(jewishYear)) {
- // if it is the last day of Adar, or Adar II as case may be
- jewishMonth = NISSAN;
- jewishDay = 1;
- } else {
- jewishMonth++;
- jewishDay = 1;
- }
- } else { // if not last date of month
- jewishDay++;
- }
-
- if (dayOfWeek == 7) { // if last day of week, loop back to Sunday
- dayOfWeek = 1;
- } else {
- dayOfWeek++;
- }
-
- gregorianAbsDate++; // increment the absolute date
- }
- } else if (field == Calendar.MONTH) {
- forwardJewishMonth(amount);
- } else {
- setJewishYear(getJewishYear() + amount);
- }
- }
-
- /**
- * Forward the Jewish date by the number of months passed in.
- * FIXME: Deal with forwarding a date such as 30 Nissan by a month. 30 Iyar does not exist. This should be dealt with similar to
- * the way that the Java Calendar behaves (not that simple since there is a difference between add() or roll().
- *
- * @throws IllegalArgumentException if the amount is less than 1
- * @param amount the number of months to roll the month forward
- */
- private void forwardJewishMonth(int amount) {
- if (amount < 1) {
- throw new IllegalArgumentException("the amount of months to forward has to be greater than zero.");
- }
- for (int i = 0; i < amount; i++) {
- if (getJewishMonth() == ELUL) {
- setJewishMonth(TISHREI);
- setJewishYear(getJewishYear() + 1);
- } else if ((! isJewishLeapYear() && getJewishMonth() == ADAR)
- || (isJewishLeapYear() && getJewishMonth() == ADAR_II)){
- setJewishMonth(NISSAN);
- } else {
- setJewishMonth(getJewishMonth() + 1);
- }
- }
- }
-
- /**
- * Rolls the date back by 1 day. It modifies both the Gregorian and Jewish dates accordingly. The API does not
- * currently offer the ability to forward more than one day at a time, or to forward by month or year. If such
- * manipulation is required use the {@link Calendar} class {@link Calendar#add(int, int)} or
- * {@link Calendar#roll(int, int)} methods in the following manner.
- *
- *
- *
- * Calendar cal = jewishDate.getTime(); // get a java.util.Calendar representation of the JewishDate
- * cal.add(Calendar.MONTH, -3); // subtract 3 Gregorian months
- * jewishDate.setDate(cal); // set the updated calendar back to this class
- *
- *
- *
- * @see #back()
- * @see Calendar#add(int, int)
- * @see Calendar#roll(int, int)
- */
- public void back() {
- // Change Gregorian date
- if (gregorianDayOfMonth == 1) { // if first day of month
- if (gregorianMonth == 1) { // if first day of year
- gregorianMonth = 12;
- gregorianYear--;
- } else {
- gregorianMonth--;
- }
- // change to last day of previous month
- gregorianDayOfMonth = getLastDayOfGregorianMonth(gregorianMonth, gregorianYear);
- } else {
- gregorianDayOfMonth--;
- }
- // change Jewish date
- if (jewishDay == 1) { // if first day of the Jewish month
- if (jewishMonth == NISSAN) {
- jewishMonth = getLastMonthOfJewishYear(jewishYear);
- } else if (jewishMonth == TISHREI) { // if Rosh Hashana
- jewishYear--;
- jewishMonth--;
- } else {
- jewishMonth--;
- }
- jewishDay = getDaysInJewishMonth();
- } else {
- jewishDay--;
- }
-
- if (dayOfWeek == 1) { // if first day of week, loop back to Saturday
- dayOfWeek = 7;
- } else {
- dayOfWeek--;
- }
- gregorianAbsDate--; // change the absolute date
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- * @see Object#equals(Object)
- */
- public boolean equals(Object object) {
- if (this == object) {
- return true;
- }
- if (!(object instanceof JewishDate)) {
- return false;
- }
- JewishDate jewishDate = (JewishDate) object;
- return gregorianAbsDate == jewishDate.getAbsDate();
- }
-
- /**
- * Compares two dates as per the compareTo() method in the Comparable interface. Returns a value less than 0 if this
- * date is "less than" (before) the date, greater than 0 if this date is "greater than" (after) the date, or 0 if
- * they are equal.
- */
- public int compareTo(JewishDate jewishDate) {
- return Integer.compare(gregorianAbsDate, jewishDate.getAbsDate());
- }
-
- /**
- * Returns the Gregorian month (between 0-11).
- *
- * @return the Gregorian month (between 0-11). Like the java.util.Calendar, months are 0 based.
- */
- public int getGregorianMonth() {
- return gregorianMonth - 1;
- }
-
- /**
- * Returns the Gregorian day of the month.
- *
- * @return the Gregorian day of the mont
- */
- public int getGregorianDayOfMonth() {
- return gregorianDayOfMonth;
- }
-
- /**
- * Returns the Gregorian year.
- *
- * @return the Gregorian year
- */
- public int getGregorianYear() {
- return gregorianYear;
- }
-
- /**
- * Returns the Jewish month 1-12 (or 13 years in a leap year). The month count starts with 1 for Nissan and goes to
- * 13 for Adar II
- *
- * @return the Jewish month from 1 to 12 (or 13 years in a leap year). The month count starts with 1 for Nissan and
- * goes to 13 for Adar II
- */
- public int getJewishMonth() {
- return jewishMonth;
- }
-
- /**
- * Returns the Jewish day of month.
- *
- * @return the Jewish day of the month
- */
- public int getJewishDayOfMonth() {
- return jewishDay;
- }
-
- /**
- * Returns the Jewish year.
- *
- * @return the Jewish year
- */
- public int getJewishYear() {
- return jewishYear;
- }
-
- /**
- * Returns the day of the week as a number between 1-7.
- *
- * @return the day of the week as a number between 1-7.
- */
- public int getDayOfWeek() {
- return dayOfWeek;
- }
-
- /**
- * Sets the Gregorian month.
- *
- * @param month
- * the Gregorian month
- *
- * @throws IllegalArgumentException
- * if a month < 0 or > 11 is passed in
- */
- public void setGregorianMonth(int month) {
- validateGregorianMonth(month);
- setInternalGregorianDate(gregorianYear, month + 1, gregorianDayOfMonth);
- }
-
- /**
- * sets the Gregorian year.
- *
- * @param year
- * the Gregorian year.
- * @throws IllegalArgumentException
- * if a year of < 1 is passed in
- */
- public void setGregorianYear(int year) {
- validateGregorianYear(year);
- setInternalGregorianDate(year, gregorianMonth, gregorianDayOfMonth);
- }
-
- /**
- * sets the Gregorian Day of month.
- *
- * @param dayOfMonth
- * the Gregorian Day of month.
- * @throws IllegalArgumentException
- * if the day of month of < 1 is passed in
- */
- public void setGregorianDayOfMonth(int dayOfMonth) {
- validateGregorianDayOfMonth(dayOfMonth);
- setInternalGregorianDate(gregorianYear, gregorianMonth, dayOfMonth);
- }
-
- /**
- * sets the Jewish month.
- *
- * @param month
- * the Jewish month from 1 to 12 (or 13 years in a leap year). The month count starts with 1 for Nissan
- * and goes to 13 for Adar II
- * @throws IllegalArgumentException
- * if a month < 1 or > 12 (or 13 on a leap year) is passed in
- */
- public void setJewishMonth(int month) {
- setJewishDate(jewishYear, month, jewishDay);
- }
-
- /**
- * sets the Jewish year.
- *
- * @param year
- * the Jewish year
- * @throws IllegalArgumentException
- * if a year of < 3761 is passed in. The same will happen if the year is 3761 and the month and day
- * previously set are < 18 Teves (prior to Jan 1, 1 AD)
- */
- public void setJewishYear(int year) {
- setJewishDate(year, jewishMonth, jewishDay);
- }
-
- /**
- * sets the Jewish day of month.
- *
- * @param dayOfMonth
- * the Jewish day of month
- * @throws IllegalArgumentException
- * if the day of month is < 1 or > 30 is passed in
- */
- public void setJewishDayOfMonth(int dayOfMonth) {
- setJewishDate(jewishYear, jewishMonth, dayOfMonth);
- }
-
- /**
- * A method that creates a deep copy of the object.
- *
- * @see Object#clone()
- */
- public Object clone() {
- JewishDate clone = null;
- try {
- clone = (JewishDate) super.clone();
- } catch (CloneNotSupportedException cnse) {
- // Required by the compiler. Should never be reached since we implement clone()
- }
- if (clone != null) {
- clone.setInternalGregorianDate(gregorianYear, gregorianMonth, gregorianDayOfMonth);
- }
- return clone;
- }
-
- /**
- * Overrides {@link Object#hashCode()}.
- * @see Object#hashCode()
- */
- public int hashCode() {
- int result = 17;
- result = 37 * result + getClass().hashCode(); // needed or this and subclasses will return identical hash
- result += 37 * result + gregorianAbsDate;
- return result;
- }
+ /**
+ * Value of the month field indicating Nissan, the first numeric month of the year in the Jewish calendar. With the
+ * year starting at {@link #TISHREI}, it would actually be the 7th (or 8th in a {@link #isJewishLeapYear() leap
+ * year}) month of the year.
+ */
+ public static final int NISSAN = 1;
+
+ /**
+ * Value of the month field indicating Iyar, the second numeric month of the year in the Jewish calendar. With the
+ * year starting at {@link #TISHREI}, it would actually be the 8th (or 9th in a {@link #isJewishLeapYear() leap
+ * year}) month of the year.
+ */
+ public static final int IYAR = 2;
+
+ /**
+ * Value of the month field indicating Sivan, the third numeric month of the year in the Jewish calendar. With the
+ * year starting at {@link #TISHREI}, it would actually be the 9th (or 10th in a {@link #isJewishLeapYear() leap
+ * year}) month of the year.
+ */
+ public static final int SIVAN = 3;
+
+ /**
+ * Value of the month field indicating Tammuz, the fourth numeric month of the year in the Jewish calendar. With the
+ * year starting at {@link #TISHREI}, it would actually be the 10th (or 11th in a {@link #isJewishLeapYear() leap
+ * year}) month of the year.
+ */
+ public static final int TAMMUZ = 4;
+
+ /**
+ * Value of the month field indicating Av, the fifth numeric month of the year in the Jewish calendar. With the year
+ * starting at {@link #TISHREI}, it would actually be the 11th (or 12th in a {@link #isJewishLeapYear() leap year})
+ * month of the year.
+ */
+ public static final int AV = 5;
+
+ /**
+ * Value of the month field indicating Elul, the sixth numeric month of the year in the Jewish calendar. With the
+ * year starting at {@link #TISHREI}, it would actually be the 12th (or 13th in a {@link #isJewishLeapYear() leap
+ * year}) month of the year.
+ */
+ public static final int ELUL = 6;
+
+ /**
+ * Value of the month field indicating Tishrei, the seventh numeric month of the year in the Jewish calendar. With
+ * the year starting at this month, it would actually be the 1st month of the year.
+ */
+ public static final int TISHREI = 7;
+
+ /**
+ * Value of the month field indicating Cheshvan/marcheshvan, the eighth numeric month of the year in the Jewish
+ * calendar. With the year starting at {@link #TISHREI}, it would actually be the 2nd month of the year.
+ */
+ public static final int CHESHVAN = 8;
+
+ /**
+ * Value of the month field indicating Kislev, the ninth numeric month of the year in the Jewish calendar. With the
+ * year starting at {@link #TISHREI}, it would actually be the 3rd month of the year.
+ */
+ public static final int KISLEV = 9;
+
+ /**
+ * Value of the month field indicating Teves, the tenth numeric month of the year in the Jewish calendar. With the
+ * year starting at {@link #TISHREI}, it would actually be the 4th month of the year.
+ */
+ public static final int TEVES = 10;
+
+ /**
+ * Value of the month field indicating Shevat, the eleventh numeric month of the year in the Jewish calendar. With
+ * the year starting at {@link #TISHREI}, it would actually be the 5th month of the year.
+ */
+ public static final int SHEVAT = 11;
+
+ /**
+ * Value of the month field indicating Adar (or Adar I in a {@link #isJewishLeapYear() leap year}), the twelfth
+ * numeric month of the year in the Jewish calendar. With the year starting at {@link #TISHREI}, it would actually
+ * be the 6th month of the year.
+ */
+ public static final int ADAR = 12;
+
+ /**
+ * Value of the month field indicating Adar II, the leap (intercalary or embolismic) thirteenth (Undecimber) numeric
+ * month of the year added in Jewish {@link #isJewishLeapYear() leap year}). The leap years are years 3, 6, 8, 11,
+ * 14, 17 and 19 of a 19-year cycle. With the year starting at {@link #TISHREI}, it would actually be the 7th month
+ * of the year.
+ */
+ public static final int ADAR_II = 13;
+
+ /**
+ * the Jewish epoch using the RD (Rata Die/Fixed Date or Reingold Dershowitz) day used in Calendrical Calculations.
+ * Day 1 is January 1, 0001 of the Gregorian calendar
+ */
+ private static final int JEWISH_EPOCH = -1373429;
+
+ /** The number of chalakim (18) in a minute.*/
+ private static final int CHALAKIM_PER_MINUTE = 18;
+ /** The number of chalakim (1080) in an hour.*/
+ private static final int CHALAKIM_PER_HOUR = 1080;
+ /** The number of chalakim (25,920) in a 24-hour day .*/
+ private static final int CHALAKIM_PER_DAY = 25920; // 24 * 1080
+ /** The number of chalakim in an average Jewish month. A month has 29 days, 12 hours and 793
+ * chalakim (44 minutes and 3.3 seconds) for a total of 765,433 chalakim*/
+ private static final long CHALAKIM_PER_MONTH = 765433; // (29 * 24 + 12) * 1080 + 793
+ /**
+ * Days from the beginning of Sunday till molad BaHaRaD. Calculated as 1 day, 5 hours and 204 chalakim =
+ * (24 + 5) * 1080 + 204 = 31524
+ */
+ private static final int CHALAKIM_MOLAD_TOHU = 31524;
+
+ /**
+ * A short year where both {@link #CHESHVAN} and {@link #KISLEV} are 29 days.
+ *
+ * @see #getCheshvanKislevKviah()
+ * @see HebrewDateFormatter#getFormattedKviah(int)
+ */
+ public static final int CHASERIM = 0;
+
+ /**
+ * An ordered year where {@link #CHESHVAN} is 29 days and {@link #KISLEV} is 30 days.
+ *
+ * @see #getCheshvanKislevKviah()
+ * @see HebrewDateFormatter#getFormattedKviah(int)
+ */
+ public static final int KESIDRAN = 1;
+
+ /**
+ * A long year where both {@link #CHESHVAN} and {@link #KISLEV} are 30 days.
+ *
+ * @see #getCheshvanKislevKviah()
+ * @see HebrewDateFormatter#getFormattedKviah(int)
+ */
+ public static final int SHELAIMIM = 2;
+
+ /** the internal Jewish month.*/
+ private int jewishMonth;
+ /** the internal Jewish day.*/
+ private int jewishDay;
+ /** the internal Jewish year.*/
+ private int jewishYear;
+ /** the internal count of molad hours.*/
+ private int moladHours;
+ /** the internal count of molad minutes.*/
+ private int moladMinutes;
+ /** the internal count of molad chalakim.*/
+ private int moladChalakim;
+
+ /**
+ * Returns the molad hours. Only a JewishDate object populated with {@link #getMolad()},
+ * {@link #setJewishDate(int, int, int, int, int, int)} or {@link #setMoladHours(int)} will have this field
+ * populated. A regular JewishDate object will have this field set to 0.
+ *
+ * @return the molad hours
+ * @see #setMoladHours(int)
+ * @see #getMolad()
+ * @see #setJewishDate(int, int, int, int, int, int)
+ */
+ public int getMoladHours() {
+ return moladHours;
+ }
+
+ /**
+ * Sets the molad hours.
+ *
+ * @param moladHours
+ * the molad hours to set
+ * @see #getMoladHours()
+ * @see #getMolad()
+ * @see #setJewishDate(int, int, int, int, int, int)
+ *
+ */
+ public void setMoladHours(int moladHours) {
+ this.moladHours = moladHours;
+ }
+
+ /**
+ * Returns the molad minutes. Only an object populated with {@link #getMolad()},
+ * {@link #setJewishDate(int, int, int, int, int, int)} or or {@link #setMoladMinutes(int)} will have these fields
+ * populated. A regular JewishDate object will have this field set to 0.
+ *
+ * @return the molad minutes
+ * @see #setMoladMinutes(int)
+ * @see #getMolad()
+ * @see #setJewishDate(int, int, int, int, int, int)
+ */
+ public int getMoladMinutes() {
+ return moladMinutes;
+ }
+
+ /**
+ * Sets the molad minutes. The expectation is that the traditional minute-less chalakim will be broken out to
+ * minutes and {@link #setMoladChalakim(int) chalakim / parts} , so 793 (TaShTZaG) parts would have the minutes set to
+ * 44 and chalakim to 1.
+ *
+ * @param moladMinutes
+ * the molad minutes to set
+ * @see #getMoladMinutes()
+ * @see #setMoladChalakim(int)
+ * @see #getMolad()
+ * @see #setJewishDate(int, int, int, int, int, int)
+ *
+ */
+ public void setMoladMinutes(int moladMinutes) {
+ this.moladMinutes = moladMinutes;
+ }
+
+ /**
+ * Sets the molad chalakim/parts. The expectation is that the traditional minute-less chalakim will be broken
+ * out to {@link #setMoladMinutes(int) minutes} and chalakim, so 793 (TaShTZaG) parts would have the minutes set to 44 and
+ * chalakim to 1.
+ *
+ * @param moladChalakim
+ * the molad chalakim / parts to set
+ * @see #getMoladChalakim()
+ * @see #setMoladMinutes(int)
+ * @see #getMolad()
+ * @see #setJewishDate(int, int, int, int, int, int)
+ *
+ */
+ public void setMoladChalakim(int moladChalakim) {
+ this.moladChalakim = moladChalakim;
+ }
+
+ /**
+ * Returns the molad chalakim / parts. Only an object populated with {@link #getMolad()},
+ * {@link #setJewishDate(int, int, int, int, int, int)} or or {@link #setMoladChalakim(int)} will have these fields
+ * populated. A regular JewishDate object will have this field set to 0.
+ *
+ * @return the molad chalakim / parts
+ * @see #setMoladChalakim(int)
+ * @see #getMolad()
+ * @see #setJewishDate(int, int, int, int, int, int)
+ */
+ public int getMoladChalakim() {
+ return moladChalakim;
+ }
+
+ /** 1 == Sunday, 2 == Monday, etc... */
+ private int dayOfWeek;
+
+ /** Returns the absolute date (days since January 1, 0001 of the Gregorian calendar).
+ * @see #getAbsDate()
+ * @see #setAbsDate(int)
+ */
+ private int gregorianAbsDate;
+
+ /**
+ * Returns the number of days in a given month in a given month and year.
+ *
+ * @param month
+ * the month. As with other cases in this class, this is 1-based, not zero-based.
+ * @param year
+ * the year (only impacts February)
+ * @return the number of days in the month in the given year
+ */
+ private static int getLastDayOfGregorianMonth(int month, int year) {
+ return YearMonth.of(year, month).lengthOfMonth();
+ }
+
+ /**
+ * Computes the Gregorian date from the absolute date. ND+ER
+ * @param absDate the absolute date
+ * @return the LocalDate.
+ */
+ private static LocalDate absDateToDate(int absDate) {
+ int year = absDate / 366; // Search forward year by year from approximate year
+ while (absDate >= gregorianDateToAbsDate(year + 1, 1, 1)) {
+ year++;
+ }
+
+ int month = 1; // Search forward month by month from January
+ while (absDate > gregorianDateToAbsDate(year, month, getLastDayOfGregorianMonth(month, year))) {
+ month++;
+ }
+
+ int dayOfMonth = absDate - gregorianDateToAbsDate(year, month, 1) + 1;
+ return LocalDate.of(year, month, dayOfMonth);
+ }
+
+ /**
+ * Returns the absolute date (days since January 1, 0001 of the Gregorian calendar).
+ *
+ * @return the number of days since January 1, 1
+ */
+ public int getAbsDate() {
+ return gregorianAbsDate;
+ }
+
+ /**
+ * Computes the absolute date from a Gregorian date. ND+ER
+ *
+ * @param year
+ * the Gregorian year
+ * @param month
+ * the Gregorian month. Unlike the Java Calendar where January has the value of 0,This expects a 1 for
+ * January
+ * @param dayOfMonth
+ * the day of the month (1st, 2nd, etc...)
+ * @return the absolute Gregorian day
+ */
+ private static int gregorianDateToAbsDate(int year, int month, int dayOfMonth) {
+ int absDate = dayOfMonth;
+ for (int m = month - 1; m > 0; m--) {
+ absDate += getLastDayOfGregorianMonth(m, year); // days in prior months of the year
+ }
+ return (absDate // days this year
+ + 365 * (year - 1) // days in previous years ignoring leap days
+ + (year - 1) / 4 // Julian leap days before this year
+ - (year - 1) / 100 // minus prior century years
+ + (year - 1) / 400); // plus prior years divisible by 400
+ }
+
+ /**
+ * Returns if the year is a Jewish leap year. Years 3, 6, 8, 11, 14, 17 and 19 in the 19-year cycle are leap years.
+ *
+ * @param year
+ * the Jewish year.
+ * @return true if it is a leap year
+ * @see #isJewishLeapYear()
+ */
+ private static boolean isJewishLeapYear(int year) {
+ return ((7 * year) + 1) % 19 < 7;
+ }
+
+ /**
+ * Returns if the year the calendar is set to is a Jewish leap year. Years 3, 6, 8, 11, 14, 17 and 19 in the 19-year
+ * cycle are leap years.
+ *
+ * @return true if it is a leap year
+ * @see #isJewishLeapYear(int)
+ */
+ public boolean isJewishLeapYear() {
+ return isJewishLeapYear(getJewishYear());
+ }
+
+ /**
+ * Returns the last month of a given Jewish year. This will be 12 on a non {@link #isJewishLeapYear(int) leap year}
+ * or 13 on a leap year.
+ *
+ * @param year
+ * the Jewish year.
+ * @return 12 on a non leap year or 13 on a leap year
+ * @see #isJewishLeapYear(int)
+ */
+ private static int getLastMonthOfJewishYear(int year) {
+ return isJewishLeapYear(year) ? ADAR_II : ADAR;
+ }
+
+ /**
+ * Returns the number of days elapsed from the Sunday prior to the start of the Jewish calendar to the mean
+ * conjunction of Tishri of the Jewish year.
+ *
+ * @param year
+ * the Jewish year
+ * @return the number of days elapsed from prior to the molad Tohu BaHaRaD (Be = Monday, Ha = 5
+ * hours and RaD = 204 chalakim / parts) prior to the start of the Jewish calendar, to
+ * the mean conjunction of Tishri of the Jewish year. BeHaRaD is 23:11:20 on Sunday night(5 hours 204/1080
+ * chalakim after sunset on Sunday evening).
+ */
+ public static int getJewishCalendarElapsedDays(int year) {
+ long chalakimSince = getChalakimSinceMoladTohu(year, TISHREI);
+ int moladDay = (int) (chalakimSince / (long) CHALAKIM_PER_DAY);
+ int moladParts = (int) (chalakimSince - moladDay * (long) CHALAKIM_PER_DAY);
+ // delay Rosh Hashana for the 4 dechiyos
+ return addDechiyos(year, moladDay, moladParts);
+ }
+
+ /**
+ * Adds the 4 dechiyos for molad Tishrei. These are:
+ *
+ * - Lo ADU Rosh - Rosh Hashana can't fall on a Sunday, Wednesday or Friday. If the molad fell on one
+ * of these days, Rosh Hashana is delayed to the following day.
+ * - Molad Zaken - If the molad of Tishrei falls after 12 noon, Rosh Hashana is delayed to the following
+ * day. If the following day is ADU, it will be delayed an additional day.
+ * - GaTRaD - If on a non leap year the molad of Tishrei falls on a Tuesday (Ga) on or after 9 hours
+ * (T) and (RaD 204 chalakim it is delayed till Thursday (one day delay, plus one day for
+ * Lo ADU Rosh)
+ * - BeTuTaKPaT - if the year following a leap year falls on a Monday (Be) on or after 15 hours
+ * (Tu) and 589 chalakim (TaKPaT) it is delayed till Tuesday
+ *
+ *
+ * @param year the year
+ * @param moladDay the molad day
+ * @param moladParts the molad parts
+ * @return the number of elapsed days in the JewishCalendar adjusted for the 4 dechiyos.
+ */
+ private static int addDechiyos(int year, int moladDay, int moladParts) {
+ int roshHashanaDay = moladDay; // if no dechiyos
+ // delay Rosh Hashana for the dechiyos of the Molad - new moon 1 - Molad Zaken, 2- GaTRaD 3- BeTuTaKPaT
+ if ((moladParts >= 19440) // Dechiya of Molad Zaken - molad is >= midday (18 hours * 1080 chalakim)
+ || (((moladDay % 7) == 2) // start Dechiya of GaTRaD - Ga = is a Tuesday
+ && (moladParts >= 9924) // TRaD = 9 hours, 204 parts or later (9 * 1080 + 204)
+ && !isJewishLeapYear(year)) // of a non-leap year - end Dechiya of GaTRaD
+ || (((moladDay % 7) == 1) // start Dechiya of BeTuTaKPaT - Be = is on a Monday
+ && (moladParts >= 16789) // TUTaKPaT part of BeTuTaKPaT = 15 hours, 589 parts or later (15 * 1080 + 589)
+ && (isJewishLeapYear(year - 1)))) { // in a year following a leap year - end Dechiya of BeTuTaKPaT
+ roshHashanaDay += 1; // Then postpone Rosh HaShanah one day
+ }
+ // start 4th Dechiya - Lo ADU Rosh - Rosh Hashana can't occur on A- sunday, D- Wednesday, U - Friday
+ if (((roshHashanaDay % 7) == 0)// If Rosh HaShanah would occur on Sunday,
+ || ((roshHashanaDay % 7) == 3) // or Wednesday,
+ || ((roshHashanaDay % 7) == 5)) { // or Friday - end 4th Dechiya - Lo ADU Rosh
+ roshHashanaDay = roshHashanaDay + 1; // Then postpone it one (more) day
+ }
+ return roshHashanaDay;
+ }
+
+ /**
+ * Returns the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
+ * to the year and month passed in.
+ *
+ * @param year
+ * the Jewish year
+ * @param month
+ * the Jewish month the Jewish month, with the month numbers starting from Nissan. Use the JewishDate
+ * constants such as {@link JewishDate#TISHREI}.
+ * @return the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
+ */
+ private static long getChalakimSinceMoladTohu(int year, int month) {
+ // Jewish lunar month = 29 days, 12 hours and 793 chalakim
+ // chalakim since Molad Tohu BeHaRaD - 1 day, 5 hours and 204 chalakim
+ int monthOfYear = getJewishMonthOfYear(year, month);
+ int monthsElapsed = (235 * ((year - 1) / 19)) // Months in complete 19-year lunar (Metonic) cycles so far
+ + (12 * ((year - 1) % 19)) // Regular months in this cycle
+ + ((7 * ((year - 1) % 19) + 1) / 19) // Leap months this cycle
+ + (monthOfYear - 1); // add elapsed months till the start of the molad of the month
+ // return chalakim prior to BeHaRaD + number of chalakim since
+ return CHALAKIM_MOLAD_TOHU + (CHALAKIM_PER_MONTH * monthsElapsed);
+ }
+
+ /**
+ * Returns the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
+ * to the Jewish year and month that this Object is set to.
+ *
+ * @return the number of chalakim (parts - 1080 to the hour) from the original hypothetical Molad Tohu
+ */
+ public long getChalakimSinceMoladTohu() {
+ return getChalakimSinceMoladTohu(jewishYear, jewishMonth);
+ }
+
+ /**
+ * Converts the {@link JewishDate#NISSAN} based constants used by this class to numeric month starting from
+ * {@link JewishDate#TISHREI}. This is required for molad calculations.
+ *
+ * @param year
+ * The Jewish year
+ * @param month
+ * The Jewish Month
+ * @return the Jewish month of the year starting with Tishrei
+ */
+ private static int getJewishMonthOfYear(int year, int month) {
+ boolean isLeapYear = isJewishLeapYear(year);
+ return (month + (isLeapYear ? 6 : 5)) % (isLeapYear ? 13 : 12) + 1;
+ }
+
+ /**
+ * Validates the components of a Jewish date for validity. It will throw an {@link IllegalArgumentException} if the Jewish
+ * date is earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a {@link #isJewishLeapYear(int)
+ * leap year}), the day of month is < 1 or > 30, an hour < 0 or > 23, a minute < 0 or > 59 or
+ * chalakim < 0 or > 17. For 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).
+ *
+ * @param year
+ * the Jewish year to validate. It will reject any year <= 3761 (lower than the year 1 Gregorian).
+ * @param month
+ * the Jewish month to validate. It will reject a month < 1 or > 12 (or 13 on a leap year) .
+ * @param dayOfMonth
+ * the day of the Jewish month to validate. It will reject any value < 1 or > 30 TODO: check calling
+ * methods to see if there is any reason that the class can validate that 30 is invalid for some months.
+ * @param hours
+ * the hours (for molad calculations). It will reject an hour < 0 or > 23
+ * @param minutes
+ * the minutes (for molad calculations). It will reject a minute < 0 or > 59
+ * @param chalakim
+ * the chalakim / parts (for molad calculations). It will reject a chalakim < 0 or >
+ * 17. For larger numbers 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)
+ *
+ * @throws IllegalArgumentException
+ * if a Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a leap year),
+ * the day of month is < 1 or > 30, an hour < 0 or > 23, a minute < 0 or > 59 or chalakim
+ * < 0 or > 17. For 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).
+ */
+ private static void validateJewishDate(int year, int month, int dayOfMonth, int hours, int minutes, int chalakim) {
+ if (month < NISSAN || month > getLastMonthOfJewishYear(year)) {
+ throw new IllegalArgumentException("The Jewish month has to be between 1 and 12 (or 13 on a leap year). "
+ + month + " is invalid for the year " + year + ".");
+ }
+ int monthLength = getDaysInJewishMonth(month, year);
+ if (dayOfMonth < 1 || dayOfMonth > monthLength) {
+ throw new IllegalArgumentException(
+ "The Jewish day of month can't be < 1 or > " + monthLength +
+ " for the month index " + monthLength + ". " + dayOfMonth + " is invalid.");
+ }
+ // reject dates prior to 18 Teves, 3761 (1/1/1 AD). This restriction can be relaxed if the date coding is
+ // changed/corrected
+ if ((year < 3761) || (year == 3761 && (month >= TISHREI && month < TEVES))
+ || (year == 3761 && month == TEVES && dayOfMonth < 18)) {
+ throw new IllegalArgumentException(
+ "A Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian) can't be set. " + year + ", " + month
+ + ", " + dayOfMonth + " is invalid.");
+ }
+ if (hours < 0 || hours > 23) {
+ throw new IllegalArgumentException("Hours < 0 or > 23 can't be set. " + hours + " is invalid.");
+ }
+
+ if (minutes < 0 || minutes > 59) {
+ throw new IllegalArgumentException("Minutes < 0 or > 59 can't be set. " + minutes + " is invalid.");
+ }
+
+ if (chalakim < 0 || chalakim > 17) {
+ throw new IllegalArgumentException(
+ "Chalakim/parts < 0 or > 17 can't be set. "
+ + chalakim
+ + " is invalid. For larger numbers 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)");
+ }
+ }
+
+ /**
+ * Returns the number of days for a given Jewish year. ND+ER
+ *
+ * @param year
+ * the Jewish year
+ * @return the number of days for a given Jewish year.
+ * @see #isCheshvanLong()
+ * @see #isKislevShort()
+ */
+ public static int getDaysInJewishYear(int year) {
+ return getJewishCalendarElapsedDays(year + 1) - getJewishCalendarElapsedDays(year);
+ }
+
+ /**
+ * Returns the number of days for the current year that the calendar is set to.
+ *
+ * @return the number of days for the Object's current Jewish year.
+ * @see #isCheshvanLong()
+ * @see #isKislevShort()
+ * @see #isJewishLeapYear()
+ */
+ public int getDaysInJewishYear() {
+ return getDaysInJewishYear(getJewishYear());
+ }
+
+ /**
+ * Returns if Cheshvan is long in a given Jewish year. The method name isLong is done since in a Kesidran (ordered)
+ * year Cheshvan is short. ND+ER
+ *
+ * @param year
+ * the year
+ * @return true if Cheshvan is long in Jewish year.
+ * @see #isCheshvanLong()
+ * @see #getCheshvanKislevKviah()
+ */
+ private static boolean isCheshvanLong(int year) {
+ return getDaysInJewishYear(year) % 10 == 5;
+ }
+
+ /**
+ * Returns if Cheshvan is long (30 days VS 29 days) for the current year that the calendar is set to. The method
+ * name isLong is done since in a Kesidran (ordered) year Cheshvan is short.
+ *
+ * @return true if Cheshvan is long for the current year that the calendar is set to
+ * @see #isCheshvanLong()
+ */
+ public boolean isCheshvanLong() {
+ return isCheshvanLong(getJewishYear());
+ }
+
+ /**
+ * Returns if Kislev is short (29 days VS 30 days) in a given Jewish year. The method name isShort is done since in
+ * a Kesidran (ordered) year Kislev is long. ND+ER
+ *
+ * @param year
+ * the Jewish year
+ * @return true if Kislev is short for the given Jewish year.
+ * @see #isKislevShort()
+ * @see #getCheshvanKislevKviah()
+ */
+ private static boolean isKislevShort(int year) {
+ return getDaysInJewishYear(year) % 10 == 3;
+ }
+
+ /**
+ * Returns if the Kislev is short for the year that this class is set to. The method name isShort is done since in a
+ * Kesidran (ordered) year Kislev is long.
+ *
+ * @return true if Kislev is short for the year that this class is set to
+ */
+ public boolean isKislevShort() {
+ return isKislevShort(getJewishYear());
+ }
+
+ /**
+ * Returns the Cheshvan and Kislev kviah (whether a Jewish year is short, regular or long). It will return
+ * {@link #SHELAIMIM} if both cheshvan and kislev are 30 days, {@link #KESIDRAN} if Cheshvan is 29 days and Kislev
+ * is 30 days and {@link #CHASERIM} if both are 29 days.
+ *
+ * @return {@link #SHELAIMIM} if both cheshvan and kislev are 30 days, {@link #KESIDRAN} if Cheshvan is 29 days and
+ * Kislev is 30 days and {@link #CHASERIM} if both are 29 days.
+ * @see #isCheshvanLong()
+ * @see #isKislevShort()
+ */
+ public int getCheshvanKislevKviah() {
+ if (isCheshvanLong() && !isKislevShort()) {
+ return SHELAIMIM;
+ } else if (!isCheshvanLong() && isKislevShort()) {
+ return CHASERIM;
+ } else {
+ return KESIDRAN;
+ }
+ }
+
+ /**
+ * Returns the number of days of a Jewish month for a given month and year.
+ *
+ * @param month
+ * the Jewish month
+ * @param year
+ * the Jewish Year
+ * @return the number of days for a given Jewish month
+ */
+ private static int getDaysInJewishMonth(int month, int year) {
+ if ((month == IYAR) || (month == TAMMUZ) || (month == ELUL) || ((month == CHESHVAN) && !(isCheshvanLong(year)))
+ || ((month == KISLEV) && isKislevShort(year)) || (month == TEVES)
+ || ((month == ADAR) && !(isJewishLeapYear(year))) || (month == ADAR_II)) {
+ return 29;
+ } else {
+ return 30;
+ }
+ }
+
+ /**
+ * Returns the number of days of the Jewish month that the calendar is currently set to.
+ *
+ * @return the number of days for the Jewish month that the calendar is currently set to.
+ */
+ public int getDaysInJewishMonth() {
+ return getDaysInJewishMonth(getJewishMonth(), getJewishYear());
+ }
+
+ /**
+ * Computes and sets the Jewish date fields based on the provided absolute (Gregorian) date.
+ * @param gregorianAbsDate the Gregorian absolute date.
+ */
+ private synchronized void setAbsDate(int gregorianAbsDate) {
+ if (gregorianAbsDate <= 0) {
+ throw new IllegalArgumentException("Dates in the BC era are not supported");
+ }
+ this.gregorianAbsDate = gregorianAbsDate;
+ // Approximation from below
+ jewishYear = (gregorianAbsDate - JEWISH_EPOCH) / 366;
+ // Search forward for year from the approximation
+ while (gregorianAbsDate >= jewishDateToAbsDate(jewishYear + 1, TISHREI, 1)) {
+ jewishYear++;
+ }
+ // Search forward for month from either Tishri or Nissan.
+ if (gregorianAbsDate < jewishDateToAbsDate(jewishYear, NISSAN, 1)) {
+ jewishMonth = TISHREI;// Start at Tishri
+ } else {
+ jewishMonth = NISSAN;// Start at Nissan
+ }
+ while (gregorianAbsDate > jewishDateToAbsDate(jewishYear, jewishMonth, getDaysInJewishMonth())) {
+ jewishMonth++;
+ }
+ // Calculate the day by subtraction
+ jewishDay = gregorianAbsDate - jewishDateToAbsDate(jewishYear, jewishMonth, 1) + 1;
+
+ // day of week (same calculation as original)
+ dayOfWeek = Math.abs(gregorianAbsDate % 7) + 1;
+ }
+
+ /**
+ * Returns the absolute date of Jewish date. ND+ER
+ *
+ * @param year
+ * the Jewish year. The year can't be negative
+ * @param month
+ * the Jewish month starting with Nissan. Nissan expects a value of 1 etc. until Adar with a value of 12.
+ * For a leap year, 13 will be the expected value for Adar II. Use the constants {@link JewishDate#NISSAN}
+ * etc.
+ * @param dayOfMonth
+ * the Jewish day of month. valid values are 1-30. If the day of month is set to 30 for a month that only
+ * has 29 days, the day will be set as 29.
+ * @return the absolute date of the Jewish date.
+ */
+ private static int jewishDateToAbsDate(int year, int month, int dayOfMonth) {
+ int elapsed = getDaysSinceStartOfJewishYear(year, month, dayOfMonth);
+ // add elapsed days this year + Days in prior years + Days elapsed before absolute year 1
+ return elapsed + getJewishCalendarElapsedDays(year) + JEWISH_EPOCH;
+ }
+
+ /**
+ * Returns the molad for a given year and month. Returns a JewishDate {@link Object} set to the date of the molad
+ * with the {@link #getMoladHours() hours}, {@link #getMoladMinutes() minutes} and {@link #getMoladChalakim()
+ * chalakim} set. In the current implementation, it sets the molad time based on a midnight date rollover. This
+ * means that Rosh Chodesh Adar II, 5771 with a molad of 7 chalakim past midnight on Shabbos 29 Adar I / March 5,
+ * 2011 12:00 AM and 7 chalakim, will have the following values: hours: 0, minutes: 0, Chalakim: 7.
+ *
+ * @return a JewishDate {@link Object} set to the date of the molad with the {@link #getMoladHours() hours},
+ * {@link #getMoladMinutes() minutes} and {@link #getMoladChalakim() chalakim} set.
+ */
+ public JewishDate getMolad() {
+ JewishDate moladDate = new JewishDate(getChalakimSinceMoladTohu());
+ if (moladDate.getMoladHours() >= 6) {
+ moladDate.plusDays(1);
+ }
+ moladDate.setMoladHours((moladDate.getMoladHours() + 18) % 24);
+ return moladDate;
+ }
+
+ /**
+ * Returns the number of days from the Jewish epoch from the number of chalakim from the epoch passed in.
+ *
+ * @param chalakim
+ * the number of chalakim since the beginning of Sunday prior to BaHaRaD
+ * @return the number of days from the Jewish epoch
+ */
+ private static int moladToAbsDate(long chalakim) {
+ return (int) (chalakim / CHALAKIM_PER_DAY) + JEWISH_EPOCH;
+ }
+
+ /**
+ * Constructor that creates a JewishDate based on a molad passed in. The molad would be the number of
+ * chalakim / parts starting at the beginning of Sunday prior to the Molad Tohu BeHaRaD (Be =
+ * Monday, Ha = 5 hours and RaD = 204 chalakim / parts) - prior to the start of the Jewish
+ * calendar. BeHaRaD is 23:11:20 on Sunday night(5 hours 204/1080 chalakim after sunset on Sunday evening).
+ *
+ * @param molad the number of chalakim since the beginning of Sunday prior to BaHaRaD
+ */
+ public JewishDate(long molad) {
+ setAbsDate(moladToAbsDate(molad));
+ int conjunctionDay = (int) (molad / (long) CHALAKIM_PER_DAY);
+ int chalakim = (int) (molad - conjunctionDay * (long) CHALAKIM_PER_DAY);
+ setMoladHours(chalakim / CHALAKIM_PER_HOUR);
+ chalakim = chalakim - (getMoladHours() * CHALAKIM_PER_HOUR);
+ setMoladMinutes(chalakim / CHALAKIM_PER_MINUTE);
+ setMoladChalakim(chalakim - moladMinutes * CHALAKIM_PER_MINUTE);
+ }
+
+ /**
+ * returns the number of days from Rosh Hashana of the date passed in, to the full date passed in.
+ *
+ * @param year
+ * the Jewish year
+ * @param month
+ * the Jewish month
+ * @param dayOfMonth
+ * the day in the Jewish month
+ * @return the number of days
+ */
+ private static int getDaysSinceStartOfJewishYear(int year, int month, int dayOfMonth) {
+ int elapsedDays = dayOfMonth;
+ // Before Tishrei (from Nissan to Tishrei), add days in prior months
+ if (month < TISHREI) {
+ // this year before and after Nissan.
+ for (int m = TISHREI; m <= getLastMonthOfJewishYear(year); m++) {
+ elapsedDays += getDaysInJewishMonth(m, year);
+ }
+ for (int m = NISSAN; m < month; m++) {
+ elapsedDays += getDaysInJewishMonth(m, year);
+ }
+ } else { // Add days in prior months this year
+ for (int m = TISHREI; m < month; m++) {
+ elapsedDays += getDaysInJewishMonth(m, year);
+ }
+ }
+ return elapsedDays;
+ }
+
+ /**
+ * returns the number of days from Rosh Hashana of the date passed in, to the full date passed in.
+ *
+ * @return the number of days
+ */
+ public int getDaysSinceStartOfJewishYear() {
+ return getDaysSinceStartOfJewishYear(getJewishYear(), getJewishMonth(), getJewishDayOfMonth());
+ }
+
+ /**
+ * Creates a Jewish date based on a Jewish year, month and day of month.
+ *
+ * @param jewishYear
+ * the Jewish year
+ * @param jewishMonth
+ * the Jewish month. The method expects a 1 for Nissan ... 12 for Adar and 13 for Adar II. Use the
+ * constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar II) to avoid any
+ * confusion.
+ * @param jewishDayOfMonth
+ * the Jewish day of month. If 30 is passed in for a month with only 29 days (for example {@link #IYAR},
+ * or {@link #KISLEV} in a year that {@link #isKislevShort()}), the 29th (last valid date of the month)
+ * will be set
+ * @throws IllegalArgumentException
+ * if the day of month is < 1 or > 30, or a year of < 0 is passed in.
+ */
+ public JewishDate(int jewishYear, int jewishMonth, int jewishDayOfMonth) {
+ setJewishDate(jewishYear, jewishMonth, jewishDayOfMonth);
+ }
+
+ /**
+ * Default constructor will set a default date to the current system date.
+ */
+ public JewishDate() {
+ resetDate();
+ }
+
+ /**
+ * A constructor that initializes the date to the {@link ZonedDateTime} parameter.
+ *
+ * @param zonedDateTime
+ * the ZonedDateTime to set the calendar to
+ */
+ public JewishDate(ZonedDateTime zonedDateTime) {
+ setGregorianDate(zonedDateTime);
+ }
+
+ /**
+ * A constructor that initializes the date to the {@link LocalDate} parameter.
+ *
+ * @param localDate
+ * the LocalDate to set the calendar to
+ */
+ public JewishDate(LocalDate localDate) {
+ setGregorianDate(localDate);
+ }
+
+ /**
+ * Sets the date based on a {@link ZonedDateTime} object. Modifies the Jewish date as well.
+ *
+ * @param zonedDateTime
+ * the {@link ZonedDateTime} to set the calendar to
+ */
+ public void setGregorianDate(ZonedDateTime zonedDateTime) {
+ setGregorianDate(zonedDateTime.toLocalDate());
+ }
+
+ /**
+ * Sets the date based on a {@link LocalDate} object. Modifies the Jewish date as well.
+ *
+ * @param localDate
+ * the LocalDate to set the calendar to
+ * @throws IllegalArgumentException
+ * if the date would fall prior to the year 1 AD
+ */
+ public void setGregorianDate(LocalDate localDate) {
+ int absDate = gregorianDateToAbsDate(localDate.getYear(), localDate.getMonth().getValue(), localDate.getDayOfMonth());
+ setAbsDate(absDate); // convert to Jewish date
+ }
+
+ /**
+ * Sets the Jewish Date and updates the Gregorian date accordingly.
+ *
+ * @param year
+ * the Jewish year. The year can't be negative
+ * @param month
+ * the Jewish month starting with Nissan. A value of 1 is expected for Nissan ... 12 for Adar and 13 for
+ * Adar II. Use the constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar
+ * II) to avoid any confusion.
+ * @param dayOfMonth
+ * the Jewish day of month. valid values are 1-30. If the day of month is set to 30 for a month that only
+ * has 29 days, the day will be set as 29.
+ * @throws IllegalArgumentException
+ * if a Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a
+ * leap year) or the day of month is < 1 or > 30 is passed in
+ */
+ public void setJewishDate(int year, int month, int dayOfMonth) {
+ setJewishDate(year, month, dayOfMonth, getMoladHours(), getMoladMinutes(), getMoladChalakim());
+ }
+
+ /**
+ * Sets the Jewish Date and updates the Gregorian date accordingly.
+ *
+ * @param year
+ * the Jewish year. The year can't be negative
+ * @param month
+ * the Jewish month starting with Nissan. A value of 1 is expected for Nissan ... 12 for Adar and 13 for
+ * Adar II. Use the constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar
+ * II) to avoid any confusion.
+ * @param dayOfMonth
+ * the Jewish day of month. valid values are 1-30. If the day of month is set to 30 for a month that only
+ * has 29 days, the day will be set as 29.
+ *
+ * @param hours
+ * the hour of the day. Used for molad calculations
+ * @param minutes
+ * the minutes. Used for molad calculations
+ * @param chalakim
+ * the chalakim / parts. Used for molad calculations. The chalakim should not
+ * exceed 17. Minutes should be used for larger numbers.
+ *
+ * @throws IllegalArgumentException
+ * if a Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian), a month < 1 or > 12 (or 13 on a leap year), the day
+ * of month is < 1 or > 30, an hour < 0 or > 23, a minute < 0 > 59 or chalakim < 0 > 17. For
+ * 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 synchronized void setJewishDate(int year, int month, int dayOfMonth, int hours, int minutes, int chalakim) {
+
+ validateJewishDate(year, month, dayOfMonth, hours, minutes, chalakim);
+
+ jewishMonth = month;
+ jewishDay = dayOfMonth;
+ jewishYear = year;
+ moladHours = hours;
+ moladMinutes = minutes;
+ moladChalakim = chalakim;
+
+ gregorianAbsDate = jewishDateToAbsDate(jewishYear, jewishMonth, jewishDay); // reset Gregorian date
+
+ dayOfWeek = Math.abs(gregorianAbsDate % 7) + 1; // reset day of week
+ }
+
+ /**
+ * Setter for the Jewish day of the month that will be clamped to the lesser of the number passed in or the max number of days in the month.
+ * @param dayOfMonth the day of the month to set the date to.
+ */
+ public void setJewishDayOfMonth(int dayOfMonth){
+ setJewishDate(getJewishYear(), getJewishMonth(), dayOfMonth);
+ }
+
+ /**
+ * Setter for the Jewish month that is passed in. If the day of month is currently the 30th and the month is being set to
+ * a month that only has 29 days, the day of month will be clamped to the 29th of the month.
+ * @param month the month to be set
+ */
+ public void setJewishMonth(int month){
+ int year = getJewishYear();
+ int day = Math.min(getDaysInJewishMonth(month,year),getJewishDayOfMonth());
+ setJewishDate(year, month, day);
+ }
+
+ /**
+ * Setter for the Jewish year of the passed in that will clamp the day to the month to the lesser of the current day and the max number of days in the month (if set
+ * to the 30th).
+ *
+ * Note that if you are using this for a yahrzeit (or any other reason)on the 30th of the month that will not always have
+ * 30 days, such as {@link #CHESHVAN} or {@link #KISLEV} or {@link #ADAR ADAR I} on a leap year and the next year is a
+ * non-leap year, you must clone your date or once it is set to the 29th, the next time you forward it to a year that has
+ * 30 days, the calendar will incorrectly be forwarded a year from the 29th to the 29th and not the 30th that you may expect.
+ * @param year the year to set.
+ */
+ public void setJewishYear(int year){
+ int month = Math.min(getJewishMonth(),getLastMonthOfJewishYear(year));
+ int day = Math.min(getJewishDayOfMonth(), getDaysInJewishMonth(month,year));
+ setJewishDate(year, month, day);
+ }
+
+
+ /**
+ * Returns this object's date as a {@link LocalDate} object.
+ *
+ * @return The {@link LocalDate}
+ */
+ public LocalDate getLocalDate() {
+ return absDateToDate(getAbsDate());
+ }
+
+ /**
+ * Resets this date to the current system date.
+ */
+ public void resetDate() {
+ LocalDate localDate = LocalDate.now();
+ setGregorianDate(localDate);
+ }
+
+ /**
+ * Subtracts the number of days passed in from the currently set date.
+ * @param days the number of days to subtract.
+ * @see plusDays(int)
+ */
+ public void minusDays(int days){
+ if (days < 1) {
+ throw new IllegalArgumentException("The number of days to subtract must be greater than zero.");
+ }
+ setAbsDate(getAbsDate() - days);
+
+ }
+
+ /**
+ * Add the number of days passed in to the currently set date.
+ * @param days the number of days to add.
+ *
+ * @see minusDays(int)
+ */
+ public void plusDays(int days){
+ if (days < 1) {
+ throw new IllegalArgumentException("The number of days to add must be greater than zero. Use minusDays(int) to subtract days.");
+ }
+ setAbsDate(getAbsDate() + days);
+ }
+
+ /**
+ * Add the number of months passed in to the currently set date. If the day of the month prior to addition is the 30th, and
+ * the target month only has 29 days, the date will be clamped to the 29th.
+ * @param months the number of months to add.
+ * @see minusMonths(int)
+ */
+ public void plusMonths(int months){
+ if (months < 1) {
+ throw new IllegalArgumentException("The number of months to add must be greater than zero. Use minusMonths(int) to subtract months.");
+ }
+ int year = getJewishYear();
+ int month = getJewishMonth();
+ for (int i = 0; i < months; i++) {
+ if (month == ELUL) {
+ month = TISHREI;
+ year++;
+ } else if ((! isJewishLeapYear(year) && month == ADAR)
+ || (isJewishLeapYear(year) && month == ADAR_II)){
+ month = NISSAN;
+ } else {
+ month++;
+ }
+ }
+ int day = Math.min(getJewishDayOfMonth(), getDaysInJewishMonth(month,year));
+ setJewishDate(year, month, day);
+ }
+
+ /**
+ * Subtracts the number of months passed in to the currently set date. If the day of the month prior to subtraction
+ * is the 30th, and the target month only has 29 days, the date will be clamped to the 29th.
+ * @param months the number of months to add.
+ * @see plusMonths(int)
+ */
+ public void minusMonths(int months){
+ if (months < 1) {
+ throw new IllegalArgumentException("The number of months to subtract must be greater than zero.");
+ }
+ int year = getJewishYear();
+ int month = getJewishMonth();
+ for (int i = 0; i < months; i++) {
+ if (month == TISHREI) {
+ month = ELUL;
+ year--;
+ } else if (month == NISSAN) {
+ month = getLastMonthOfJewishYear(year);
+ } else if (!isJewishLeapYear(year) && month == ADAR){
+ month = SHEVAT;
+ } else {
+ month--;
+ }
+ }
+ int day = Math.min(getJewishDayOfMonth(), getDaysInJewishMonth(month,year));
+ setJewishDate(year, month, day);
+ }
+
+ /**
+ * Add the number of years passed in to the currently set date. If the current month is Adar on a non-leap year,
+ * and the year after the addition will be a leap year, passing true to the useAdarAlephForLeapYear
+ * parameter will set the month to Adar I, and passing false will forward it to Adar II. The
+ * useAdarAlephForLeapYear will be ignored if the month is not Adar. If the current year is a leap year and it is
+ * currently Adar I or Adar II and the year it is being increased to is also a leap year, the same Adar will be used.
+ * If it is being increased to a non-leap year, the month will be set to Adar. It is important to keep in mind when
+ * calculating yahrzits that are on the 30th and the target year only has 29 days, that the date will be set
+ * to the 29th, something that may nt be desirable.
+ * @param years the number of years to add
+ * @param useAdarAlephForLeapYear if set to true and the current month is Adar on a non-leap year and it is being moved
+ * forward to a leap year, it will be set to Adar I, and if set to false it will set to Adar II. This will be
+ * ignored if the month is not set to Adar.
+ * @see minusYears(int, boolean)
+ */
+ public void plusYears(int years, boolean useAdarAlephForLeapYear){
+ if (years < 1) {
+ throw new IllegalArgumentException("The number of years to add has to be greater than zero. Use minusYears(int, boolean) to subtract years.");
+ }
+ int targetYear = getJewishYear() + years;
+ // If we are in the month of Adar in a non-leap year and we are skipping
+ // to a year that is a leap year, we will use useAdarAlephInYear do
+ // decide which month to skip to.
+ int month;
+ if (getJewishMonth() == JewishDate.ADAR && !isJewishLeapYear(getJewishYear()) && isJewishLeapYear(targetYear)){
+ if (useAdarAlephForLeapYear){
+ month = JewishDate.ADAR;
+ }else{
+ month = JewishDate.ADAR_II;
+ }
+ } else{
+ // If we are in JewishDate.ADAR_II, this will clamp the month to 12 (JewishDate.ADAR)
+ month = Math.min(getJewishMonth(),getLastMonthOfJewishYear(targetYear));
+ }
+ // Clamp to final day of the month
+ int day = Math.min(getJewishDayOfMonth(), getDaysInJewishMonth(month,targetYear));
+ setJewishDate(targetYear, month, day);
+ }
+
+ /**
+ * Subtract the number of years passed in to the currently set date. If the current month is Adar on a non-leap year,
+ * and the year after the subtraction will be a leap year, passing true to the useAdarAlephForLeapYear
+ * parameter will set the month to Adar I, and passing false will set it to Adar II. The
+ * useAdarAlephForLeapYear will be ignored if the current month is not Adar on a non-leap year. If the current year
+ * is a leap year and it is currently Adar I or Adar II and the year it is being decreased to is also a leap year,
+ * the same Adar will be used. If it is being decreased to a non-leap year, the month will be set to Adar.
+ * @param years the number of years to subtract
+ * @param useAdarAlephForLeapYear if set to true and the current month is Adar on a non-leap year and it is being
+ * subtracted to a leap year, it will be set to Adar I, and if set to false it will set to Adar II. This will
+ * be ignored if the month is not set to Adar.
+ * @see plusYears(int, boolean)
+ */
+ public void minusYears(int years, boolean useAdarAlephForLeapYear){
+ if (years < 1) {
+ throw new IllegalArgumentException("The number of years to add has to be greater than zero.");
+ }
+ int targetYear = getJewishYear() - years;
+ // If we are in the month of Adar in a non-leap year and we are skipping
+ // to a year that is a leap year, we will use useAdarAlephInYear do
+ // decide which month to skip to.
+ int month;
+ if (getJewishMonth() == JewishDate.ADAR && !isJewishLeapYear(getJewishYear()) && isJewishLeapYear(targetYear)){
+ if (useAdarAlephForLeapYear){
+ month = JewishDate.ADAR;
+ }else{
+ month = JewishDate.ADAR_II;
+ }
+ } else{
+ // If we are in JewishDate.ADAR_II, this will clamp the month to 12 (JewishDate.ADAR)
+ month = Math.min(getJewishMonth(),getLastMonthOfJewishYear(targetYear));
+ }
+ // Clamp to final day of the month
+ int day = Math.min(getJewishDayOfMonth(), getDaysInJewishMonth(month,targetYear));
+ setJewishDate(targetYear, month, day);
+ }
+
+ /**
+ * Returns a string containing the Jewish date in the form, "day Month, year" e.g. "21 Shevat, 5729". For more
+ * complex formatting, use the formatter classes.
+ *
+ * @return the Jewish date in the form "day Month, year" e.g. "21 Shevat, 5729"
+ * @see HebrewDateFormatter#format(JewishDate)
+ */
+ public String toString() {
+ return new HebrewDateFormatter().format(this);
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object == null || getClass() != object.getClass()) {
+ return false;
+ }
+ JewishDate jewishDate = (JewishDate) object;
+ return gregorianAbsDate == jewishDate.getAbsDate();
+ }
+
+ /**
+ * Compares two dates as per the compareTo() method in the Comparable interface. Returns a value less than 0 if this
+ * date is "less than" (before) the date, greater than 0 if this date is "greater than" (after) the date, or 0 if
+ * they are equal.
+ */
+ public int compareTo(JewishDate jewishDate) {
+ return Integer.compare(gregorianAbsDate, jewishDate.getAbsDate());
+ }
+
+ /**
+ * Returns the Jewish month 1-12 (or 13 years in a leap year). The month count starts with 1 for Nissan and goes to
+ * 13 for Adar II
+ *
+ * @return the Jewish month from 1 to 12 (or 13 years in a leap year). The month count starts with 1 for Nissan and
+ * goes to 13 for Adar II
+ */
+ public int getJewishMonth() {
+ return jewishMonth;
+ }
+
+ /**
+ * Returns the Jewish day of month.
+ *
+ * @return the Jewish day of the month
+ */
+ public int getJewishDayOfMonth() {
+ return jewishDay;
+ }
+
+ /**
+ * Returns the Jewish year.
+ *
+ * @return the Jewish year
+ */
+ public int getJewishYear() {
+ return jewishYear;
+ }
+
+ /**
+ * Returns the day of the week as a number between 1-7.
+ *
+ * @return the day of the week as a number between 1-7.
+ */
+ public int getDayOfWeek() {
+ return dayOfWeek;
+ }
+
+ /**
+ * A method that creates a deep copy of the object.
+ *
+ * @see Object#clone()
+ */
+ public Object clone() {
+ JewishDate clone = null;
+ try {
+ clone = (JewishDate) super.clone();
+ } catch (CloneNotSupportedException cnse) {
+ // Required by the compiler. Should never be reached since we implement clone()
+ }
+ if (clone != null) {
+ clone.setAbsDate(getAbsDate());
+ clone.setMoladHours(getMoladHours());
+ clone.setMoladMinutes(getMoladMinutes());
+ clone.setMoladChalakim(getMoladChalakim());
+ }
+ return clone;
+ }
+
+ /**
+ * Overrides {@link Object#hashCode()}.
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return Integer.hashCode(gregorianAbsDate);
+ }
}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TefilaRules.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TefilaRules.java
index 7e1c3b2b..68d7315e 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TefilaRules.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TefilaRules.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2019 - 2025 Eliyahu Hershfeld
+ * Copyright (C) 2019 - 2026 Eliyahu Hershfeld
* Copyright (C) 2019 - 2021 Y Paritcher
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
@@ -45,7 +45,7 @@
* System.out.println(hdf.format(jewishCalendar) + ": " + tr.isTachanunRecitedShacharis(jewishCalendar));
*
* @author © Y. Paritcher 2019 - 2021
- * @author © Eliyahu Hershfeld 2019 - 2025
+ * @author © Eliyahu Hershfeld 2019 - 2026
*
* @todo The following items may be added at a future date.
*
@@ -177,34 +177,31 @@ public boolean isTachanunRecitedShacharis(JewishCalendar jewishCalendar) {
int day = jewishCalendar.getJewishDayOfMonth();
int month = jewishCalendar.getJewishMonth();
- if (jewishCalendar.getDayOfWeek() == Calendar.SATURDAY
- || (! tachanunRecitedSundays && jewishCalendar.getDayOfWeek() == Calendar.SUNDAY)
- || (! tachanunRecitedFridays && jewishCalendar.getDayOfWeek() == Calendar.FRIDAY)
- || month == JewishDate.NISSAN
- || (month == JewishDate.TISHREI && ((! tachanunRecitedEndOfTishrei && day > 8)
- || (tachanunRecitedEndOfTishrei && (day > 8 && day < 22))))
- || (month == JewishDate.SIVAN && (tachanunRecitedWeekAfterShavuos && day < 7
- || ! tachanunRecitedWeekAfterShavuos && day < (! jewishCalendar.getInIsrael()
- && ! tachanunRecited13SivanOutOfIsrael ? 14: 13)))
- || jewishCalendar.isErevYomTov() || (jewishCalendar.isYomTov() && (! jewishCalendar.isTaanis() //FIXME logic needs review for 15 shevat
- || (! tachanunRecitedPesachSheni && holidayIndex == JewishCalendar.PESACH_SHENI)))
- || (! jewishCalendar.getInIsrael() && ! tachanunRecitedPesachSheni && ! tachanunRecited15IyarOutOfIsrael
- && jewishCalendar.getJewishMonth() == JewishDate.IYAR && day == 15)
- || holidayIndex == JewishCalendar.TISHA_BEAV || jewishCalendar.isIsruChag()
- || jewishCalendar.isRoshChodesh()
- || (! tachanunRecitedShivasYemeiHamiluim &&
- ((! jewishCalendar.isJewishLeapYear() && month == JewishDate.ADAR)
- || (jewishCalendar.isJewishLeapYear() && month == JewishDate.ADAR_II)) && day > 22)
- || (! tachanunRecitedWeekOfPurim &&
- ((! jewishCalendar.isJewishLeapYear() && month == JewishDate.ADAR)
- || (jewishCalendar.isJewishLeapYear() && month == JewishDate.ADAR_II)) && day > 10 && day < 18)
- || (jewishCalendar.isUseModernHolidays()
- && (holidayIndex == JewishCalendar.YOM_HAATZMAUT || holidayIndex == JewishCalendar.YOM_YERUSHALAYIM))
- || (! tachanunRecitedWeekOfHod && month == JewishDate.IYAR && day > 13 && day < 21)) {
- return false;
- }
- return true;
- }
+ return jewishCalendar.getDayOfWeek() != Calendar.SATURDAY
+ && (tachanunRecitedSundays || jewishCalendar.getDayOfWeek() != Calendar.SUNDAY)
+ && (tachanunRecitedFridays || jewishCalendar.getDayOfWeek() != Calendar.FRIDAY)
+ && month != JewishDate.NISSAN
+ && (month != JewishDate.TISHREI || ((tachanunRecitedEndOfTishrei || day <= 8)
+ && (!tachanunRecitedEndOfTishrei || (day <= 8 || day >= 22))))
+ && (month != JewishDate.SIVAN || ((!tachanunRecitedWeekAfterShavuos || day >= 7)
+ && (tachanunRecitedWeekAfterShavuos || day >= (!jewishCalendar.getInIsrael()
+ && !tachanunRecited13SivanOutOfIsrael ? 14 : 13))))
+ && !jewishCalendar.isErevYomTov() && (!jewishCalendar.isYomTov() || (jewishCalendar.isTaanis() //FIXME logic needs review for 15 shevat
+ && (tachanunRecitedPesachSheni || holidayIndex != JewishCalendar.PESACH_SHENI)))
+ && (jewishCalendar.getInIsrael() || tachanunRecitedPesachSheni || tachanunRecited15IyarOutOfIsrael
+ || jewishCalendar.getJewishMonth() != JewishDate.IYAR || day != 15)
+ && holidayIndex != JewishCalendar.TISHA_BEAV && !jewishCalendar.isIsruChag()
+ && !jewishCalendar.isRoshChodesh()
+ && (tachanunRecitedShivasYemeiHamiluim ||
+ ((jewishCalendar.isJewishLeapYear() || month != JewishDate.ADAR)
+ && (!jewishCalendar.isJewishLeapYear() || month != JewishDate.ADAR_II)) || day <= 22)
+ && (tachanunRecitedWeekOfPurim ||
+ ((jewishCalendar.isJewishLeapYear() || month != JewishDate.ADAR)
+ && (!jewishCalendar.isJewishLeapYear() || month != JewishDate.ADAR_II)) || day <= 10 || day >= 18)
+ && (!jewishCalendar.isUseModernHolidays()
+ || (holidayIndex != JewishCalendar.YOM_HAATZMAUT && holidayIndex != JewishCalendar.YOM_YERUSHALAYIM))
+ && (tachanunRecitedWeekOfHod || month != JewishDate.IYAR || day <= 13 || day >= 21);
+ }
/**
* Returns if tachanun is recited during mincha on the day in question.
@@ -215,20 +212,17 @@ public boolean isTachanunRecitedShacharis(JewishCalendar jewishCalendar) {
*/
public boolean isTachanunRecitedMincha(JewishCalendar jewishCalendar) {
JewishCalendar tomorrow = (JewishCalendar) jewishCalendar.clone();
- tomorrow.forward(Calendar.DATE, 1);
-
- if (! tachanunRecitedMinchaAllYear
- || jewishCalendar.getDayOfWeek() == Calendar.FRIDAY
- || ! isTachanunRecitedShacharis(jewishCalendar)
- || (! isTachanunRecitedShacharis(tomorrow) &&
- !(tomorrow.getYomTovIndex() == JewishCalendar.EREV_ROSH_HASHANA) &&
- !(tomorrow.getYomTovIndex() == JewishCalendar.EREV_YOM_KIPPUR) &&
- !(tomorrow.getYomTovIndex() == JewishCalendar.PESACH_SHENI))
- || ! tachanunRecitedMinchaErevLagBaomer && tomorrow.getYomTovIndex() == JewishCalendar.LAG_BAOMER) {
- return false;
- }
- return true;
- }
+ tomorrow.plusDays(1);
+
+ return tachanunRecitedMinchaAllYear
+ && jewishCalendar.getDayOfWeek() != Calendar.FRIDAY
+ && isTachanunRecitedShacharis(jewishCalendar)
+ && (isTachanunRecitedShacharis(tomorrow) ||
+ tomorrow.getYomTovIndex() == JewishCalendar.EREV_ROSH_HASHANA ||
+ tomorrow.getYomTovIndex() == JewishCalendar.EREV_YOM_KIPPUR ||
+ tomorrow.getYomTovIndex() == JewishCalendar.PESACH_SHENI)
+ && (tachanunRecitedMinchaErevLagBaomer || tomorrow.getYomTovIndex() != JewishCalendar.LAG_BAOMER);
+ }
/**
* Returns if it is the Jewish day (starting the evening before) to start reciting Vesein Tal Umatar Livracha
@@ -446,12 +440,8 @@ public boolean isHallelShalemRecited(JewishCalendar jewishCalendar) {
int month = jewishCalendar.getJewishMonth();
boolean inIsrael = jewishCalendar.getInIsrael();
if (isHallelRecited(jewishCalendar)) {
- if ((jewishCalendar.isRoshChodesh() && ! jewishCalendar.isChanukah())
- || (month == JewishDate.NISSAN && ((inIsrael && day > 15) || (! inIsrael && day > 16)))) {
- return false;
- } else {
- return true;
- }
+ return (!jewishCalendar.isRoshChodesh() || jewishCalendar.isChanukah())
+ && (month != JewishDate.NISSAN || ((!inIsrael || day <= 15) && (inIsrael || day <= 16)));
}
return false;
}
@@ -503,14 +493,11 @@ public boolean isMizmorLesodaRecited(JewishCalendar jewishCalendar) {
}
int holidayIndex = jewishCalendar.getYomTovIndex();
- if (! isMizmorLesodaRecitedErevYomKippurAndPesach()
- && (holidayIndex == JewishCalendar.EREV_YOM_KIPPUR
- || holidayIndex == JewishCalendar.EREV_PESACH
- || jewishCalendar.isCholHamoedPesach())) {
- return false;
- }
- return true;
- }
+ return isMizmorLesodaRecitedErevYomKippurAndPesach()
+ || (holidayIndex != JewishCalendar.EREV_YOM_KIPPUR
+ && holidayIndex != JewishCalendar.EREV_PESACH
+ && !jewishCalendar.isCholHamoedPesach());
+ }
/**
* Is tachanun set to be recited during the week of Purim, from the 11th through the 17th of {@link
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YerushalmiYomiCalculator.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YerushalmiYomiCalculator.java
index a5603e9b..e9dee2c4 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YerushalmiYomiCalculator.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YerushalmiYomiCalculator.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2017 - 2025 Eliyahu Hershfeld
+ * Copyright (C) 2017 - 2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,161 +15,158 @@
*/
package com.kosherjava.zmanim.hebrewcalendar;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
/**
* This class calculates the Talmud Yerusalmi Daf Yomi page ({@link Daf}) for the a given date.
*
* @author © elihaidv
- * @author © Eliyahu Hershfeld 2017 - 2025
+ * @author © Eliyahu Hershfeld 2017 - 2026
*/
public class YerushalmiYomiCalculator {
-
- /**
- * The start date of the first Daf Yomi Yerushalmi cycle of February 2, 1980 / 15 Shevat, 5740.
- */
- private final static Calendar DAF_YOMI_START_DAY = new GregorianCalendar(1980, Calendar.FEBRUARY, 2);
- /** The number of milliseconds in a day. */
- private final static int DAY_MILIS = 1000 * 60 * 60 * 24;
- /** The number of pages in the Talmud Yerushalmi.*/
- private final static int WHOLE_SHAS_DAFS = 1554;
- /** The number of pages per masechta (tractate).*/
- private final static int[] BLATT_PER_MASECHTA = {
- 68, 37, 34, 44, 31, 59, 26, 33, 28, 20, 13, 92, 65, 71, 22, 22, 42, 26, 26, 33, 34, 22,
- 19, 85, 72, 47, 40, 47, 54, 48, 44, 37, 34, 44, 9, 57, 37, 19, 13};
-
- /**
- * Default constructor.
- */
- public YerushalmiYomiCalculator() {
- // nothing here
- }
-
- /**
- * Returns the Daf Yomi
- * Yerusalmi page ({@link Daf}) for a given date.
- * The first Daf Yomi cycle started on 15 Shevat (Tu Bishvat), 5740 (February, 2, 1980) and calculations
- * prior to this date will result in an IllegalArgumentException thrown. A null will be returned on Tisha B'Av or
- * Yom Kippur.
- *
- * @param calendar
- * the calendar date for calculation
- * @return the {@link Daf} or null if the date is on Tisha B'Av or Yom Kippur.
- *
- * @throws IllegalArgumentException
- * if the date is prior to the February 2, 1980, the start of the first Daf Yomi Yerushalmi cycle
- */
- public static Daf getDafYomiYerushalmi(JewishCalendar calendar) {
-
- Calendar nextCycle = new GregorianCalendar();
- Calendar prevCycle = new GregorianCalendar();
- Calendar requested = calendar.getGregorianCalendar();
- int masechta = 0;
- Daf dafYomi = null;
-
- // There isn't Daf Yomi on Yom Kippur or Tisha B'Av.
- if ( calendar.getYomTovIndex() == JewishCalendar.YOM_KIPPUR ||
- calendar.getYomTovIndex() == JewishCalendar.TISHA_BEAV ) {
- return null;
- }
-
-
- if (requested.before(DAF_YOMI_START_DAY)) {
- throw new IllegalArgumentException(requested + " is prior to organized Daf Yomi Yerushalmi cycles that started on "
- + DAF_YOMI_START_DAY);
- }
-
- // Start to calculate current cycle. init the start day
- nextCycle.setTime(DAF_YOMI_START_DAY.getTime());
-
- // Go cycle by cycle, until we get the next cycle
- while (requested.after(nextCycle)) {
- prevCycle.setTime(nextCycle.getTime());
-
- // Adds the number of whole shas dafs. and the number of days that not have daf.
- nextCycle.add(Calendar.DAY_OF_MONTH, WHOLE_SHAS_DAFS);
- nextCycle.add(Calendar.DAY_OF_MONTH, getNumOfSpecialDays(prevCycle, nextCycle));
- }
-
- // Get the number of days from cycle start until request.
- int dafNo = (int)(getDiffBetweenDays(prevCycle, requested));
-
- // Get the number of special day to subtract
- int specialDays = getNumOfSpecialDays(prevCycle, requested);
- int total = dafNo - specialDays;
-
- // Finally find the daf.
- for (int i : BLATT_PER_MASECHTA) {
- if (total < i) {
- dafYomi = new Daf(masechta, total + 1);
- break;
- }
- total -= i;
- masechta++;
- }
-
- return dafYomi;
- }
-
- /**
- * Return the number of special days (Yom Kippur and Tisha Beav, where there are no dafim), between the start date
- * (as a Calendar) and end date (also as a Calendar).
- *
- * @param start date to start calculating from
- * @param end date to finish calculating at
- * @return the number of special days between the start and end dates
- */
- private static int getNumOfSpecialDays(Calendar start, Calendar end) {
-
- // Find the start and end Jewish years
- int startYear = new JewishCalendar(start).getJewishYear();
- int endYear = new JewishCalendar(end).getJewishYear();
-
- // Value to return
- int specialDays = 0;
-
- //Instant of special Dates
- JewishCalendar yom_kippur = new JewishCalendar(5770, 7, 10);
- JewishCalendar tisha_beav = new JewishCalendar(5770, 5, 9);
-
- // Go over the years and find special dates
- for (int i = startYear; i <= endYear; i++) {
- yom_kippur.setJewishYear(i);
- tisha_beav.setJewishYear(i);
-
- if (isBetween(start, yom_kippur.getGregorianCalendar(), end)) {
- specialDays++;
- }
- if (isBetween(start, tisha_beav.getGregorianCalendar(), end)) {
- specialDays++;
- }
- }
-
- return specialDays;
- }
-
- /**
- * Return if the date is between two dates
- *
- * @param start the start date
- * @param date the date being compared
- * @param end the end date
- * @return if the date is between the start and end dates
- */
- private static boolean isBetween(Calendar start, Calendar date, Calendar end ) {
- return start.before(date) && end.after(date);
- }
-
- /**
- * Return the number of days between the dates passed in
- * @param start the start date
- * @param end the end date
- * @return the number of days between the start and end dates
- */
- private static long getDiffBetweenDays(Calendar start, Calendar end) {
- return (end.getTimeInMillis() - start.getTimeInMillis()) / DAY_MILIS;
- }
+
+ /** Start date of first Daf Yomi Yerushalmi cycle: 1980-02-02 */
+ private static final LocalDate DAF_YOMI_START_DAY = LocalDate.of(1980, 2, 2);
+
+ /** number of pages (blatt/dafim) in Shas*/
+ private static final int WHOLE_SHAS_DAFS = 1554;
+
+ /** number of pages (blatt/dafim) per masechta*/
+ private static final int[] BLATT_PER_MASECHTA = {
+ 68, 37, 34, 44, 31, 59, 26, 33, 28, 20, 13, 92, 65, 71, 22, 22, 42, 26, 26, 33, 34, 22,
+ 19, 85, 72, 47, 40, 47, 54, 48, 44, 37, 34, 44, 9, 57, 37, 19, 13
+ };
+
+ /**
+ * Default constructor.
+ */
+ public YerushalmiYomiCalculator() {
+ // No-op
+ }
+
+ /**
+ * Returns the Daf Yomi Yerushalmi page for a given Jewish date.
+ * Returns null on Yom Kippur or Tisha B’Av.
+ * @param jewishCalendar the JewishCalendar to set.
+ * @return the daf.
+ */
+ public static Daf getDafYomiYerushalmi(JewishCalendar jewishCalendar) {
+ LocalDate requested = jewishCalendar.getLocalDate();
+ int masechta = 0;
+ Daf dafYomi = null;
+
+ // No Daf Yomi on Yom Kippur or Tisha B'Av
+ if (jewishCalendar.getYomTovIndex() == JewishCalendar.YOM_KIPPUR ||
+ jewishCalendar.getYomTovIndex() == JewishCalendar.TISHA_BEAV) {
+ return null;
+ }
+
+ if (requested.isBefore(DAF_YOMI_START_DAY)) {
+ throw new IllegalArgumentException(requested + " is prior to the first Daf Yomi cycle starting on "
+ + DAF_YOMI_START_DAY);
+ }
+
+ // Initialize cycle dates
+ LocalDate prevCycle = DAF_YOMI_START_DAY;
+ LocalDate nextCycle = getNextCycleStart(prevCycle);
+
+ // Loop through cycles until we reach the requested date
+ while (!requested.isBefore(nextCycle)) {
+ prevCycle = nextCycle;
+ nextCycle = getNextCycleStart(prevCycle);
+ }
+
+ // Days between start of cycle and requested date
+ int dafNo = (int) getDiffBetweenDays(prevCycle, requested);
+
+ int specialDays = getNumOfSpecialDays(prevCycle, requested);
+ int total = dafNo - specialDays;
+
+ // Find the daf
+ for (int blatt : BLATT_PER_MASECHTA) {
+ if (total < blatt) {
+ dafYomi = new Daf(masechta, total + 1);
+ break;
+ }
+ total -= blatt;
+ masechta++;
+ }
+
+ return dafYomi;
+ }
+
+ /**
+ * Returns the start date of the cycle after the one beginning on {@code cycleStart}.
+ * The cycle end is inclusive, so skipped days on the tentative end date extend the cycle.
+ * @param cycleStart the first day of the current cycle
+ * @return the first day of the following cycle
+ */
+ private static LocalDate getNextCycleStart(LocalDate cycleStart) {
+ LocalDate endDate = cycleStart.plusDays(WHOLE_SHAS_DAFS - 1);
+ int specialDays = getNumOfSpecialDays(cycleStart, endDate);
+
+ while (specialDays > 0) {
+ LocalDate newStart = endDate.plusDays(1);
+ endDate = endDate.plusDays(specialDays);
+ specialDays = getNumOfSpecialDays(newStart, endDate);
+ }
+
+ return endDate.plusDays(1);
+ }
+
+ /**
+ * Counts the number of "special days" (Yom Kippur, Tisha B’Av) between two dates.
+ * @param start the start date for the calculation
+ * @param end the end date for the calculation
+ * @return the number of special days
+ */
+ private static int getNumOfSpecialDays(LocalDate start, LocalDate end) {
+
+ int startYear = new JewishCalendar(start).getJewishYear();
+ int endYear = new JewishCalendar(end).getJewishYear();
+
+ int specialDays = 0;
+
+ // Loop over each Jewish year in range
+ for (int year = startYear; year <= endYear; year++) {
+ // Create Yom Kippur and Tisha B’Av for that Jewish year
+ JewishCalendar yomKippur = new JewishCalendar(year, JewishCalendar.TISHREI, 10);
+ JewishCalendar tishaBeav = new JewishCalendar(year, JewishCalendar.AV, 9);
+ // Check if Tisha B'Av is a Nidche.
+ if (tishaBeav.getDayOfWeek() == 7) {
+ tishaBeav.plusDays(1);
+ }
+ LocalDate ykDate = yomKippur.getLocalDate();
+ LocalDate tbDate = tishaBeav.getLocalDate();
+
+ if (isBetween(start, ykDate, end)) specialDays++;
+ if (isBetween(start, tbDate, end)) specialDays++;
+ }
+
+ return specialDays;
+ }
+
+
+ /**
+ * Checks if a date is after start and on or before end.
+ * @param start the start ZonedDateTime
+ * @param date the ZonedDateTime to check
+ * @param end the end ZonedDateTime
+ * @return if the date is between the two dates
+ */
+ private static boolean isBetween(LocalDate start, LocalDate date, LocalDate end) {
+ return start.isBefore(date) && !end.isBefore(date);
+ }
+
+ /**
+ * Returns the number of full days between two ZonedDateTimes.
+ * @param start the start ZonedDateTime
+ * @param end the end ZonedDateTime
+ * @return the number of days between the dates.
+ */
+ private static long getDiffBetweenDays(LocalDate start, LocalDate end) {
+ return ChronoUnit.DAYS.between(start, end);
+ }
}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YomiCalculator.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YomiCalculator.java
index 90ba0b8c..59b62ba2 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YomiCalculator.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/YomiCalculator.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2011-2025 Eliyahu Hershfeld
+ * Copyright (C) 2011-2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,29 +15,29 @@
*/
package com.kosherjava.zmanim.hebrewcalendar;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
+import java.time.LocalDate;
+import java.time.Month;
/**
* This class calculates the Daf Yomi Bavli page (daf) for a given date. To calculate Daf Yomi Yerushalmi
* use the {@link YerushalmiYomiCalculator}. The library may cover Mishna Yomi etc. at some point in the future.
*
* @author © Bob Newell (original C code)
- * @author © Eliyahu Hershfeld 2011 - 2025
+ * @author © Eliyahu Hershfeld 2011 - 2026
*/
public class YomiCalculator {
/**
* The start date of the first Daf Yomi Bavli cycle of September 11, 1923 / Rosh Hashana 5684.
*/
- private static final Calendar dafYomiStartDay = new GregorianCalendar(1923, Calendar.SEPTEMBER, 11);
+ private static final LocalDate dafYomiStartDay = LocalDate.of(1923, Month.SEPTEMBER,11);
/** The start date of the first Daf Yomi Bavli cycle in the Julian calendar. Used internally for calculations.*/
private static final int dafYomiJulianStartDay = getJulianDay(dafYomiStartDay);
/**
* The date that the pagination for the Daf Yomi Maseches Shekalim changed to use the commonly used Vilna
* Shas pagination from the no longer commonly available Zhitomir / Slavuta Shas used by Rabbi Meir Shapiro.
*/
- private static final Calendar shekalimChangeDay = new GregorianCalendar(1975, Calendar.JUNE, 24);
+ private static final LocalDate shekalimChangeDay = LocalDate.of(1975, Month.JUNE, 24);
/** The Julian date that the cycle for Shekalim changed.
* @see #getDafYomiBavli(JewishCalendar) for details.
@@ -83,18 +83,18 @@ public static Daf getDafYomiBavli(JewishCalendar jewishCalendar) {
*/
int[] blattPerMasechta = { 64, 157, 105, 121, 22, 88, 56, 40, 35, 31, 32, 29, 27, 122, 112, 91, 66, 49, 90, 82,
119, 119, 176, 113, 24, 49, 76, 14, 120, 110, 142, 61, 34, 34, 28, 22, 4, 9, 5, 73 };
- Calendar calendar = jewishCalendar.getGregorianCalendar();
+ LocalDate date = jewishCalendar.getLocalDate();
Daf dafYomi = null;
- int julianDay = getJulianDay(calendar);
+ int julianDay = getJulianDay(date);
int cycleNo;
int dafNo;
- if (calendar.before(dafYomiStartDay)) {
+ if (date.isBefore(dafYomiStartDay) ) {
// TODO: should we return a null or throw an IllegalArgumentException?
- throw new IllegalArgumentException(calendar + " is prior to organized Daf Yomi Bavli cycles that started on "
+ throw new IllegalArgumentException(date + " is prior to organized Daf Yomi Bavli cycles that started on "
+ dafYomiStartDay);
}
- if (calendar.equals(shekalimChangeDay) || calendar.after(shekalimChangeDay)) {
+ if (date.equals(shekalimChangeDay) || date.isAfter(shekalimChangeDay)) {
cycleNo = 8 + ((julianDay - shekalimJulianChangeDay) / 2711);
dafNo = ((julianDay - shekalimJulianChangeDay) % 2711);
} else {
@@ -136,14 +136,14 @@ public static Daf getDafYomiBavli(JewishCalendar jewishCalendar) {
/**
* Return the Julian day from a Java Calendar.
*
- * @param calendar
- * The Java Calendar of the date to be calculated
+ * @param localDate
+ * The Java {@link java.time.LocalDate} of the date to be calculated
* @return the Julian day number corresponding to the date
*/
- private static int getJulianDay(Calendar calendar) {
- int year = calendar.get(Calendar.YEAR);
- int month = calendar.get(Calendar.MONTH) + 1;
- int day = calendar.get(Calendar.DAY_OF_MONTH);
+ private static int getJulianDay(LocalDate localDate) {
+ int year = localDate.getYear();
+ int month = localDate.getMonthValue() ;
+ int day = localDate.getDayOfMonth();
if (month <= 2) {
year -= 1;
month += 12;
diff --git a/src/main/java/com/kosherjava/zmanim/util/AstronomicalCalculator.java b/src/main/java/com/kosherjava/zmanim/util/AstronomicalCalculator.java
index b4d5fdf4..055403ed 100644
--- a/src/main/java/com/kosherjava/zmanim/util/AstronomicalCalculator.java
+++ b/src/main/java/com/kosherjava/zmanim/util/AstronomicalCalculator.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2004-2025 Eliyahu Hershfeld
+ * Copyright (C) 2004-2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,7 +15,8 @@
*/
package com.kosherjava.zmanim.util;
-import java.util.Calendar;
+import java.time.LocalDate;
+import java.time.ZonedDateTime;
/**
* An abstract class that all sun time calculating classes extend. This allows the algorithm used to be changed at
@@ -23,7 +24,7 @@
* @todo Consider methods that would allow atmospheric modeling. This can currently be adjusted by {@link
* #setRefraction(double) setting the refraction}.
*
- * @author © Eliyahu Hershfeld 2004 - 2025
+ * @author © Eliyahu Hershfeld 2004 - 2026
*/
public abstract class AstronomicalCalculator implements Cloneable {
/**
@@ -104,10 +105,10 @@ public static AstronomicalCalculator getDefault() {
* A method that calculates UTC sunrise as well as any time based on an angle above or below sunrise. This abstract
* method is implemented by the classes that extend this class.
*
- * @param calendar
- * Used to calculate day of year.
+ * @param localDate
+ * The LocalDate representing the date to calculate sunrise for.
* @param geoLocation
- * The location information used for astronomical calculating sun times.
+ * The location information used for astronomical calculation of solar times.
* @param zenith
* the azimuth below the vertical zenith of 90 degrees. for sunrise typically the {@link #adjustZenith
* zenith} used for the calculation uses geometric zenith of 90° and {@link #adjustZenith adjusts}
@@ -116,22 +117,21 @@ public static AstronomicalCalculator getDefault() {
* {@link com.kosherjava.zmanim.AstronomicalCalendar#NAUTICAL_ZENITH} to this method.
* @param adjustForElevation
* Should the time be adjusted for elevation
- * @return The UTC time of sunrise in 24-hour format. 5:45:00 AM will return 5.75.0. If an error was encountered in
- * the calculation (expected behavior for some locations such as near the poles,
- * {@link java.lang.Double#NaN} will be returned.
+ * @return The UTC time of sunrise in 24-hour format. 5:45:00 AM will return 5.75. If an error was encountered in the
+ * calculation (expected behavior for some locations such as near the poles, {@link Double#NaN} will be returned.
* @see #getElevationAdjustment(double)
*/
- public abstract double getUTCSunrise(Calendar calendar, GeoLocation geoLocation, double zenith,
+ public abstract double getUTCSunrise(LocalDate localDate, GeoLocation geoLocation, double zenith,
boolean adjustForElevation);
/**
* A method that calculates UTC sunset as well as any time based on an angle above or below sunset. This abstract
* method is implemented by the classes that extend this class.
*
- * @param calendar
- * Used to calculate day of year.
+ * @param localDate
+ * The LocalDate representing the date to calculate sunset for.
* @param geoLocation
- * The location information used for astronomical calculating sun times.
+ * The location information used for astronomical calculation of solar times.
* @param zenith
* the azimuth below the vertical zenith of 90°. For sunset typically the {@link #adjustZenith
* zenith} used for the calculation uses geometric zenith of 90° and {@link #adjustZenith adjusts}
@@ -140,75 +140,101 @@ public abstract double getUTCSunrise(Calendar calendar, GeoLocation geoLocation,
* {@link com.kosherjava.zmanim.AstronomicalCalendar#NAUTICAL_ZENITH} to this method.
* @param adjustForElevation
* Should the time be adjusted for elevation
- * @return The UTC time of sunset in 24-hour format. 5:45:00 AM will return 5.75.0. If an error was encountered in
- * the calculation (expected behavior for some locations such as near the poles,
- * {@link java.lang.Double#NaN} will be returned.
+ * @return The UTC time of sunset in 24-hour format. 5:45:00 AM will return 5.75. If an error was encountered in the
+ * calculation (expected behavior for some locations such as near the poles, {@link Double#NaN} will be returned.
* @see #getElevationAdjustment(double)
*/
- public abstract double getUTCSunset(Calendar calendar, GeoLocation geoLocation, double zenith,
+ public abstract double getUTCSunset(LocalDate localDate, GeoLocation geoLocation, double zenith,
boolean adjustForElevation);
-
/**
- * Return solar noon (UTC) for the given day at the
- * given location on earth. The {@link com.kosherjava.zmanim.util.NOAACalculator} implementation calculates
- * true solar noon, while the {@link com.kosherjava.zmanim.util.SunTimesCalculator} approximates it, calculating
- * the time as halfway between sunrise and sunset.
+ * Return the Universal Coordinated Time (UTC) of
+ * solar noon (UTC) for the given day at the given location. The
+ * {@link NOAACalculator}, the default calculator implementation calculates true solar noon, something that can be calculated
+ * even in the Arctic / Antarctic where there may be no sunrise or sunset, while the {@link SunTimesCalculator} approximates it,
+ * calculating the time as halfway between sunrise and sunset, something that can't be calculated in Polar regions where there is
+ * no sunrise or sunset for part of the year. See The
+ * Definition of Chatzos for details on solar noon /
+ * midnight calculations.
*
- * @param calendar
- * Used to calculate day of year.
+ * @param localDate
+ * The LocalDate representing the date to calculate noon for.
* @param geoLocation
- * The location information used for astronomical calculating sun times.
+ * The location information used for astronomical calculation of solar times.
*
- * @return the time in minutes from zero UTC
+ * @return The UTC time of solar noon in 24-hour format. 1:45:00 PM will return 13.75. If an error was encountered in the
+ * the calculation (expected behavior for some locations such as near the poles, {@link Double#NaN} will be returned.
+ * @see #getUTCMidnight(LocalDate, GeoLocation)
*/
- public abstract double getUTCNoon(Calendar calendar, GeoLocation geoLocation);
+ public abstract double getUTCNoon(LocalDate localDate, GeoLocation geoLocation);
/**
- * Return solar midnight (UTC) for the given day at the
- * given location on earth. The the {@link com.kosherjava.zmanim.util.NOAACalculator} implementation calculates
- * true solar midnight, while the {@link com.kosherjava.zmanim.util.SunTimesCalculator} approximates it, calculating
- * the time as 12 hours after halfway between sunrise and sunset.
+ * Return the Universal Coordinated Time (UTC) of
+ * solar midnight (UTC) for the given day at the given location. The
+ * {@link NOAACalculator}, the default calculator implementation calculates true solar midnight, something that can be calculated
+ * even in the Arctic / Antarctic where there may be no sunrise or sunset, while the {@link SunTimesCalculator} approximates it,
+ * calculating the time as 12 hours after halfway between sunrise and sunset, something that can't be calculated in Polar
+ * regions where there is no sunrise or sunset for part of the year. See The Definition of Chatzos for details on solar noon /
+ * midnight calculations.
*
- * @param calendar
- * Used to calculate day of year.
+ * @param localDate
+ * The LocalDate representing the date to calculate midnight for. The calculation will be for midnight
+ * at the end of the day passed in.
* @param geoLocation
- * The location information used for astronomical calculating sun times.
+ * The location information used for astronomical calculation of solar times.
+ *
+ * @return The UTC time of solar midnight in in a 24-hour double format. 1:45:00 AM will return 1.75. If an error
+ * was encountered in the calculation (expected behavior for the {@link SunTimesCalculator} at times of the year in
+ * Polar regions), {@link Double#NaN} will be returned.
+ * @see #getUTCNoon(LocalDate, GeoLocation)
+ */
+ public abstract double getUTCMidnight(LocalDate localDate, GeoLocation geoLocation);
+
+ /**
+ * Returns the time that the azimuth will occur for the date and location passed to this method. As an example, to know
+ * when the sun will be directly west, pass in an azimuth of 270°, and for directly east, pass in an azimith of 90°.
+ *
+ * @param localDate The LocalDate representing the date to calculate the time of the azimuth for.
+ * @param geoLocation The location information used for astronomical calculation of solar times.
+ * @param azimuth the azimuth to run the calculation for
*
- * @return the time in minutes from zero UTC
+ * @return The UTC time that the azimuth will be reached in a 24-hour double format. 5:45:00 PM will return 17.75.
+ * If an error was encountered in the calculation (expected behavior for some locations such as near the poles, a
+ * {@link Double#NaN} will be returned.
*/
- public abstract double getUTCMidnight(Calendar calendar, GeoLocation geoLocation);
+ public abstract double getTimeAtAzimuth(LocalDate localDate, GeoLocation geoLocation, double azimuth);
/**
* Return the Solar Elevation for the
* horizontal coordinate system at the given location at the given time. Can be negative if the sun is below the
* horizon. Not corrected for altitude.
*
- * @param calendar
- * time of calculation
+ * @param zonedDateTime
+ * The ZonedDateTime to calculate the elevation for.
* @param geoLocation
- * The location information
+ * The location information used for astronomical calculation of solar times.
* @return solar elevation in degrees. The horizon (calculated in a vacuum using the solar radius as the point)
* is 090°, civil twilight is -690° etc. This means that sunrise and sunset that do use
* refraction and are calculated from the upper limb of the sun will return about 0.83390°.
*/
- public abstract double getSolarElevation(Calendar calendar, GeoLocation geoLocation);
+ public abstract double getSolarElevation(ZonedDateTime zonedDateTime, GeoLocation geoLocation);
/**
* Return the Solar Azimuth for the
* horizontal coordinate system at the given location at the given time. Not corrected for altitude. True south is 180
* degrees.
*
- * @param calendar
- * time of calculation
+ * @param zonedDateTime
+ * The ZonedDateTime to calculate the azimuth for.ac
* @param geoLocation
- * The location information
+ * The location information used for astronomical calculation of solar times.
* @return the solar azimuth in degrees. Astronomical midday would be 180 in the norther hemosphere and 0 in the
* southern hemosphere. Depending on the location and time of year, sunrise will have an azimuth of about
* 90° and sunset about 270°.
*/
- public abstract double getSolarAzimuth(Calendar calendar, GeoLocation geoLocation);
+ public abstract double getSolarAzimuth(ZonedDateTime zonedDateTime, GeoLocation geoLocation);
/**
* Method to return the adjustment to the zenith required to account for the elevation. Since a person at a higher
@@ -236,8 +262,7 @@ public abstract double getUTCSunset(Calendar calendar, GeoLocation geoLocation,
* @return the adjusted zenith
*/
double getElevationAdjustment(double elevation) {
- double elevationAdjustment = Math.toDegrees(Math.acos(earthRadius / (earthRadius + (elevation / 1000))));
- return elevationAdjustment;
+ return Math.toDegrees(Math.acos(earthRadius / (earthRadius + (elevation / 1000))));
}
/**
@@ -258,7 +283,7 @@ public abstract double getUTCSunset(Calendar calendar, GeoLocation geoLocation,
* below the zenith}. This is traditionally calculated with none of the above mentioned adjustments. The same goes
* for various tzais and alos times such as the
* {@link com.kosherjava.zmanim.ZmanimCalendar#ZENITH_16_POINT_1 16.1°} dip used in
- * {@link com.kosherjava.zmanim.ComplexZmanimCalendar#getAlos16Point1Degrees()}.
+ * {@link com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getAlos16Point1Degrees()}.
*
* @param zenith
* the azimuth below the vertical zenith of 90°. For sunset typically the {@link #adjustZenith
@@ -282,13 +307,13 @@ public abstract double getUTCSunset(Calendar calendar, GeoLocation geoLocation,
}
/**
- * Method to get the refraction value to be used when calculating sunrise and sunset. The default value is 34
- * arcminutes. The Errata and Notes
- * for Calendrical Calculations: The Millennium Edition by Edward M. Reingold and Nachum Dershowitz lists the
- * actual average refraction value as 34.478885263888294 or approximately 34' 29". The refraction value as well
- * as the solarRadius and elevation adjustment are added to the zenith used to calculate sunrise and sunset.
+ * Method to get the refraction value to be used when calculating sunrise and sunset. The default value is 34 arcminutes
+ * (returned in degrees). The Errata and
+ * Notes for Calendrical Calculations: The Millennium Edition by Edward M. Reingold and Nachum Dershowitz lists the
+ * actual average refraction value as 34.478885263888294 or approximately 34' 29". The refraction value as well as the
+ * solar radius and elevation adjustment are added to the zenith used to calculate sunrise and sunset.
*
- * @return The refraction in arcminutes.
+ * @return The refraction in degrees.
*/
public double getRefraction() {
return this.refraction;
@@ -300,7 +325,7 @@ public double getRefraction() {
* locations might be used for increased accuracy.
*
* @param refraction
- * The refraction in arcminutes.
+ * The refraction in degrees.
* @see #getRefraction()
*/
public void setRefraction(double refraction) {
@@ -322,7 +347,7 @@ public void setRefraction(double refraction) {
* they show the extreme difference on days that are not the perihelion or aphelion, but are shown for illustrative
* purposes only.
*
- * @return The sun's radius in arcminutes.
+ * @return The sun's radius in degrees.
*/
public double getSolarRadius() {
return this.solarRadius;
@@ -332,7 +357,7 @@ public double getSolarRadius() {
* Method to set the sun's radius.
*
* @param solarRadius
- * The sun's radius in arcminutes.
+ * The sun's radius in degrees.
* @see #getSolarRadius()
*/
public void setSolarRadius(double solarRadius) {
@@ -340,7 +365,35 @@ public void setSolarRadius(double solarRadius) {
}
/**
- * @see java.lang.Object#clone()
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object == null || getClass() != object.getClass()) {
+ return false;
+ }
+ AstronomicalCalculator calculator = (AstronomicalCalculator) object;
+ return Double.doubleToLongBits(getEarthRadius()) == Double.doubleToLongBits(calculator.getEarthRadius())
+ && Double.doubleToLongBits(getRefraction()) == Double.doubleToLongBits(calculator.getRefraction())
+ && Double.doubleToLongBits(getSolarRadius()) == Double.doubleToLongBits(calculator.getSolarRadius());
+ }
+
+ /**
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ int result = 17;
+ result = 37 * result + getClass().hashCode();
+ result = 37 * result + Double.hashCode(getEarthRadius());
+ result = 37 * result + Double.hashCode(getRefraction());
+ result = 37 * result + Double.hashCode(getSolarRadius());
+ return result;
+ }
+
+ /**
+ * @see Object#clone()
* @since 1.1
*/
public Object clone() {
diff --git a/src/main/java/com/kosherjava/zmanim/util/GeoLocation.java b/src/main/java/com/kosherjava/zmanim/util/GeoLocation.java
index b2888a33..9ddb08fd 100644
--- a/src/main/java/com/kosherjava/zmanim/util/GeoLocation.java
+++ b/src/main/java/com/kosherjava/zmanim/util/GeoLocation.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2004-2025 Eliyahu Hershfeld
+ * Copyright (C) 2004-2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,8 +15,12 @@
*/
package com.kosherjava.zmanim.util;
+import java.util.Locale;
import java.util.Objects;
-import java.util.TimeZone;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.TextStyle;
/**
* A class that contains location information such as latitude and longitude required for astronomical calculations. The
@@ -24,7 +28,7 @@
* specific implementations of the {@link AstronomicalCalculator} to see if elevation is calculated as part of the
* algorithm.
*
- * @author © Eliyahu Hershfeld 2004 - 2025
+ * @author © Eliyahu Hershfeld 2004 - 2026
*/
public class GeoLocation implements Cloneable {
/**
@@ -51,11 +55,11 @@ public class GeoLocation implements Cloneable {
private String locationName;
/**
- * The location's time zone.
- * @see #getTimeZone()
- * @see #setTimeZone(TimeZone)
+ * The location's zoneId
+ * @see #getZoneId()
+ * @see #setZoneId(ZoneId)
*/
- private TimeZone timeZone;
+ private ZoneId zoneId;
/**
* The elevation in Meters above sea level.
@@ -127,11 +131,11 @@ public void setElevation(double elevation) {
* the longitude as a double, for example -74.222 for Lakewood, NJ. Note: For longitudes
* east of the Prime Meridian (Greenwich),
* a negative value should be used.
- * @param timeZone
- * the TimeZone for the location.
+ * @param zoneId
+ * the ZoneId for the location.
*/
- public GeoLocation(String name, double latitude, double longitude, TimeZone timeZone) {
- this(name, latitude, longitude, 0, timeZone);
+ public GeoLocation(String name, double latitude, double longitude, ZoneId zoneId) {
+ this(name, latitude, longitude, 0, zoneId);
}
/**
@@ -148,27 +152,27 @@ public GeoLocation(String name, double latitude, double longitude, TimeZone time
* Meridian (Greenwich), a negative value should be used.
* @param elevation
* the elevation above sea level in Meters.
- * @param timeZone
- * the TimeZone for the location.
+ * @param zoneId
+ * the ZoneId for the location.
*/
- public GeoLocation(String name, double latitude, double longitude, double elevation, TimeZone timeZone) {
+ public GeoLocation(String name, double latitude, double longitude, double elevation, ZoneId zoneId) {
setLocationName(name);
setLatitude(latitude);
setLongitude(longitude);
setElevation(elevation);
- setTimeZone(timeZone);
+ setZoneId(zoneId);
}
/**
- * Default GeoLocation constructor will set location to the Prime Meridian at Greenwich, England and a TimeZone of
- * GMT. The longitude will be set to 0 and the latitude will be 51.4772 to match the location of the ZoneId
+ * of GMT. The longitude will be set to 0 and the latitude will be 51.4772 to match the location of the Royal Observatory, Greenwich. No daylight savings time will be used.
*/
public GeoLocation() {
setLocationName("Greenwich, England");
setLongitude(0); // added for clarity
setLatitude(51.4772);
- setTimeZone(TimeZone.getTimeZone("GMT"));
+ setZoneId(ZoneId.of("GMT"));
}
/**
@@ -204,11 +208,12 @@ public void setLatitude(double latitude) {
* IllegalArgumentException will be thrown if the value is not "S" or "N".
*/
public void setLatitude(int degrees, int minutes, double seconds, String direction) {
- double tempLat = degrees + ((minutes + (seconds / 60.0)) / 60.0);
- if (tempLat > 90 || tempLat < 0 || Double.isNaN(tempLat)) { //FIXME An exception should be thrown if degrees, minutes or seconds are negative
- throw new IllegalArgumentException(
- "Latitude must be between 0 and 90. Use direction of S instead of negative.");
+ if (degrees > 90 || degrees < 0 || Double.isNaN(degrees) || minutes > 59 || minutes < 0 || Double.isNaN(minutes) ||
+ seconds > 59 || seconds < 0 || Double.isNaN(seconds)){
+ throw new IllegalArgumentException("Latitude degrees must be between 0 and 90. Minutes and seconds must be between 0 and 59. Use a direction of \"S\" instead of negative.");
}
+
+ double tempLat = degrees + ((minutes + (seconds / 60.0)) / 60.0);
if (direction.equals("S")) {
tempLat *= -1;
} else if (!direction.equals("N")) {
@@ -260,14 +265,16 @@ public void setLongitude(double longitude) {
* An IllegalArgumentException will be thrown if the value is not E or W.
*/
public void setLongitude(int degrees, int minutes, double seconds, String direction) {
- double longTemp = degrees + ((minutes + (seconds / 60.0)) / 60.0);
- if (longTemp > 180 || this.longitude < 0 || Double.isNaN(longTemp)) { //FIXME An exception should be thrown if degrees, minutes or seconds are negative
- throw new IllegalArgumentException("Longitude must be between 0 and 180. Use a direction of W instead of negative.");
+ if (degrees > 180 || degrees < 0 || Double.isNaN(degrees) || minutes > 59 || minutes < 0 || Double.isNaN(minutes) ||
+ seconds > 59 || seconds < 0 || Double.isNaN(seconds)){
+ throw new IllegalArgumentException("Longitude degrees must be between 0 and 180. Minutes and seconds must be between 0 and 59. Use a direction of \"W\" instead of negative.");
}
+
+ double longTemp = degrees + ((minutes + (seconds / 60.0)) / 60.0);
if (direction.equals("W")) {
longTemp *= -1;
} else if (!direction.equals("E")) {
- throw new IllegalArgumentException("Longitude direction must be E or W");
+ throw new IllegalArgumentException("Longitude direction must be \"E\" or \"W\"");
}
this.longitude = longTemp;
}
@@ -296,48 +303,50 @@ public String getLocationName() {
public void setLocationName(String name) {
this.locationName = name;
}
-
+
/**
- * Method to return the time zone.
- * @return Returns the timeZone.
+ * Method to return the ZoneId.
+ * @return Returns the zoneId.
*/
- public TimeZone getTimeZone() {
- return timeZone;
+ public ZoneId getZoneId() {
+ return zoneId;
}
-
+
/**
- * Method to set the TimeZone. If this is ever set after the GeoLocation is set in the
+ * Method to set the zoneId. If this is ever set after the GeoLocation is set in the
* {@link com.kosherjava.zmanim.AstronomicalCalendar}, it is critical that
- * {@link com.kosherjava.zmanim.AstronomicalCalendar#getCalendar()}.
- * {@link java.util.Calendar#setTimeZone(TimeZone) setTimeZone(TimeZone)} be called in order for the
+ * {@link java.time.ZonedDateTime #setZoneId(ZoneId) setZoneId(ZoneId)} be called in order for the
* AstronomicalCalendar to output times in the expected offset. This situation will arise if the
* AstronomicalCalendar is ever {@link com.kosherjava.zmanim.AstronomicalCalendar#clone() cloned}.
*
- * @param timeZone
- * The timeZone to set.
+ * @param zoneId
+ * The zoneId to set.
*/
- public void setTimeZone(TimeZone timeZone) {
- this.timeZone = timeZone;
+ public void setZoneId(ZoneId zoneId) {
+ this.zoneId = zoneId;
}
/**
- * A method that will return the location's local mean time offset in milliseconds from local standard time. The globe is split into 360°, with
+ * A method that will return the location's local mean time offset in milliseconds from the local clock time defined
+ * by the time zone offset in effect for the supplied Instant. The globe is split into 360°, with
* 15° per hour of the day. For a local that is at a longitude that is evenly divisible by 15 (longitude % 15 ==
* 0), at solar {@link com.kosherjava.zmanim.AstronomicalCalendar#getSunTransit() noon} (with adjustment for the equation of time) the sun should be directly overhead,
- * so a user who is 1° west of this will have noon at 4 minutes after standard time noon, and conversely, a user
- * who is 1° east of the 15° longitude will have noon at 11:56 AM. Lakewood, N.J., whose longitude is
- * -74.222, is 0.778 away from the closest multiple of 15 at -75°. This is multiplied by 4 to yield 3 minutes
- * and 10 seconds earlier than standard time. The offset returned does not account for the Daylight saving time offset since this class is
- * unaware of dates.
- *
- * @return the offset in milliseconds not accounting for Daylight saving time. A positive value will be returned
- * East of the 15° timezone line, and a negative value West of it.
- */
- public long getLocalMeanTimeOffset() {
- return (long) (getLongitude() * 4 * MINUTE_MILLIS - getTimeZone().getRawOffset());
+ * so a user who is 1° west of this will have noon at 4 minutes after local clock noon, and conversely, a user
+ * who is 1° east of the 15° longitude will have noon at 11:56 AM local clock time. Lakewood, N.J., whose
+ * longitude is -74.222, is 0.778 away from the closest multiple of 15 at -75°. This is multiplied by 4 to
+ * yield 3 minutes and 10 seconds earlier than the local clock time derived from the zone offset in effect for the
+ * supplied instant, including any applicable Daylight saving time adjustment.
+ * @param instant
+ * the Instant used to claculate the local mean offset for the date in question.
+ * @return the offset in milliseconds relative to the time zone offset in effect at the supplied instant. A
+ * positive value will be returned East of the 15° timezone line, and a negative value West of it.
+ */
+ public long getLocalMeanTimeOffset(Instant instant) {
+ ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, zoneId);
+ long timezoneOffsetMillis = zonedDateTime.getOffset().getTotalSeconds() * 1000L;
+ return (long) (getLongitude() * 4 * MINUTE_MILLIS - timezoneOffsetMillis);
}
/**
@@ -354,11 +363,13 @@ public long getLocalMeanTimeOffset() {
* 2018-02-03, the calculator should operate using 2018-02-02 since the expected zone is -11. After determining the
* UTC time, the local DST offset of UTC+14:00 should be applied
* to bring the date back to 2018-02-03.
+ * @param instant
+ * the Instant required for the local mean time offset calculation
*
* @return the number of days to adjust the date This will typically be 0 unless the date crosses the antimeridian
*/
- public int getAntimeridianAdjustment() {
- double localHoursOffset = getLocalMeanTimeOffset() / (double)HOUR_MILLIS;
+ public int getAntimeridianAdjustment(Instant instant) {
+ double localHoursOffset = getLocalMeanTimeOffset(instant) / (double)HOUR_MILLIS;
if (localHoursOffset >= 20){// if the offset is 20 hours or more in the future (never expected anywhere other
// than a location using a timezone across the antimeridian to the east such as Samoa)
@@ -448,7 +459,7 @@ private double vincentyInverseFormula(GeoLocation location, int formula) {
double sinSigma = 0;
double cosSigma = 0;
double sigma = 0;
- double sinAlpha = 0;
+ double sinAlpha;
double cosSqAlpha = 0;
double cos2SigmaM = 0;
double C;
@@ -557,8 +568,6 @@ public double getRhumbLineDistance(GeoLocation location) {
* <Elevation>0 Meters</Elevation>
* <TimezoneName>America/New_York</TimezoneName>
* <TimeZoneDisplayName>Eastern Standard Time</TimeZoneDisplayName>
- * <TimezoneGMTOffset>-5</TimezoneGMTOffset>
- * <TimezoneDSTOffset>1</TimezoneDSTOffset>
* </GeoLocation>
*
*
@@ -570,12 +579,8 @@ public String toXML() {
"\t" + getLatitude() + " \n" +
"\t" + getLongitude() + " \n" +
"\t" + getElevation() + " Meters" + " \n" +
- "\t" + getTimeZone().getID() + " \n" +
- "\t" + getTimeZone().getDisplayName() + " \n" +
- "\t" + getTimeZone().getRawOffset() / HOUR_MILLIS +
- " \n" +
- "\t" + getTimeZone().getDSTSavings() / HOUR_MILLIS +
- " \n" +
+ "\t" + getZoneId().getId() + " \n" +
+ "\t" + getZoneId().getDisplayName(TextStyle.FULL, Locale.ENGLISH) + " \n" +
"";
}
@@ -592,7 +597,7 @@ public boolean equals(Object object) {
&& Double.doubleToLongBits(this.longitude) == Double.doubleToLongBits(geo.longitude)
&& this.elevation == geo.elevation
&& (Objects.equals(this.locationName, geo.locationName))
- && (Objects.equals(this.timeZone, geo.timeZone));
+ && (Objects.equals(this.zoneId, geo.zoneId));
}
/**
@@ -604,15 +609,15 @@ public int hashCode() {
long latLong = Double.doubleToLongBits(this.latitude);
long lonLong = Double.doubleToLongBits(this.longitude);
long elevLong = Double.doubleToLongBits(this.elevation);
- int latInt = (int) (latLong ^ (latLong >>> 32));
- int lonInt = (int) (lonLong ^ (lonLong >>> 32));
- int elevInt = (int) (elevLong ^ (elevLong >>> 32));
+ int latInt = Long.hashCode(latLong);
+ int lonInt = Long.hashCode(lonLong);
+ int elevInt = Long.hashCode(elevLong);
result = 37 * result + getClass().hashCode();
result += 37 * result + latInt;
result += 37 * result + lonInt;
result += 37 * result + elevInt;
result += 37 * result + (this.locationName == null ? 0 : this.locationName.hashCode());
- result += 37 * result + (this.timeZone == null ? 0 : this.timeZone.hashCode());
+ result += 37 * result + (this.zoneId == null ? 0 : this.zoneId.hashCode());
return result;
}
@@ -624,20 +629,13 @@ public String toString() {
"\nLatitude:\t\t\t" + getLatitude() + "\u00B0" +
"\nLongitude:\t\t\t" + getLongitude() + "\u00B0" +
"\nElevation:\t\t\t" + getElevation() + " Meters" +
- "\nTimezone ID:\t\t\t" + getTimeZone().getID() +
- "\nTimezone Display Name:\t\t" + getTimeZone().getDisplayName() +
- " (" + getTimeZone().getDisplayName(false, TimeZone.SHORT) + ")" +
- "\nTimezone GMT Offset:\t\t" + getTimeZone().getRawOffset() / HOUR_MILLIS +
- "\nTimezone DST Offset:\t\t" + getTimeZone().getDSTSavings() / HOUR_MILLIS;
+ "\nTimezone ID:\t\t\t" + getZoneId().getId() +
+ "\nTimezone Display Name:\t\t" + getZoneId().getDisplayName(TextStyle.FULL, Locale.ENGLISH);
}
/**
* An implementation of the {@link java.lang.Object#clone()} method that creates a deep copy of the object.
- * Note: If the {@link java.util.TimeZone} in the clone will be changed from the original, it is critical
- * that {@link com.kosherjava.zmanim.AstronomicalCalendar#getCalendar()}.
- * {@link java.util.Calendar#setTimeZone(TimeZone) setTimeZone(TimeZone)} is called after cloning in order for the
- * AstronomicalCalendar to output times in the expected offset.
*
* @see java.lang.Object#clone()
*/
@@ -649,7 +647,7 @@ public Object clone() {
//Required by the compiler. Should never be reached since we implement clone()
}
if (clone != null) {
- clone.timeZone = (TimeZone) getTimeZone().clone();
+ clone.zoneId = getZoneId();
clone.locationName = getLocationName();
}
return clone;
diff --git a/src/main/java/com/kosherjava/zmanim/util/NOAACalculator.java b/src/main/java/com/kosherjava/zmanim/util/NOAACalculator.java
index ec9a0453..15f5e475 100644
--- a/src/main/java/com/kosherjava/zmanim/util/NOAACalculator.java
+++ b/src/main/java/com/kosherjava/zmanim/util/NOAACalculator.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2004-2025 Eliyahu Hershfeld
+ * Copyright (C) 2004-2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,7 +15,9 @@
*/
package com.kosherjava.zmanim.util;
-import java.util.Calendar;
+import java.time.ZoneOffset;
+import java.time.LocalDate;
+import java.time.ZonedDateTime;
/**
* Implementation of sunrise and sunset methods to calculate astronomical times based on the Wikipedia Sunrise Equation article.
*
- * @author © Eliyahu Hershfeld 2011 - 2025
+ * @author © Eliyahu Hershfeld 2011 - 2026
*/
public class NOAACalculator extends AstronomicalCalculator {
@@ -60,56 +62,74 @@ public NOAACalculator() {
super();
}
- /**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getCalculatorName()
- */
+ @Override
public String getCalculatorName() {
return "US National Oceanic and Atmospheric Administration Algorithm"; // Implementation of the Jean Meeus algorithm
}
- /**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCSunrise(Calendar, GeoLocation, double, boolean)
- */
- public double getUTCSunrise(Calendar calendar, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
- double elevation = adjustForElevation ? geoLocation.getElevation() : 0;
- double adjustedZenith = adjustZenith(zenith, elevation);
- double sunrise = getSunRiseSetUTC(calendar, geoLocation.getLatitude(), -geoLocation.getLongitude(),
- adjustedZenith, SolarEvent.SUNRISE);
- sunrise = sunrise / 60;
- return sunrise > 0 ? sunrise % 24 : sunrise % 24 + 24; // ensure that the time is >= 0 and < 24
+ @Override
+ public double getUTCSunrise(LocalDate dt, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
+ return getUTCSunRiseSet(dt, geoLocation, zenith, adjustForElevation,SolarEvent.SUNRISE);
}
+ @Override
+ public double getUTCSunset(LocalDate dt, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
+ return getUTCSunRiseSet(dt, geoLocation, zenith, adjustForElevation,SolarEvent.SUNSET);
+ }
+
/**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCSunset(Calendar, GeoLocation, double, boolean)
+ * A method that calculates UTC sunrise or sunset as well as any time based on an angle above or below sunset and
+ * returns it as a double in 24-hour format. 5:45:00 AM will return 5.75.
+ *
+ * @param localDate
+ * Used to calculate day of year.
+ * @param geoLocation
+ * The location information used for astronomical calculation of solar times.
+ * @param zenith
+ * the azimuth below the vertical zenith of 90°. For sunset typically the {@link #adjustZenith zenith} used for
+ * the calculation uses geometric zenith of 90° and {@link #adjustZenith adjusts} this slightly to account for
+ * solar refraction and the sun's radius. Another example would be {@link
+ * com.kosherjava.zmanim.AstronomicalCalendar#getEndNauticalTwilight()} that passes {@link
+ * com.kosherjava.zmanim.AstronomicalCalendar#NAUTICAL_ZENITH} to this method.
+ * @param adjustForElevation
+ * Should the time be adjusted for elevation
+ * @param solarEvent if the calculation is for {@link SolarEvent#SUNRISE} or {@link SolarEvent#SUNSET}
+ * @return The UTC time of sunset in 24-hour format. 5:45:00 AM will return 5.75. If an error was encountered in the
+ * calculation (expected behavior for some locations such as near the poles, {@link Double#NaN} will be returned.
+ * @see #getElevationAdjustment(double)
*/
- public double getUTCSunset(Calendar calendar, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
+ private double getUTCSunRiseSet(LocalDate localDate, GeoLocation geoLocation, double zenith, boolean adjustForElevation,
+ SolarEvent solarEvent) {
double elevation = adjustForElevation ? geoLocation.getElevation() : 0;
double adjustedZenith = adjustZenith(zenith, elevation);
- double sunset = getSunRiseSetUTC(calendar, geoLocation.getLatitude(), -geoLocation.getLongitude(),
- adjustedZenith, SolarEvent.SUNSET);
- sunset = sunset / 60;
- return sunset > 0 ? sunset % 24 : sunset % 24 + 24; // ensure that the time is >= 0 and < 24
+ double riseSet = getSunRiseSetUTC(localDate, geoLocation.getLatitude(), -geoLocation.getLongitude(),
+ adjustedZenith, solarEvent);
+ riseSet = riseSet / 60;
+ return riseSet > 0 ? riseSet % 24 : riseSet % 24 + 24; // ensure that the time is >= 0 and < 24
}
/**
* Return the Julian day from a Java Calendar.
*
- * @param calendar
- * The Java Calendar
+ * @param localDate
+ * The LocalDate
* @return the Julian day corresponding to the date Note: Number is returned for the start of the Julian
* day. Fractional days / time should be added later.
*/
- private static double getJulianDay(Calendar calendar) {
- int year = calendar.get(Calendar.YEAR);
- int month = calendar.get(Calendar.MONTH) + 1;
- int day = calendar.get(Calendar.DAY_OF_MONTH);
- if (month <= 2) {
- year -= 1;
- month += 12;
- }
- int a = year / 100;
- int b = 2 - a + a / 4;
- return Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + b - 1524.5;
+ private static double getJulianDay(LocalDate localDate) {
+ int year = localDate.getYear();
+ int month = localDate.getMonthValue();
+ int day = localDate.getDayOfMonth();
+
+ if (month <= 2) {
+ year -= 1;
+ month += 12;
+ }
+
+ int a = year / 100;
+ int b = 2 - a + a / 4;
+
+ return Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + b - 1524.5;
}
/**
@@ -204,8 +224,7 @@ private static double getSunTrueLongitude(double julianCenturies) {
private static double getSunApparentLongitude(double julianCenturies) {
double sunTrueLongitude = getSunTrueLongitude(julianCenturies);
double omega = 125.04 - 1934.136 * julianCenturies;
- double lambda = sunTrueLongitude - 0.00569 - 0.00478 * Math.sin(Math.toRadians(omega));
- return lambda;
+ return sunTrueLongitude - 0.00569 - 0.00478 * Math.sin(Math.toRadians(omega));
}
/**
@@ -223,8 +242,7 @@ private static double getMeanObliquityOfEcliptic(double julianCenturies) {
}
/**
- * Returns the corrected obliquity of the ecliptic (Axial
- * tilt).
+ * Returns the corrected obliquity of the ecliptic (Axial tilt).
*
* @param julianCenturies
* the number of Julian centuries since 1 ? 1 : cosZenith < -1 ? -1 : cosZenith));
- double azDenom = Math.cos(Math.toRadians(latitude)) * Math.sin(Math.toRadians(zenith));
- double refractionAdjustment = 0;
- double elevation = 90.0 - (zenith - refractionAdjustment);
- double azimuth = 0;
- double azRad = (Math.sin(Math.toRadians(latitude)) * Math.cos(Math.toRadians(zenith))
- - Math.sin(Math.toRadians(theta))) / azDenom;
- if(Math.abs(azDenom) > 0.001) {
- azimuth = 180 - Math.toDegrees(Math.acos(azRad > 1 ? 1 : azRad < -1? -1 : azRad)) * (hourAngelRad > 0 ? -1 : 1) ;
- } else {
- azimuth = latitude > 0 ? 180 : 0;
- }
- return isAzimuth ? azimuth % 360 : elevation;
+ private double getSolarElevationAzimuth(ZonedDateTime zonedDateTime, GeoLocation geoLocation, boolean isAzimuth) {
+ double lat = Math.toRadians(geoLocation.getLatitude());
+ double lon = geoLocation.getLongitude();
+ ZonedDateTime utc = zonedDateTime.withZoneSameInstant(ZoneOffset.UTC);
+ double fractionalDay = (utc.getHour() + (utc.getMinute()
+ + (utc.getSecond() + utc.getNano() / 1_000_000_000.0) / 60.0) / 60.0) / 24.0;
+ double jd = getJulianDay(utc.toLocalDate()) + fractionalDay;
+ double jc = getJulianCenturiesFromJulianDay(jd);
+ double decl = Math.toRadians(getSunDeclination(jc));
+ double eot = getEquationOfTime(jc);
+ double trueSolarTime = ((fractionalDay + eot / 1440.0 + lon / 360.0) + 2) % 1;
+ double hourAngle = trueSolarTime * 2 * Math.PI - Math.PI;
+ double cosZenith = Math.sin(lat) * Math.sin(decl) + Math.cos(lat) * Math.cos(decl) * Math.cos(hourAngle);
+ double zenith = Math.acos(Math.max(-1, Math.min(1, cosZenith)));
+ double zenithDeg = Math.toDegrees(zenith);
+ double elevation = 90.0 - zenithDeg;
+ elevation = 90.0 - (zenithDeg - adjustElevationForRefraction(elevation));
+ double azimuth;
+ double azDenom = Math.cos(lat) * Math.sin(zenith);
+
+ if (Math.abs(azDenom) > 0.001) {
+ double az = (Math.sin(lat) * Math.cos(zenith) - Math.sin(decl)) / azDenom;
+ azimuth = 180 - Math.toDegrees(Math.acos(Math.max(-1, Math.min(1, az)))) * (hourAngle > 0 ? -1 : 1);
+ } else {
+ azimuth = geoLocation.getLatitude() > 0 ? 180 : 0;
+ }
+ return isAzimuth ? (azimuth + 360) % 360 : elevation;
}
/**
- * Returns the hour of day adjusted for the timezone and DST. This is needed for the azimuth and elevation
- * calculations.
- * @param calendar the Calendar to extract the hour from. This must have the timezone set to the proper timezone.
- * @return the adjusted hour corrected for timezone and DST offset.
+ * Apply refraction adjustment to solar elevation.
+ * @param elevation the elevation to adjust.
+ * @return the adjusted elevation.
*/
- private int adjustHourForTimeZone(Calendar calendar) {
- int offset = calendar.getTimeZone().getRawOffset();
- int dstOffset = calendar.getTimeZone().getDSTSavings();
- if(calendar.getTimeZone().inDaylightTime(calendar.getTime())) {
- offset = offset + dstOffset;
- }
- return offset;
- }
+ private double adjustElevationForRefraction(double elevation) {
+ if (elevation > 85.0) {
+ return 0.0;
+ }
+ double te = Math.tan(Math.toRadians(elevation));
+ double correction;
+
+ if (elevation > 5.0) {
+ correction = 58.1 / te - 0.07 / Math.pow(te, 3) + 0.000086 / Math.pow(te, 5);
+ } else if (elevation > -0.575) {
+ correction = 1735.0 + elevation * (-518.2 + elevation * (103.4 + elevation * (-12.79 + 0.711 * elevation)));
+ } else {
+ correction = -20.774 / te;
+ }
+ return correction / 3600.0;
+ }
+
/**
- * Return the Universal Coordinated Time (UTC)
- * of solar noon for the given day at the given location
- * on earth. This implementation returns true solar noon as opposed to the time halfway between sunrise and sunset.
- * Other calculators may return a more simplified calculation of halfway between sunrise and sunset. See The Definition of Chatzos for details on
- * solar noon calculations.
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation)
+ * {@inheritDoc}
* @see #getSolarNoonMidnightUTC(double, double, SolarEvent)
- *
- * @param calendar
- * The Calendar representing the date to calculate solar noon for
- * @param geoLocation
- * The location information used for astronomical calculating sun times. This class uses only requires
- * the longitude for calculating noon since it is the same time anywhere along the longitude line.
- * @return the time in minutes from zero UTC
*/
- public double getUTCNoon(Calendar calendar, GeoLocation geoLocation) {
- double noon = getSolarNoonMidnightUTC(getJulianDay(calendar), -geoLocation.getLongitude(), SolarEvent.NOON);
+ @Override
+ public double getUTCNoon(LocalDate localDate, GeoLocation geoLocation) {
+ double noon = getSolarNoonMidnightUTC(getJulianDay(localDate), -geoLocation.getLongitude(), SolarEvent.NOON);
noon = noon / 60;
return noon > 0 ? noon % 24 : noon % 24 + 24; // ensure that the time is >= 0 and < 24
}
/**
- * Return the Universal Coordinated Time
- * (UTC) of the solar midnight for the end of the given civil
- * day at the given location on earth (about 12 hours after solar noon). This implementation returns true solar
- * midnight as opposed to the time halfway between sunrise and sunset. Other calculators may return a more
- * simplified calculation of halfway between sunrise and sunset. See The Definition of Chatzos for details on
- * solar noon / midnight calculations.
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation)
+ * {@inheritDoc}
* @see #getSolarNoonMidnightUTC(double, double, SolarEvent)
- *
- * @param calendar
- * The Calendar representing the date to calculate solar noon for
- * @param geoLocation
- * The location information used for astronomical calculating sun times. This class uses only requires
- * the longitude for calculating noon since it is the same time anywhere along the longitude line.
- * @return the time in minutes from zero UTC
*/
- public double getUTCMidnight(Calendar calendar, GeoLocation geoLocation) {
- double midnight = getSolarNoonMidnightUTC(getJulianDay(calendar), -geoLocation.getLongitude(), SolarEvent.MIDNIGHT);
+ @Override
+ public double getUTCMidnight(LocalDate localDate, GeoLocation geoLocation) {
+ double midnight = getSolarNoonMidnightUTC(getJulianDay(localDate), -geoLocation.getLongitude(), SolarEvent.MIDNIGHT);
midnight = midnight / 60;
return midnight > 0 ? midnight % 24 : midnight % 24 + 24; // ensure that the time is >= 0 and < 24
}
@@ -444,8 +430,7 @@ public double getUTCMidnight(Calendar calendar, GeoLocation geoLocation) {
* midnight (about 12 hours after solar noon) of the given day at the given location on earth.
*
* @param julianDay
- * The Julian day since J2000.0.
+ * The Julian day since J2000.0.
* @param longitude
* The longitude of observer in degrees
* @param solarEvent
@@ -453,8 +438,8 @@ public double getUTCMidnight(Calendar calendar, GeoLocation geoLocation) {
*
* @return the time in minutes from zero UTC
*
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation)
- * @see #getUTCNoon(Calendar, GeoLocation)
+ * @see #getUTCNoon(LocalDate, GeoLocation)
+ * @see #getUTCMidnight(LocalDate, GeoLocation)
*/
private static double getSolarNoonMidnightUTC(double julianDay, double longitude, SolarEvent solarEvent) {
julianDay = (solarEvent == SolarEvent.NOON) ? julianDay : julianDay + 0.5;
@@ -462,11 +447,15 @@ private static double getSolarNoonMidnightUTC(double julianDay, double longitude
double tnoon = getJulianCenturiesFromJulianDay(julianDay + longitude / 360.0);
double equationOfTime = getEquationOfTime(tnoon);
double solNoonUTC = (longitude * 4) - equationOfTime; // minutes
-
- // second pass
- double newt = getJulianCenturiesFromJulianDay(julianDay + solNoonUTC / 1440.0);
- equationOfTime = getEquationOfTime(newt);
- return (solarEvent == SolarEvent.NOON ? 720 : 1440) + (longitude * 4) - equationOfTime;
+
+ // Refine the equation of time at the calculated transit time.
+ double newt;
+ for (int i = 0; i < 2; i++) {
+ newt = getJulianCenturiesFromJulianDay(julianDay + solNoonUTC / 1440.0);
+ equationOfTime = getEquationOfTime(newt);
+ solNoonUTC = (solarEvent == SolarEvent.NOON ? 720 : 1440) + (longitude * 4) - equationOfTime;
+ }
+ return (solarEvent == SolarEvent.NOON ? 720 : 1440) + (longitude * 4 ) - equationOfTime;
}
/**
@@ -474,8 +463,8 @@ private static double getSolarNoonMidnightUTC(double julianDay, double longitude
* of sunrise or sunset in minutes for the given day at the given location on earth.
* @todo Possibly increase the number of passes for improved accuracy, especially in the Arctic areas.
*
- * @param calendar
- * The calendar
+ * @param localDate
+ * The LocalDate.
* @param latitude
* The latitude of observer in degrees
* @param longitude
@@ -486,9 +475,9 @@ private static double getSolarNoonMidnightUTC(double julianDay, double longitude
* If the calculation is for {@link SolarEvent#SUNRISE SUNRISE} or {@link SolarEvent#SUNSET SUNSET}
* @return the time in minutes from zero Universal Coordinated Time (UTC)
*/
- private static double getSunRiseSetUTC(Calendar calendar, double latitude, double longitude, double zenith,
+ private static double getSunRiseSetUTC(LocalDate localDate, double latitude, double longitude, double zenith,
SolarEvent solarEvent) {
- double julianDay = getJulianDay(calendar);
+ double julianDay = getJulianDay(localDate);
// Find the time of solar noon at the location, and use that declination.
// This is better than start of the Julian day
@@ -496,10 +485,8 @@ private static double getSunRiseSetUTC(Calendar calendar, double latitude, doubl
// efficient but would likely cause a very minor discrepancy in the calculated times (likely not reducing
// accuracy, just slightly different, thus potentially breaking test cases). Regardless, it would be within
// milliseconds.
- double noonmin = getSolarNoonMidnightUTC(julianDay, longitude, SolarEvent.NOON);
-
+ double noonmin = getSolarNoonMidnightUTC(julianDay, longitude, SolarEvent.NOON);
double tnoon = getJulianCenturiesFromJulianDay(julianDay + noonmin / 1440.0);
-
// First calculates sunrise and approximate length of day
double equationOfTime = getEquationOfTime(tnoon);
double solarDeclination = getSunDeclination(tnoon);
@@ -507,11 +494,9 @@ private static double getSunRiseSetUTC(Calendar calendar, double latitude, doubl
double delta = longitude - Math.toDegrees(hourAngle);
double timeDiff = 4 * delta;
double timeUTC = 720 + timeDiff - equationOfTime;
-
// Second pass includes fractional Julian Day in gamma calc
double newt = getJulianCenturiesFromJulianDay(julianDay + timeUTC / 1440.0);
equationOfTime = getEquationOfTime(newt);
-
solarDeclination = getSunDeclination(newt);
hourAngle = getSunHourAngle(latitude, solarDeclination, zenith, solarEvent);
delta = longitude - Math.toDegrees(hourAngle);
@@ -519,4 +504,65 @@ private static double getSunRiseSetUTC(Calendar calendar, double latitude, doubl
timeUTC = 720 + timeDiff - equationOfTime;
return timeUTC;
}
+
+ /**
+ * {@inheritDoc}
+ * @todo This is very much a work in progress. It works in some but not all cases.
+ * There will be edge cases where the azimuth will occur more than once a day when based on the equation of time,
+ * the day is shorter than 24 hours. In that case, the time for the first one will be returned.
+ *
FIXME:
+ * - Deal with the rerunning the method for a different date when near the boundaries and it rolls over the date.
+ * - Deal with when the event does not occur (it happened right before and after the date)
+ * - Deal with when the event does not occur because the sun never reaches that azimuth (too close to the equator)
+ * - May or may not be an issue - when it reaches 270 but not in every iteration (also an edge case).
+ * - Deal with issues when the solar declination matches the latitude (also an edge case).
+ * - etc
+ */
+ public double getTimeAtAzimuth(LocalDate date, GeoLocation geo, double targetAzimuth) {
+ targetAzimuth %= 360.0;
+ if (targetAzimuth < 0) targetAzimuth += 360.0;
+ final double step = 15.0 / 60.0;
+ double bestHour = Double.NaN;
+ double bestError = Double.POSITIVE_INFINITY;
+ for (double hour = 0.0; hour <= 24.0; hour += step) {
+ ZonedDateTime t = date.atStartOfDay(ZoneOffset.UTC).plusSeconds((long)(hour * 3600.0));
+ double az = getSolarAzimuth(t, geo);
+ if (Double.isNaN(az)) continue;
+ double diff = Math.abs((az - targetAzimuth) % 360.0);
+ diff = Math.min(diff, 360.0 - diff);
+ if (diff < bestError) {
+ bestError = diff;
+ bestHour = hour;
+ }
+ }
+
+ if (Double.isNaN(bestHour) || bestError > 5.0) {
+ return Double.NaN;
+ }
+
+ double low = Math.max(0.0, bestHour - step);
+ double high = Math.min(24.0, bestHour + step);
+
+ for (int i = 0; i < 30; i++) {
+ double m1 = low + (high - low) / 3.0;
+ double m2 = high - (high - low) / 3.0;
+ ZonedDateTime t1 = date.atStartOfDay(ZoneOffset.UTC).plusSeconds((long)(m1 * 3600.0));
+ ZonedDateTime t2 = date.atStartOfDay(ZoneOffset.UTC).plusSeconds((long)(m2 * 3600.0));
+ double a1 = getSolarAzimuth(t1, geo);
+ double a2 = getSolarAzimuth(t2, geo);
+ double e1 = Math.abs((a1 - targetAzimuth) % 360.0);
+ double e2 = Math.abs((a2 - targetAzimuth) % 360.0);
+ e1 = Math.min(e1, 360.0 - e1);
+ e2 = Math.min(e2, 360.0 - e2);
+ if (e1 < e2) high = m2;
+ else low = m1;
+ }
+
+ double result = (low + high) / 2.0;
+ ZonedDateTime t = date.atStartOfDay(ZoneOffset.UTC).plusSeconds((long)(result * 3600.0));
+ double az = getSolarAzimuth(t, geo);
+ double diff = Math.abs((az - targetAzimuth) % 360.0);
+ diff = Math.min(diff, 360.0 - diff);
+ return diff < 0.01 ? result : Double.NaN;
+ }
}
diff --git a/src/main/java/com/kosherjava/zmanim/util/SunTimesCalculator.java b/src/main/java/com/kosherjava/zmanim/util/SunTimesCalculator.java
index 9e3fee26..a19e5366 100644
--- a/src/main/java/com/kosherjava/zmanim/util/SunTimesCalculator.java
+++ b/src/main/java/com/kosherjava/zmanim/util/SunTimesCalculator.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2004-2025 Eliyahu Hershfeld
+ * Copyright (C) 2004-2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,7 +15,8 @@
*/
package com.kosherjava.zmanim.util;
-import java.util.Calendar;
+import java.time.LocalDate;
+import java.time.ZonedDateTime;
/**
* Implementation of sunrise and sunset methods to calculate astronomical times. This calculator uses the Java algorithm
@@ -24,9 +25,9 @@
* href="https://aa.usno.navy.mil/publications/asa">Astronomical Almanac and used with his permission. Added to Kevin's
* code is adjustment of the zenith to account for elevation. This algorithm returns the same time every year and does not
* account for leap years. It is not as accurate as the Jean Meeus based {@link NOAACalculator} that is the default calculator
- * use by the KosherJava zmanim library.
+ * use by the KosherJava zmanim library. It also does not have an implementation of some solar calculation methods.
*
- * @author © Eliyahu Hershfeld 2004 - 2025
+ * @author © Eliyahu Hershfeld 2004 - 2026
* @author © Kevin Boone 2000
*/
public class SunTimesCalculator extends AstronomicalCalculator {
@@ -38,29 +39,23 @@ public SunTimesCalculator() {
super();
}
- /**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getCalculatorName()
- */
+ @Override
public String getCalculatorName() {
return "US Naval Almanac Algorithm";
}
- /**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCSunrise(Calendar, GeoLocation, double, boolean)
- */
- public double getUTCSunrise(Calendar calendar, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
+ @Override
+ public double getUTCSunrise(LocalDate localDate, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
double elevation = adjustForElevation ? geoLocation.getElevation() : 0;
double adjustedZenith = adjustZenith(zenith, elevation);
- return getTimeUTC(calendar, geoLocation, adjustedZenith, true);
+ return getTimeUTC(localDate, geoLocation, adjustedZenith, true);
}
- /**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCSunset(Calendar, GeoLocation, double, boolean)
- */
- public double getUTCSunset(Calendar calendar, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
+ @Override
+ public double getUTCSunset(LocalDate localDate, GeoLocation geoLocation, double zenith, boolean adjustForElevation) {
double elevation = adjustForElevation ? geoLocation.getElevation() : 0;
double adjustedZenith = adjustZenith(zenith, elevation);
- return getTimeUTC(calendar, geoLocation, adjustedZenith, false);
+ return getTimeUTC(localDate, geoLocation, adjustedZenith, false);
}
/**
@@ -118,7 +113,8 @@ private static double cosDeg(double deg) {
* Get time difference between location's longitude and the Meridian, in hours.
*
* @param longitude the longitude
- * @return time difference between the location's longitude and the Meridian, in hours. West of Meridian has a negative time difference
+ * @return time difference between the location's longitude and the Meridian, in hours. West of Meridian has a negative
+ * time difference
*/
private static double getHoursFromMeridian(double longitude) {
return longitude / DEG_PER_HOUR;
@@ -133,7 +129,7 @@ private static double getHoursFromMeridian(double longitude) {
* @param isSunrise true for sunrise and false for sunset
*
* @return the approximate time of sunset or sunrise in days since midnight Jan 1st, assuming 6am and 6pm events. We
- * need this figure to derive the Sun's mean anomaly.
+ * need this figure to derive the Sun's mean anomaly.
*/
private static double getApproxTimeDays(int dayOfYear, double hoursFromMeridian, boolean isSunrise) {
if (isSunrise) {
@@ -219,23 +215,21 @@ private static double getLocalMeanTime(double localHour, double sunRightAscensio
}
/**
- * Get sunrise or sunset time in UTC, according to flag. This time is returned as
- * a double and is not adjusted for time-zone.
+ * Get sunrise or sunset time in UTC, according to flag. This time is returned as a double and is not adjusted for time-zone.
*
- * @param calendar
- * the Calendar object to extract the day of year for calculation
+ * @param localDate
+ * the LocalDate object to extract the day of year for calculation
* @param geoLocation
- * the GeoLocation object that contains the latitude and longitude
+ * The location information used for astronomical calculation of solar times.
* @param zenith
- * Sun's zenith, in degrees
+ * Sun's zenith in degrees
* @param isSunrise
* True for sunrise and false for sunset.
- * @return the time as a double. If an error was encountered in the calculation
- * (expected behavior for some locations such as near the poles,
- * {@link Double#NaN} will be returned.
+ * @return the time as a double. If an error was encountered in the calculation (expected behavior for some locations such as
+ * near the poles, {@link Double#NaN} will be returned.
*/
- private static double getTimeUTC(Calendar calendar, GeoLocation geoLocation, double zenith, boolean isSunrise) {
- int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
+ private static double getTimeUTC(LocalDate localDate, GeoLocation geoLocation, double zenith, boolean isSunrise) {
+ int dayOfYear = localDate.getDayOfYear();
double sunMeanAnomaly = getMeanAnomaly(dayOfYear, geoLocation.getLongitude(), isSunrise);
double sunTrueLong = getSunTrueLongitude(sunMeanAnomaly);
double sunRightAscensionHours = getSunRightAscensionHours(sunTrueLong);
@@ -255,26 +249,10 @@ private static double getTimeUTC(Calendar calendar, GeoLocation geoLocation, dou
return pocessedTime > 0 ? pocessedTime % 24 : pocessedTime % 24 + 24; // ensure that the time is >= 0 and < 24
}
- /**
- * Return the Universal Coordinated Time (UTC)
- * of solar noon for the given day at the given location
- * on earth. This implementation returns solar noon as the time halfway between sunrise and sunset.
- * {@link NOAACalculator}, the default calculator, returns true solar noon. See The Definition of Chatzos for details on solar
- * noon calculations.
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation)
- * @see NOAACalculator
- *
- * @param calendar
- * The Calendar representing the date to calculate solar noon for
- * @param geoLocation
- * The location information used for astronomical calculating sun times.
- * @return the time in minutes from zero UTC. If an error was encountered in the calculation (expected behavior for
- * some locations such as near the poles, {@link Double#NaN} will be returned.
- */
- public double getUTCNoon(Calendar calendar, GeoLocation geoLocation) {
- double sunrise = getUTCSunrise(calendar, geoLocation, 90, false);
- double sunset = getUTCSunset(calendar, geoLocation, 90, false);
+ @Override
+ public double getUTCNoon(LocalDate localDate, GeoLocation geoLocation) {
+ double sunrise = getUTCSunrise(localDate, geoLocation, 90, false);
+ double sunset = getUTCSunset(localDate, geoLocation, 90, false);
double noon = sunrise + ((sunset - sunrise) / 2);
if (noon < 0) {
noon += 12;
@@ -285,38 +263,47 @@ public double getUTCNoon(Calendar calendar, GeoLocation geoLocation) {
return noon;
}
+ @Override
+ public double getUTCMidnight(LocalDate localDate, GeoLocation geoLocation) {
+ return (getUTCNoon(localDate, geoLocation) + 12);
+ }
+
/**
- * Return the Universal Coordinated Time (UTC)
- * of midnight for the given day at the given location on earth. This implementation returns solar midnight as 12 hours
- * after utc noon that is halfway between sunrise and sunset.
- * {@link NOAACalculator}, the default calculator, returns true solar noon. See The Definition of Chatzos for details on solar
- * noon calculations.
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation)
- * @see NOAACalculator
- *
- * @param calendar
- * The Calendar representing the date to calculate solar noon for
- * @param geoLocation
- * The location information used for astronomical calculating sun times.
- * @return the time in minutes from zero UTC. If an error was encountered in the calculation (expected behavior for
- * some locations such as near the poles, {@link Double#NaN} will be returned.
+ * This calculator class does not implement the getSolarAzimuth method, and throws a {@link UnsupportedOperationException}.
+ * Use the {@link NOAACalculator}if this method is required.
+ *
{@inheritDoc}
+ * @throws UnsupportedOperationException This calculator class does not implement the getSolarAzimuth method. Use the
+ * {@link NOAACalculator} instead.
*/
- public double getUTCMidnight(Calendar calendar, GeoLocation geoLocation) {
- return (getUTCNoon(calendar, geoLocation) + 12);
+ @Override
+ public double getSolarAzimuth(ZonedDateTime zdt, GeoLocation geoLocation) {
+ throw new UnsupportedOperationException(
+ "The SunTimesCalculator class does not implement the getSolarAzimuth method. Use the {@link NOAACalculator} instead.");
}
/**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getSolarAzimuth(Calendar, GeoLocation)
+ * This calculator class does not implement the getSolarElevation method, and throws a {@link UnsupportedOperationException}.
+ * Use the {@link NOAACalculator}if this method is required.
+ *
{@inheritDoc}
+ * @throws UnsupportedOperationException This calculator class does not implement the getSolarElevation method. Use the
+ * {@link NOAACalculator} instead.
*/
- public double getSolarAzimuth(Calendar calendar, GeoLocation geoLocation) {
- throw new UnsupportedOperationException("The SunTimesCalculator class does not implement the getSolarAzimuth method. Use the NOAACalculator instead.");
+ @Override
+ public double getSolarElevation(ZonedDateTime zdt, GeoLocation geoLocation) {
+ throw new UnsupportedOperationException(
+ "The SunTimesCalculator class does not implement the getSolarElevation method. Use the NOAACalculator instead.");
}
/**
- * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getSolarElevation(Calendar, GeoLocation)
+ * This calculator class does not implement the getTimeAtAzimuth method, and throws a {@link UnsupportedOperationException}.
+ * Use the {@link NOAACalculator}if this method is required.
+ *
{@inheritDoc}
+ * @throws UnsupportedOperationException This calculator class does not implement the getTimeAtAzimuth method. Use the
+ * {@link NOAACalculator} instead.
*/
- public double getSolarElevation(Calendar calendar, GeoLocation geoLocation) {
- throw new UnsupportedOperationException("The SunTimesCalculator class does not implement the getSolarElevation method. Use the NOAACalculator instead.");
+ @Override
+ public double getTimeAtAzimuth(LocalDate localDate, GeoLocation geoLocation, double azimuth) {
+ throw new UnsupportedOperationException(
+ "The SunTimesCalculator class does not implement the getTimeAtAzimuth method. Use the {@link NOAACalculator} instead.");
}
}
diff --git a/src/main/java/com/kosherjava/zmanim/util/Time.java b/src/main/java/com/kosherjava/zmanim/util/Time.java
index 1b190893..9b45ad0d 100644
--- a/src/main/java/com/kosherjava/zmanim/util/Time.java
+++ b/src/main/java/com/kosherjava/zmanim/util/Time.java
@@ -1,6 +1,6 @@
/*
* Zmanim Java API
- * Copyright (C) 2004-2025 Eliyahu Hershfeld
+ * Copyright (C) 2004-2026 Eliyahu Hershfeld
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -15,14 +15,14 @@
*/
package com.kosherjava.zmanim.util;
-import java.util.TimeZone;
+import java.time.ZoneId;
/**
* A class that represents a numeric time. Times that represent a time of day are stored as {@link java.util.Date}s in
* this API. The time class is used to represent numeric time such as the time in hours, minutes, seconds and
* milliseconds of a {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour}.
*
- * @author © Eliyahu Hershfeld 2004 - 2025
+ * @author © Eliyahu Hershfeld 2004 - 2026
*/
public class Time {
/** milliseconds in a second. */
@@ -201,14 +201,15 @@ public void setMilliseconds(int milliseconds) {
* @return the time in milliseconds
*/
public double getTime() {
- return this.hours * HOUR_MILLIS + this.minutes * MINUTE_MILLIS + this.seconds * SECOND_MILLIS
+ double time = this.hours * HOUR_MILLIS + this.minutes * MINUTE_MILLIS + this.seconds * SECOND_MILLIS
+ this.milliseconds;
+ return isNegative() ? -time : time;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
- return new ZmanimFormatter(TimeZone.getTimeZone("UTC")).format(this);
+ return new ZmanimFormatter(ZoneId.of("UTC")).format(this);
}
}
diff --git a/src/main/java/com/kosherjava/zmanim/util/Zman.java b/src/main/java/com/kosherjava/zmanim/util/Zman.java
index ff7e622e..f8699166 100644
--- a/src/main/java/com/kosherjava/zmanim/util/Zman.java
+++ b/src/main/java/com/kosherjava/zmanim/util/Zman.java
@@ -15,9 +15,10 @@
*/
package com.kosherjava.zmanim.util;
-import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
import java.util.Comparator;
-import java.util.Date;
/**
* A wrapper class for astronomical times / zmanim that is mostly intended to allow sorting collections of astronomical times.
@@ -36,7 +37,7 @@
* TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
* GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone);
* ComprehensiveZmanimCalendar czc = new ComprehensiveZmanimCalendar(location);
- * Zman sunset = new Zman(czc.getSunset(), "Sunset");
+ * Zman sunset = new Zman(czc.getSunset(), "Sunset");
* Zman shaah16 = new Zman(czc.getShaahZmanis16Point1Degrees(), "Shaah zmanis 16.1");
* Zman sunrise = new Zman(czc.getSunrise(), "Sunrise");
* Zman shaah = new Zman(czc.getShaahZmanisGra(), "Shaah zmanis GRA");
@@ -67,13 +68,13 @@ public class Zman {
private String label;
/**
- * The {@link Date} of the zman
+ * The {@link Instant} of the zman
*/
- private Date zman;
+ private Instant zman;
/**
* The duration if the zman is a {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} (or the various
- * shaah zmanis base times such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() shaah Zmanis GRA} or
+ * shaah zmanis base times such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGRA() shaah Zmanis GRA} or
* {@link com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getShaahZmanis16Point1Degrees() shaah Zmanis 16.1°}).
*/
private long duration;
@@ -87,27 +88,27 @@ public class Zman {
* The location information of the zman.
*/
private GeoLocation geoLocation;
-
+
/**
- * The constructor setting a {@link Date} based zman and a label. In most cases you will likely want to call
- * {@link #Zman(Date, GeoLocation, String)} that also sets the location.
- * @param date the Date of the zman.
- * @param label the label of the zman such as "Sof Zman Krias Shema GRA".
- * @see #Zman(Date, GeoLocation, String)
+ * The constructor setting a {@link Instant} based zman and a label. In most cases you will likely want to call
+ * {@link #Zman(Instant, GeoLocation, String)} that also sets the location.
+ * @param instant the Instant of the zman.
+ * @param label the label of the zman such as "Sof Zman Krias Shema GRA".
+ * @see #Zman(Instant, GeoLocation, String)
*/
- public Zman(Date date, String label) {
- this(date, null, label);
+ public Zman(Instant instant, String label) {
+ this(instant, null, label);
}
/**
- * The constructor setting a {@link Date} based zman and a label. In most cases you will likely want to call
- * {@link #Zman(Date, GeoLocation, String)} that also sets the geo location.
- * @param date the Date of the zman.
+ * The constructor setting a {@link Instant} based zman and a label. In most cases you will likely want to call
+ * {@link #Zman(Instant, GeoLocation, String)} that also sets the geo location.
+ * @param instant the Instant of the zman.
* @param geoLocation the {@link GeoLocation} of the zman.
* @param label the label of the zman such as "Sof Zman Krias Shema GRA".
*/
- public Zman(Date date, GeoLocation geoLocation, String label) {
- this.zman = date;
+ public Zman(Instant instant, GeoLocation geoLocation, String label) {
+ this.zman = instant;
this.geoLocation = geoLocation;
this.label = label;
}
@@ -115,11 +116,11 @@ public Zman(Date date, GeoLocation geoLocation, String label) {
/**
* The constructor setting a duration based zman such as
* {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} (or the various shaah zmanis times such as
- * {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() shaah zmanis GRA} or
+ * {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGRA() shaah zmanis GRA} or
* {@link com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getShaahZmanis16Point1Degrees() shaah Zmanis 16.1°}) and label.
* @param duration a duration based zman such as ({@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour()}
* @param label the label of the zman such as "Shaah Zmanis GRA".
- * @see #Zman(Date, String)
+ * @see #Zman(Instant, String)
*/
public Zman(long duration, String label) {
this.label = label;
@@ -127,21 +128,21 @@ public Zman(long duration, String label) {
}
/**
- * Returns the {@code Date} based zman.
- * @return the zman.
- * @see #setZman(Date)
+ * Returns the {@code Instant} based zman.
+ * @return the Instant of the zman.
+ * @see #setZman(Instant)
*/
- public Date getZman() {
+ public Instant getZman() {
return this.zman;
}
/**
- * Sets a {@code Date} based zman.
- * @param date a {@code Date} based zman
+ * Sets a {@code Instant} based zman.
+ * @param instant an {@code Instant} based zman
* @see #getZman()
*/
- public void setZman(Date date) {
- this.zman = date;
+ public void setZman(Instant instant) {
+ this.zman = instant;
}
/**
@@ -162,7 +163,7 @@ public void setGeoLocation(GeoLocation geoLocation) {
/**
* Returns a duration based zman such as {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour}
- * (or the various shaah zmanis times such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() shaah zmanis GRA}
+ * (or the various shaah zmanis times such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGRA() shaah zmanis GRA}
* or {@link com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getShaahZmanis16Point1Degrees() shaah zmanis 16.1°}).
* @return the duration based zman.
* @see #setDuration(long)
@@ -173,7 +174,7 @@ public long getDuration() {
/**
* Sets a duration based zman such as {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour}
- * (or the various shaah zmanis times as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() shaah zmanis GRA} or
+ * (or the various shaah zmanis times as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGRA() shaah zmanis GRA} or
* {@link com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getShaahZmanis16Point1Degrees() shaah zmanis 16.1°}).
* @param duration duration based zman such as {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour()}.
* @see #getDuration()
@@ -229,11 +230,11 @@ public void setDescription(String description) {
*/
public static final Comparator DATE_ORDER = new Comparator() {
public int compare(Zman zman1, Zman zman2) {
- long firstTime = (zman1 == null || zman1.getZman() == null) ? Long.MAX_VALUE : zman1.getZman().getTime();
- long secondTime = (zman2 == null || zman2.getZman() == null) ? Long.MAX_VALUE : zman2.getZman().getTime();
- return Long.valueOf(firstTime).compareTo(Long.valueOf(secondTime));
+ long firstTime = (zman1 == null || zman1.getZman() == null) ? Long.MAX_VALUE : zman1.getZman().toEpochMilli();
+ long secondTime = (zman2 == null || zman2.getZman() == null) ? Long.MAX_VALUE : zman2.getZman().toEpochMilli();
+ return Long.compare(firstTime, secondTime);
}
- };
+ };
/**
* A {@link Comparator} that will compare and sort zmanim by zmanim label order. Compares its two arguments by the zmanim label
@@ -244,16 +245,16 @@ public int compare(Zman zman1, Zman zman2) {
*/
public static final Comparator NAME_ORDER = new Comparator() {
public int compare(Zman zman1, Zman zman2) {
- String firstLabel = (zman1 == null || zman1.getLabel() == null) ? "" : zman1.getLabel();
- String secondLabel = (zman2 == null || zman2.getLabel() == null) ? "" : zman2.getLabel();
- return firstLabel.compareTo(secondLabel);
+ String firstLabel = (zman1 == null || zman1.getLabel() == null) ? "" : zman1.getLabel();
+ String secondLabel = (zman2 == null || zman2.getLabel() == null) ? "" : zman2.getLabel();
+ return firstLabel.compareTo(secondLabel);
}
- };
+ };
/**
* A {@link Comparator} that will compare and sort duration based zmanim such as
* {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} (or the various shaah zmanis times
- * such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() shaah zmanis GRA} or
+ * such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGRA() shaah zmanis GRA} or
* {@link com.kosherjava.zmanim.ComprehensiveZmanimCalendar#getShaahZmanis16Point1Degrees() shaah zmanis 16.1°}). Returns a negative
* integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
* Please note that this class will sort cases where {@code Zman} is a null.
@@ -262,9 +263,9 @@ public int compare(Zman zman1, Zman zman2) {
public int compare(Zman zman1, Zman zman2) {
long firstDuration = zman1 == null ? Long.MAX_VALUE : zman1.getDuration();
long secondDuration = zman2 == null ? Long.MAX_VALUE : zman2.getDuration();
- return firstDuration == secondDuration ? 0 : firstDuration > secondDuration ? 1 : -1;
+ return Long.compare(firstDuration, secondDuration);
}
- };
+ };
/**
* A method that returns an XML formatted String representing the serialized Object. Very
@@ -288,12 +289,15 @@ public int compare(Zman zman1, Zman zman2) {
* @return The XML formatted String.
*/
public String toXML() {
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
+ ZoneId zoneId = getGeoLocation() == null ? ZoneId.of("UTC") : getGeoLocation().getZoneId();
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS").withZone(zoneId);
StringBuilder sb = new StringBuilder();
sb.append("\n");
sb.append("\t\n");
sb.append("\t").append(getZman() == null ? "": formatter.format(getZman())).append(" \n");
- sb.append("\t" + getGeoLocation().toXML().replaceAll("\n", "\n\t"));
+ if (getGeoLocation() != null) {
+ sb.append("\t").append(getGeoLocation().toXML().replaceAll("\n", "\n\t"));
+ }
sb.append("\n\t").append(getDuration()).append(" \n");
sb.append("\t").append(getDescription()).append(" \n");
sb.append(" ");
@@ -307,7 +311,12 @@ public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("\nLabel:\t").append(this.getLabel());
sb.append("\nZman:\t").append(getZman());
- sb.append("\nGeoLocation:\t").append(getGeoLocation().toString().replaceAll("\n", "\n\t"));
+ sb.append("\nGeoLocation:\t");
+ if (getGeoLocation() == null) {
+ sb.append("null");
+ } else {
+ sb.append(getGeoLocation().toString().replaceAll("\n", "\n\t"));
+ }
sb.append("\nDuration:\t").append(getDuration());
sb.append("\nDescription:\t").append(getDescription());
return sb.toString();
diff --git a/src/main/java/com/kosherjava/zmanim/util/ZmanimFormatter.java b/src/main/java/com/kosherjava/zmanim/util/ZmanimFormatter.java
index 644f0c15..de7e7e0d 100644
--- a/src/main/java/com/kosherjava/zmanim/util/ZmanimFormatter.java
+++ b/src/main/java/com/kosherjava/zmanim/util/ZmanimFormatter.java
@@ -16,15 +16,16 @@
package com.kosherjava.zmanim.util;
import java.lang.reflect.Method;
-import java.text.DateFormat;
import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.LocalTime;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Calendar;
import java.util.List;
-import java.util.TimeZone;
-import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
import com.kosherjava.zmanim.AstronomicalCalendar;
/**
@@ -56,46 +57,46 @@ public class ZmanimFormatter {
/**
* the formatter for minutes as seconds.
*/
- private static DecimalFormat minuteSecondNF = new DecimalFormat("00");
+ private final static DecimalFormat minuteSecondNF = new DecimalFormat("00");
/**
* the formatter for hours.
*/
- private DecimalFormat hourNF;
+ private final DecimalFormat hourNF;
/**
* the formatter for minutes as milliseconds.
*/
- private static DecimalFormat milliNF = new DecimalFormat("000");
+ private final static DecimalFormat milliNF = new DecimalFormat("000");
/**
* The SimpleDateFormat class.
- * @see #setDateFormat(SimpleDateFormat)
+ * @see #setDateTimeFormatter(DateTimeFormatter)
*/
- private SimpleDateFormat dateFormat;
-
+ private DateTimeFormatter dateTimeFormatter;
+
/**
* The TimeZone class.
- * @see #setTimeZone(TimeZone)
+ * @see #setZoneId(ZoneId)
*/
- private TimeZone timeZone = null;
+ private ZoneId zoneId = null;
/**
- * Method to return the TimeZone.
- * @return the timeZone
+ * Method to return the ZoneId.
+ * @return the ZoneId
*/
- public TimeZone getTimeZone() {
- return timeZone;
+ public ZoneId getZoneId() {
+ return zoneId;
}
/**
* Method to set the TimeZone.
- * @param timeZone
- * the timeZone to set
+ * @param zoneId
+ * the ZoneId to set
*/
- public void setTimeZone(TimeZone timeZone) {
- this.timeZone = timeZone;
+ public void setZoneId(ZoneId zoneId) {
+ this.zoneId = zoneId;
}
/**
@@ -138,10 +139,10 @@ public void setTimeZone(TimeZone timeZone) {
/**
* Constructor that defaults to this will use the format "h:mm:ss" for dates and 00.00.00.0 for {@link Time}.
- * @param timeZone the TimeZone Object
+ * @param zoneId the ZoneId Object
*/
- public ZmanimFormatter(TimeZone timeZone) {
- this(0, new SimpleDateFormat("h:mm:ss"), timeZone);
+ public ZmanimFormatter(ZoneId zoneId) {
+ this(0, DateTimeFormatter.ofPattern("h:mm:ss"), zoneId);
}
/**
@@ -150,19 +151,18 @@ public ZmanimFormatter(TimeZone timeZone) {
* @param format
* int The formatting style to use. Using ZmanimFormatter.SEXAGESIMAL_SECONDS_FORMAT will format the
* time of 90*60*1000 + 1 as 1:30:00
- * @param dateFormat the SimpleDateFormat Object
- * @param timeZone the TimeZone Object
+ * @param dateTimeFormatter the DateTimeFormatter Object
+ * @param zoneId the ZoneId Object
*/
- public ZmanimFormatter(int format, SimpleDateFormat dateFormat, TimeZone timeZone) {
- setTimeZone(timeZone);
+ public ZmanimFormatter(int format, DateTimeFormatter dateTimeFormatter, ZoneId zoneId) {
+ setZoneId(zoneId);
String hourFormat = "0";
if (prependZeroHours) {
hourFormat = "00";
}
this.hourNF = new DecimalFormat(hourFormat);
setTimeFormat(format);
- dateFormat.setTimeZone(timeZone);
- setDateFormat(dateFormat);
+ setDateTimeFormatter(dateTimeFormatter.withZone(zoneId));
}
/**
@@ -186,25 +186,23 @@ public void setTimeFormat(int format) {
case SEXAGESIMAL_MILLIS_FORMAT:
setSettings(false, true, true);
break;
- // case DECIMAL_FORMAT:
- // default:
}
}
/**
* Sets the SimpleDateFormat Object
- * @param simpleDateFormat the SimpleDateFormat Object to set
+ * @param dateTimeFormatter the DateTimeFormatter Object to set
*/
- public void setDateFormat(SimpleDateFormat simpleDateFormat) {
- this.dateFormat = simpleDateFormat;
+ public void setDateTimeFormatter(DateTimeFormatter dateTimeFormatter) {
+ this.dateTimeFormatter = dateTimeFormatter;
}
/**
- * returns the SimpleDateFormat Object
- * @return the SimpleDateFormat Object
+ * returns the DateTimeFormatter Object.
+ * @return the DateTimeFormatter Object.
*/
- public SimpleDateFormat getDateFormat() {
- return this.dateFormat;
+ public DateTimeFormatter getDateTimeFormatter() {
+ return this.dateTimeFormatter;
}
/**
@@ -253,6 +251,9 @@ public String format(Time time) {
return formatXSDDurationTime(time);
}
StringBuilder sb = new StringBuilder();
+ if (time.isNegative()) {
+ sb.append("-");
+ }
sb.append(this.hourNF.format(time.getHours()));
sb.append(":");
sb.append(minuteSecondNF.format(time.getMinutes()));
@@ -268,54 +269,30 @@ public String format(Time time) {
}
/**
- * Formats a date using this class's {@link #getDateFormat() date format}.
+ * Formats an Instant using this class's {@link #getDateTimeFormatter()}.
*
- * @param dateTime
- * the date to format
- * @param calendar
- * the {@link java.util.Calendar Calendar} used to help format based on the Calendar's DST and other
+ * @param instant
+ * the Instant to format
+ * @param zoneId
+ * the {@link java.time.ZoneId ZoneId} used to help format based on the Instant's DST and other
* settings.
* @return the formatted String
+ * @see #getXSDateTime(Instant)
*/
- public String formatDateTime(Date dateTime, Calendar calendar) {
- this.dateFormat.setCalendar(calendar);
- if (this.dateFormat.toPattern().equals("yyyy-MM-dd'T'HH:mm:ss")) {
- return getXSDateTime(dateTime);
- } else {
- return this.dateFormat.format(dateTime);
- }
-
- }
-
- /**
- * The date:date-time function returns the current date and time as a date/time string. The date/time string that's
- * returned must be a string in the format defined as the lexical representation of xs:dateTime in [3.3.8 dateTime] of [XML Schema 1.1 Part 2: Datatypes]. The date/time format is
- * basically CCYY-MM-DDThh:mm:ss, although implementers should consult [XML Schema 1.1 Part 2: Datatypes] and [ISO 8601] for details. The date/time string format must include a
- * time zone, either a Z to indicate Coordinated Universal Time or a + or - followed by the difference between the
- * difference from UTC represented as hh:mm.
- * @param date Date Object
- * @param calendar Calendar Object that is now ignored.
- * @return the XSD dateTime
- * @deprecated This method will be removed in v3.0
- */
- @Deprecated // (since="2.5", forRemoval=true)// add back once Java 9 is the minimum supported version
- public String getXSDateTime(Date date, Calendar calendar) {
- return getXSDateTime(date);
+ public String formatDateTime(Instant instant, ZoneId zoneId) {
+ ZonedDateTime dateTime = instant.atZone(zoneId);
+ return this.getDateTimeFormatter().format(dateTime);
}
/**
- * Format the Date using the format "yyyy-MM-dd'T'HH:mm:ssXXX"
- * @param date the Date to format.
- * @return the Date formatted using the format "yyyy-MM-dd'T'HH:mm:ssXXX
+ * Format the Instant using the format "yyyy-MM-dd'T'HH:mm:ssXXX".
+ * @param instant the Instant to format.
+ * @return the Instant formatted using the format "yyyy-MM-dd'T'HH:mm:ssXXX
*/
- public String getXSDateTime(Date date) {
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
- dateFormat.setTimeZone(getTimeZone());
- return new StringBuilder(dateFormat.format(date)).toString();
+ public String formatXSDateTime(Instant instant) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX")
+ .withZone(getZoneId());
+ return formatter.format(instant);
}
/**
@@ -365,13 +342,15 @@ public String formatXSDDurationTime(Time time) {
* format used is:
*
*
- * <AstronomicalTimes date="1969-02-08" type="com.kosherjava.zmanim.AstronomicalCalendar algorithm="US Naval Almanac Algorithm" location="Lakewood, NJ" latitude="40.095965" longitude="-74.22213" elevation="31.0" timeZoneName="Eastern Standard Time" timeZoneID="America/New_York" timeZoneOffset="-5">
- * <Sunrise>2007-02-18T06:45:27-05:00</Sunrise>
- * <TemporalHour>PT54M17.529S</TemporalHour>
+ * <AstronomicalTimes date="1969-02-08" type="com.kosherjava.zmanim.AstronomicalCalendar algorithm="US Naval Almanac Algorithm" location="Montreal, Quebec" latitude="45.497" longitude="-73.63" elevation="85.0" timeZoneName="Eastern Standard Time" timeZoneID="America/New_York" timeZoneOffset="-5">
+ * <SeaLevelSunset>1969-02-08T17:11:26-05:00</SeaLevelSunset>
+ * <TemporalHour>PT50M23.259S</TemporalHour>
* ...
* </AstronomicalTimes>
*
*
+ * If a zman does not occur, the value "N/A" will be returned.
+ *
* Note that the output uses the xsd:dateTime format for
* times such as sunrise, and xsd:duration format for
* times that are a duration such as the length of a
@@ -380,107 +359,104 @@ public String formatXSDDurationTime(Time time) {
*
* @param astronomicalCalendar the AstronomicalCalendar Object
*
- * @return The XML formatted String. The format will be:
- *
- *
- * <AstronomicalTimes date="1969-02-08" type="com.kosherjava.zmanim.AstronomicalCalendar algorithm="US Naval Almanac Algorithm" location="Lakewood, NJ" latitude="40.095965" longitude="-74.22213" elevation="31.0" timeZoneName="Eastern Standard Time" timeZoneID="America/New_York" timeZoneOffset="-5">
- * <Sunrise>2007-02-18T06:45:27-05:00</Sunrise>
- * <TemporalHour>PT54M17.529S</TemporalHour>
- * ...
- * </AstronomicalTimes>
- *
+ * @return The XML String formatted as described above.
*
* @todo Add proper schema, and support for nulls. XSD duration (for solar hours), should probably return nil and not P.
*/
public static String toXML(AstronomicalCalendar astronomicalCalendar) {
- ZmanimFormatter formatter = new ZmanimFormatter(ZmanimFormatter.XSD_DURATION_FORMAT, new SimpleDateFormat(
- "yyyy-MM-dd'T'HH:mm:ss"), astronomicalCalendar.getGeoLocation().getTimeZone());
- DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
- df.setTimeZone(astronomicalCalendar.getGeoLocation().getTimeZone());
-
- Date date = astronomicalCalendar.getCalendar().getTime();
- TimeZone tz = astronomicalCalendar.getGeoLocation().getTimeZone();
- boolean daylight = tz.useDaylightTime() && tz.inDaylightTime(date);
+ ZmanimFormatter formatter = new ZmanimFormatter(ZmanimFormatter.XSD_DURATION_FORMAT, DateTimeFormatter.ofPattern(
+ "yyyy-MM-dd'T'HH:mm:ss"), astronomicalCalendar.getGeoLocation().getZoneId());
+ DateTimeFormatter xsdFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX")
+ .withZone(astronomicalCalendar.getGeoLocation().getZoneId());
+ DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+ df = df.withZone(astronomicalCalendar.getGeoLocation().getZoneId());
+
+ LocalDate localDate = astronomicalCalendar.getLocalDate();
+ GeoLocation geoLocation = astronomicalCalendar.getGeoLocation();
+ ZonedDateTime lastMidnight = ZonedDateTime.of(astronomicalCalendar.getLocalDate(), LocalTime.MIDNIGHT, astronomicalCalendar.getGeoLocation().getZoneId());
+ double offsetHours = lastMidnight.getOffset().getTotalSeconds() / 3600.0;
+ String timeZoneName = lastMidnight.format(DateTimeFormatter.ofPattern("zzzz", Locale.getDefault()));
StringBuilder sb = new StringBuilder("<");
- if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.AstronomicalCalendar")) {
+ boolean isAstronomicalCalendar = astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.AstronomicalCalendar");
+ boolean isComprehensiveZmanimCalendar = astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ComprehensiveZmanimCalendar");
+ boolean isZmanimCalendar = astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ZmanimCalendar");
+ if (isAstronomicalCalendar) {
sb.append("AstronomicalTimes");
// TODO: use proper schema ref, and maybe build a real schema.
// output += "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
// output += xsi:schemaLocation="http://www.kosherjava.com/zmanim astronomical.xsd"
- } else if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ComprehensiveZmanimCalendar")) {
+ } else if (isComprehensiveZmanimCalendar) {
sb.append("Zmanim");
// TODO: use proper schema ref, and maybe build a real schema.
// output += "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
// output += xsi:schemaLocation="http://www.kosherjava.com/zmanim zmanim.xsd"
- } else if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ZmanimCalendar")) {
+ } else if (isZmanimCalendar) {
sb.append("BasicZmanim");
// TODO: use proper schema ref, and maybe build a real schema.
// output += "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
// output += xsi:schemaLocation="http://www.kosherjava.com/zmanim basicZmanim.xsd"
}
- sb.append(" date=\"").append(df.format(date)).append("\"");
+ sb.append(" date=\"").append(df.format(localDate)).append("\"");
sb.append(" type=\"").append(astronomicalCalendar.getClass().getName()).append("\"");
sb.append(" algorithm=\"").append(astronomicalCalendar.getAstronomicalCalculator().getCalculatorName()).append("\"");
sb.append(" location=\"").append(astronomicalCalendar.getGeoLocation().getLocationName()).append("\"");
sb.append(" latitude=\"").append(astronomicalCalendar.getGeoLocation().getLatitude()).append("\"");
sb.append(" longitude=\"").append(astronomicalCalendar.getGeoLocation().getLongitude()).append("\"");
sb.append(" elevation=\"").append(astronomicalCalendar.getGeoLocation().getElevation()).append("\"");
- sb.append(" timeZoneName=\"").append(tz.getDisplayName(daylight, TimeZone.LONG)).append("\"");
- sb.append(" timeZoneID=\"").append(tz.getID()).append("\"");
- sb.append(" timeZoneOffset=\"")
- .append((tz.getOffset(astronomicalCalendar.getCalendar().getTimeInMillis()) / ((double) HOUR_MILLIS)))
- .append("\"");
- // sb.append(" useElevationAllZmanim=\"").append(astronomicalCalendar.useElevationAllZmanim).append("\""); //TODO likely using reflection
-
+ sb.append(" timeZoneName=\"").append(timeZoneName).append("\"");
+ sb.append(" timeZoneID=\"").append(geoLocation.getZoneId().getId()).append("\"");
+ sb.append(" timeZoneOffset=\"").append(offsetHours).append("\"");
+ //sb.append(" useElevationAllZmanim=\"").append(astronomicalCalendar.useElevationAllZmanim()).append("\""); //TODO likely using reflection
sb.append(">\n");
Method[] theMethods = astronomicalCalendar.getClass().getMethods();
- String tagName = "";
- Object value = null;
- List dateList = new ArrayList();
- List durationList = new ArrayList();
- List otherList = new ArrayList();
- for (int i = 0; i < theMethods.length; i++) {
- if (includeMethod(theMethods[i])) {
- tagName = theMethods[i].getName().substring(3);
- // String returnType = theMethods[i].getReturnType().getName();
- try {
- value = theMethods[i].invoke(astronomicalCalendar, (Object[]) null);
- if (value == null) {// TODO: Consider using reflection to determine the return type, not the value
- otherList.add("<" + tagName + ">N/A" + tagName + ">");
- // TODO: instead of N/A, consider return proper xs:nil.
- // otherList.add("<" + tagName + " xs:nil=\"true\" />");
- } else if (value instanceof Date) {
- dateList.add(new Zman((Date) value, tagName));
- } else if (value instanceof Long || value instanceof Integer) {// shaah zmanis
- if (((Long) value).longValue() == Long.MIN_VALUE) {
- otherList.add("<" + tagName + ">N/A" + tagName + ">");
- // TODO: instead of N/A, consider return proper xs:nil.
- // otherList.add("<" + tagName + " xs:nil=\"true\" />");
- } else {
- durationList.add(new Zman((int) ((Long) value).longValue(), tagName));
- }
- } else { // will probably never enter this block, but is present to be future-proof
- otherList.add("<" + tagName + ">" + value + "" + tagName + ">");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
+ String tagName;
+ Object value;
+ List dateList = new ArrayList<>();
+ List durationList = new ArrayList<>();
+ List otherList = new ArrayList<>();
+ for (Method theMethod : theMethods) {
+ if (includeMethod(theMethod)) {
+ tagName = theMethod.getName().substring(3);
+ // String returnType = theMethods[i].getReturnType().getName();
+ try {
+ value = theMethod.invoke(astronomicalCalendar, (Object[]) null);
+ if (value == null) {// TODO: Consider using reflection to determine the return type, not the value
+ otherList.add("<" + tagName + ">N/A" + tagName + ">");
+ // TODO: instead of N/A, consider return proper xs:nil.
+ // otherList.add("<" + tagName + " xs:nil=\"true\" />");
+ } else if (value instanceof Instant) {
+ dateList.add(new Zman((Instant) value, tagName));
+ } else if (value instanceof Long || value instanceof Integer) {// shaah zmanis
+ value = ((Number) value).longValue();
+ if ((Long) value == Long.MIN_VALUE) {
+ otherList.add("<" + tagName + ">N/A" + tagName + ">");
+ // TODO: instead of N/A, consider return proper xs:nil.
+ // otherList.add("<" + tagName + " xs:nil=\"true\" />");
+ } else {
+ durationList.add(new Zman((int) ((Long) value).longValue(), tagName));
+ }
+ } else { // will probably never enter this block, but is present to be future-proof
+ otherList.add("<" + tagName + ">" + value + "" + tagName + ">");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
Zman zman;
- Collections.sort(dateList, Zman.DATE_ORDER);
+ dateList.sort(Zman.DATE_ORDER);
for (int i = 0; i < dateList.size(); i++) {
- zman = (Zman) dateList.get(i);
+ zman = dateList.get(i);
sb.append("\t<").append(zman.getLabel()).append(">");
- sb.append(formatter.formatDateTime(zman.getZman(), astronomicalCalendar.getCalendar()));
+ sb.append(xsdFormatter.format(zman.getZman()));
sb.append("").append(zman.getLabel()).append(">\n");
}
- Collections.sort(durationList, Zman.DURATION_ORDER);
+ durationList.sort(Zman.DURATION_ORDER);
for (int i = 0; i < durationList.size(); i++) {
- zman = (Zman) durationList.get(i);
+ zman = durationList.get(i);
sb.append("\t<" + zman.getLabel()).append(">");
sb.append(formatter.format((int) zman.getDuration())).append("").append(zman.getLabel())
.append(">\n");
@@ -490,11 +466,11 @@ public static String toXML(AstronomicalCalendar astronomicalCalendar) {
sb.append("\t").append(otherList.get(i)).append("\n");
}
- if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.AstronomicalCalendar")) {
+ if (isAstronomicalCalendar) {
sb.append("");
- } else if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ComprehensiveZmanimCalendar")) {
+ } else if (isComprehensiveZmanimCalendar) {
sb.append("");
- } else if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ZmanimCalendar")) {
+ } else if (isZmanimCalendar) {
sb.append("");
}
return sb.toString();
@@ -509,16 +485,16 @@ public static String toXML(AstronomicalCalendar astronomicalCalendar) {
* "date":"1969-02-08",
* "type":"com.kosherjava.zmanim.AstronomicalCalendar",
* "algorithm":"US Naval Almanac Algorithm",
- * "location":"Lakewood, NJ",
- * "latitude":"40.095965",
- * "longitude":"-74.22213",
- * "elevation:"31.0",
+ * "location":"Montreal, Quebec",
+ * "latitude":"45.497",
+ * "longitude":"-73.63",
+ * "elevation:"85.0",
* "timeZoneName":"Eastern Standard Time",
* "timeZoneID":"America/New_York",
* "timeZoneOffset":"-5"},
* "AstronomicalTimes":{
- * "Sunrise":"2007-02-18T06:45:27-05:00",
- * "TemporalHour":"PT54M17.529S"
+ * "SeaLevelSunset":"1969-02-08T17:11:26-05:00",
+ * "TemporalHour":"PT50M23.259S"
* ...
* }
* }
@@ -528,106 +504,94 @@ public static String toXML(AstronomicalCalendar astronomicalCalendar) {
* times such as sunrise, and xsd:duration format for
* times that are a duration such as the length of a
* {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour}.
+ * If a zman does not occur, the value "N/A" will be returned.
*
* @param astronomicalCalendar the AstronomicalCalendar Object
*
- * @return The JSON formatted String. The format will be:
- *
- * {
- * "metadata":{
- * "date":"1969-02-08",
- * "type":"com.kosherjava.zmanim.AstronomicalCalendar",
- * "algorithm":"US Naval Almanac Algorithm",
- * "location":"Lakewood, NJ",
- * "latitude":"40.095965",
- * "longitude":"-74.22213",
- * "elevation:"31.0",
- * "timeZoneName":"Eastern Standard Time",
- * "timeZoneID":"America/New_York",
- * "timeZoneOffset":"-5"},
- * "AstronomicalTimes":{
- * "Sunrise":"2007-02-18T06:45:27-05:00",
- * "TemporalHour":"PT54M17.529S"
- * ...
- * }
- * }
- *
+ * @return The JSON String formatted as described above.
*/
public static String toJSON(AstronomicalCalendar astronomicalCalendar) {
- ZmanimFormatter formatter = new ZmanimFormatter(ZmanimFormatter.XSD_DURATION_FORMAT, new SimpleDateFormat(
- "yyyy-MM-dd'T'HH:mm:ss"), astronomicalCalendar.getGeoLocation().getTimeZone());
- DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
- df.setTimeZone(astronomicalCalendar.getGeoLocation().getTimeZone());
-
- Date date = astronomicalCalendar.getCalendar().getTime();
- TimeZone tz = astronomicalCalendar.getGeoLocation().getTimeZone();
- boolean daylight = tz.useDaylightTime() && tz.inDaylightTime(date);
+ ZmanimFormatter formatter = new ZmanimFormatter(ZmanimFormatter.XSD_DURATION_FORMAT, DateTimeFormatter.ofPattern(
+ "yyyy-MM-dd'T'HH:mm:ss"), astronomicalCalendar.getGeoLocation().getZoneId());
+ DateTimeFormatter xsdFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX")
+ .withZone(astronomicalCalendar.getGeoLocation().getZoneId());
+ DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd")
+ .withZone(astronomicalCalendar.getGeoLocation().getZoneId());
+
+ LocalDate localDate = astronomicalCalendar.getLocalDate();
+ GeoLocation geoLocation = astronomicalCalendar.getGeoLocation();
+ ZonedDateTime lastMidnight = ZonedDateTime.of(astronomicalCalendar.getLocalDate(), LocalTime.MIDNIGHT,
+ astronomicalCalendar.getGeoLocation().getZoneId());
+ double offsetHours = lastMidnight.getOffset().getTotalSeconds() / 3600.0;
+ String timeZoneName = lastMidnight.format(DateTimeFormatter.ofPattern("zzzz", Locale.getDefault()));
StringBuilder sb = new StringBuilder("{\n\"metadata\":{\n");
- sb.append("\t\"date\":\"").append(df.format(date)).append("\",\n");
+ sb.append("\t\"date\":\"").append(df.format(localDate)).append("\",\n");
sb.append("\t\"type\":\"").append(astronomicalCalendar.getClass().getName()).append("\",\n");
sb.append("\t\"algorithm\":\"").append(astronomicalCalendar.getAstronomicalCalculator().getCalculatorName()).append("\",\n");
- sb.append("\t\"location\":\"").append(astronomicalCalendar.getGeoLocation().getLocationName()).append("\",\n");
- sb.append("\t\"latitude\":\"").append(astronomicalCalendar.getGeoLocation().getLatitude()).append("\",\n");
- sb.append("\t\"longitude\":\"").append(astronomicalCalendar.getGeoLocation().getLongitude()).append("\",\n");
- sb.append("\t\"elevation\":\"").append(astronomicalCalendar.getGeoLocation().getElevation()).append("\",\n");
- sb.append("\t\"timeZoneName\":\"").append(tz.getDisplayName(daylight, TimeZone.LONG)).append("\",\n");
- sb.append("\t\"timeZoneID\":\"").append(tz.getID()).append("\",\n");
- sb.append("\t\"timeZoneOffset\":\"")
- .append((tz.getOffset(astronomicalCalendar.getCalendar().getTimeInMillis()) / ((double) HOUR_MILLIS)))
- .append("\"");
-
+ sb.append("\t\"location\":\"").append(geoLocation.getLocationName()).append("\",\n");
+ sb.append("\t\"latitude\":\"").append(geoLocation.getLatitude()).append("\",\n");
+ sb.append("\t\"longitude\":\"").append(geoLocation.getLongitude()).append("\",\n");
+ sb.append("\t\"elevation\":\"").append(geoLocation.getElevation()).append("\",\n");
+ sb.append("\t\"timeZoneName\":\"").append(timeZoneName).append("\",\n");
+ sb.append("\t\"timeZoneID\":\"").append(geoLocation.getZoneId().getId()).append("\",\n");
+ sb.append("\t\"timeZoneOffset\":\"").append(offsetHours).append("\"");
sb.append("},\n\"");
-
- if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.AstronomicalCalendar")) {
- sb.append("AstronomicalTimes");
- } else if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ComprehensiveZmanimCalendar")) {
- sb.append("Zmanim");
- } else if (astronomicalCalendar.getClass().getName().equals("com.kosherjava.zmanim.ZmanimCalendar")) {
- sb.append("BasicZmanim");
- }
+
+ switch (astronomicalCalendar.getClass().getName()) {
+ case "com.kosherjava.zmanim.AstronomicalCalendar":
+ sb.append("AstronomicalTimes");
+ break;
+ case "com.kosherjava.zmanim.ComprehensiveZmanimCalendar":
+ sb.append("Zmanim");
+ break;
+ case "com.kosherjava.zmanim.ZmanimCalendar":
+ sb.append("BasicZmanim");
+ break;
+ }
sb.append("\":{\n");
Method[] theMethods = astronomicalCalendar.getClass().getMethods();
- String tagName = "";
- Object value = null;
- List dateList = new ArrayList();
- List durationList = new ArrayList();
- List otherList = new ArrayList();
- for (int i = 0; i < theMethods.length; i++) {
- if (includeMethod(theMethods[i])) {
- tagName = theMethods[i].getName().substring(3);
- // String returnType = theMethods[i].getReturnType().getName();
- try {
- value = theMethods[i].invoke(astronomicalCalendar, (Object[]) null);
- if (value == null) {// TODO: Consider using reflection to determine the return type, not the value
- otherList.add("\"" + tagName + "\":\"N/A\",");
- } else if (value instanceof Date) {
- dateList.add(new Zman((Date) value, tagName));
- } else if (value instanceof Long || value instanceof Integer) {// shaah zmanis
- if (((Long) value).longValue() == Long.MIN_VALUE) {
- otherList.add("\"" + tagName + "\":\"N/A\"");
- } else {
- durationList.add(new Zman((int) ((Long) value).longValue(), tagName));
- }
- } else { // will probably never enter this block, but is present to be future-proof
- otherList.add("\"" + tagName + "\":\"" + value + "\",");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
+ String tagName;
+ Object value;
+ List dateList = new ArrayList<>();
+ List durationList = new ArrayList<>();
+ List otherList = new ArrayList<>();
+ for (Method theMethod : theMethods) {
+ if (includeMethod(theMethod)) {
+ tagName = theMethod.getName().substring(3);
+ // String returnType = theMethods[i].getReturnType().getName();
+ try {
+ value = theMethod.invoke(astronomicalCalendar, (Object[]) null);
+ if (value == null) {// TODO: Consider using reflection to determine the return type, not the value
+ otherList.add("\"" + tagName + "\":\"N/A\",");
+ } else if (value instanceof Instant) {
+ dateList.add(new Zman((Instant) value, tagName));
+ } else if (value instanceof Long || value instanceof Integer) {// shaah zmanis
+ value = ((Number) value).longValue();
+ if ((Long) value == Long.MIN_VALUE) {
+ otherList.add("\"" + tagName + "\":\"N/A\"");
+ } else {
+ durationList.add(new Zman((int) ((Long) value).longValue(), tagName));
+ }
+ } else { // will probably never enter this block, but is present to be future-proof
+ otherList.add("\"" + tagName + "\":\"" + value + "\",");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
Zman zman;
- Collections.sort(dateList, Zman.DATE_ORDER);
+ dateList.sort(Zman.DATE_ORDER);
for (int i = 0; i < dateList.size(); i++) {
- zman = (Zman) dateList.get(i);
+ zman = dateList.get(i);
sb.append("\t\"").append(zman.getLabel()).append("\":\"");
- sb.append(formatter.formatDateTime(zman.getZman(), astronomicalCalendar.getCalendar()));
+ sb.append(xsdFormatter.format(zman.getZman()));
sb.append("\",\n");
}
- Collections.sort(durationList, Zman.DURATION_ORDER);
+ durationList.sort(Zman.DURATION_ORDER);
for (int i = 0; i < durationList.size(); i++) {
- zman = (Zman) durationList.get(i);
+ zman = durationList.get(i);
sb.append("\t\"" + zman.getLabel()).append("\":\"");
sb.append(formatter.format((int) zman.getDuration())).append("\",\n");
}
@@ -647,10 +611,10 @@ public static String toJSON(AstronomicalCalendar astronomicalCalendar) {
* @return if the method should be included in serialization
*/
private static boolean includeMethod(Method method) {
- List methodWhiteList = new ArrayList();
+ List methodWhiteList = new ArrayList<>();
// methodWhiteList.add("getName");
- List methodBlackList = new ArrayList();
+ List methodBlackList = new ArrayList<>();
// methodBlackList.add("getGregorianChange");
if (methodWhiteList.contains(method.getName()))
@@ -663,9 +627,6 @@ private static boolean includeMethod(Method method) {
if (!method.getName().startsWith("get"))
return false;
- if (method.getReturnType().getName().endsWith("Date") || method.getReturnType().getName().endsWith("long")) {
- return true;
- }
- return false;
- }
+ return method.getReturnType().getName().endsWith("Instant") || method.getReturnType().getName().endsWith("long");
+ }
}
diff --git a/src/main/java/com/kosherjava/zmanim/util/package-info.java b/src/main/java/com/kosherjava/zmanim/util/package-info.java
index e3fd6c4d..42159bee 100644
--- a/src/main/java/com/kosherjava/zmanim/util/package-info.java
+++ b/src/main/java/com/kosherjava/zmanim/util/package-info.java
@@ -1,8 +1,8 @@
/**
- * Utility classes for the Zmanim API including classes to calculate sun based times, {@link com.kosherjava.zmanim.util.GeoLocation location information},
- * some {@link com.kosherjava.zmanim.util.ZmanimFormatter formatting} and {@link com.kosherjava.zmanim.util.GeoLocationUtils geographic location utilities}. Included in this package
- * are implementations for both the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO} and {@link com.kosherjava.zmanim.util.NOAACalculator NOAA / Jean Meeus} algorithms.
+ * Utility classes for the Zmanim API including classes to calculate sun based times, {@link GeoLocation location information},
+ * some {@link ZmanimFormatter formatting}. Included in this package
+ * are implementations for both the {@link SunTimesCalculator USNO} and {@link NOAACalculator NOAA / Jean Meeus} algorithms.
*
- * @author © Eliyahu Hershfeld 2004 - 2022
+ * @author © Eliyahu Hershfeld 2004 - 2026
*/
package com.kosherjava.zmanim.util;
diff --git a/src/test/java/com/kosherjava/zmanim/AstronomicalCalendarRegressionTest.java b/src/test/java/com/kosherjava/zmanim/AstronomicalCalendarRegressionTest.java
new file mode 100644
index 00000000..6df90326
--- /dev/null
+++ b/src/test/java/com/kosherjava/zmanim/AstronomicalCalendarRegressionTest.java
@@ -0,0 +1,46 @@
+package com.kosherjava.zmanim;
+
+import static org.junit.Assert.assertEquals;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.Test;
+
+import com.kosherjava.zmanim.util.GeoLocation;
+
+public class AstronomicalCalendarRegressionTest {
+
+ @Test
+ public void localMeanTimeForLateEveningStaysOnRequestedLocalDate() {
+ GeoLocation geoLocation = new GeoLocation("Chicago", 41.8781, -87.6298, ZoneId.of("America/Chicago"));
+ AstronomicalCalendar astronomicalCalendar = new AstronomicalCalendar(geoLocation);
+ LocalDate localDate = LocalDate.of(2026, 6, 1);
+ astronomicalCalendar.setLocalDate(localDate);
+
+ Instant actual = astronomicalCalendar.getLocalMeanTime(LocalTime.of(23, 0));
+ ZonedDateTime civilTime = ZonedDateTime.of(localDate, LocalTime.of(23, 0), geoLocation.getZoneId());
+ Instant expected = civilTime.toInstant().minusMillis(geoLocation.getLocalMeanTimeOffset(civilTime.toInstant()));
+
+ assertEquals(expected, actual);
+ assertEquals(localDate, actual.atZone(geoLocation.getZoneId()).toLocalDate());
+ }
+
+ @Test
+ public void localMeanTimeUsesOffsetAtRequestedTimeOnDstTransitionDate() {
+ GeoLocation geoLocation = new GeoLocation("New York", 40.7128, -74.0060, ZoneId.of("America/New_York"));
+ AstronomicalCalendar astronomicalCalendar = new AstronomicalCalendar(geoLocation);
+ LocalDate localDate = LocalDate.of(2026, 3, 8);
+ astronomicalCalendar.setLocalDate(localDate);
+
+ Instant actual = astronomicalCalendar.getLocalMeanTime(LocalTime.NOON);
+ ZonedDateTime civilTime = ZonedDateTime.of(localDate, LocalTime.NOON, geoLocation.getZoneId());
+ Instant expected = civilTime.toInstant().minusMillis(geoLocation.getLocalMeanTimeOffset(civilTime.toInstant()));
+
+ assertEquals(expected, actual);
+ assertEquals(LocalTime.of(12, 56, 1, 440_000_000), actual.atZone(geoLocation.getZoneId()).toLocalTime());
+ }
+}
diff --git a/src/test/java/com/kosherjava/zmanim/CalendarEqualityRegressionTest.java b/src/test/java/com/kosherjava/zmanim/CalendarEqualityRegressionTest.java
new file mode 100644
index 00000000..21690cb9
--- /dev/null
+++ b/src/test/java/com/kosherjava/zmanim/CalendarEqualityRegressionTest.java
@@ -0,0 +1,57 @@
+package com.kosherjava.zmanim;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.time.ZoneId;
+
+import org.junit.Test;
+
+import com.kosherjava.zmanim.util.GeoLocation;
+
+public class CalendarEqualityRegressionTest {
+
+ @Test
+ public void astronomicalCalendarCloneRemainsEqual() {
+ AstronomicalCalendar astronomicalCalendar = new AstronomicalCalendar(
+ new GeoLocation("Lakewood", 40.0828, -74.2094, ZoneId.of("America/New_York")));
+ astronomicalCalendar.getAstronomicalCalculator().setRefraction(0.6);
+ astronomicalCalendar.getAstronomicalCalculator().setSolarRadius(0.3);
+ astronomicalCalendar.getAstronomicalCalculator().setEarthRadius(6400);
+
+ AstronomicalCalendar clone = (AstronomicalCalendar) astronomicalCalendar.clone();
+
+ assertEquals(astronomicalCalendar, clone);
+ assertEquals(astronomicalCalendar.hashCode(), clone.hashCode());
+ }
+
+ @Test
+ public void zmanimCalendarEqualityIncludesZmanimSettings() {
+ ZmanimCalendar zmanimCalendar = new ZmanimCalendar(
+ new GeoLocation("Lakewood", 40.0828, -74.2094, ZoneId.of("America/New_York")));
+ ZmanimCalendar clone = (ZmanimCalendar) zmanimCalendar.clone();
+
+ assertEquals(zmanimCalendar, clone);
+ assertEquals(zmanimCalendar.hashCode(), clone.hashCode());
+
+ clone.setUseElevation(true);
+ clone.setUseAstronomicalChatzosForOtherZmanim(true);
+ clone.setCandleLightingOffset(40);
+
+ assertFalse(zmanimCalendar.equals(clone));
+ }
+
+ @Test
+ public void comprehensiveZmanimCalendarEqualityIncludesAteretTorahOffset() {
+ ComprehensiveZmanimCalendar comprehensiveZmanimCalendar = new ComprehensiveZmanimCalendar(
+ new GeoLocation("Lakewood", 40.0828, -74.2094, ZoneId.of("America/New_York")));
+ ComprehensiveZmanimCalendar clone = (ComprehensiveZmanimCalendar) comprehensiveZmanimCalendar.clone();
+
+ assertEquals(comprehensiveZmanimCalendar, clone);
+ assertEquals(comprehensiveZmanimCalendar.hashCode(), clone.hashCode());
+
+ clone.setAteretTorahSunsetOffset(30);
+
+ assertFalse(comprehensiveZmanimCalendar.equals(clone));
+ }
+}
diff --git a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/RegressionTestFileWriter.java b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/RegressionTestFileWriter.java
index d498431d..ea275fc6 100644
--- a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/RegressionTestFileWriter.java
+++ b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/RegressionTestFileWriter.java
@@ -1,11 +1,12 @@
package com.kosherjava.zmanim.hebrewcalendar;
import com.kosherjava.zmanim.ComprehensiveZmanimCalendar;
-import com.kosherjava.zmanim.util.AstronomicalCalculator;
import com.kosherjava.zmanim.util.GeoLocation;
import java.io.*;
+import java.time.Instant;
import java.time.LocalDate;
+import java.time.ZoneId;
import java.util.*;
public class RegressionTestFileWriter {
@@ -15,9 +16,9 @@ public static void main(String[] args) throws IOException {
LocalDate end = LocalDate.of(9999, 1, 1);
LocalDate current = start;
JewishCalendar cal = new JewishCalendar(current);
- GregorianCalendar gregorian = new GregorianCalendar(current.getYear(), current.getMonthValue() - 1, current.getDayOfMonth());
+ LocalDate gregorian = LocalDate.of(current.getYear(), current.getMonthValue() , current.getDayOfMonth());
JewishDate date = new JewishDate(current);
- ComprehensiveZmanimCalendar zcal = new ComprehensiveZmanimCalendar(new GeoLocation("Lakewood, NJ", 40.096, -74.222, 29.02, TimeZone.getTimeZone("America/New_York")));
+ ComprehensiveZmanimCalendar zcal = new ComprehensiveZmanimCalendar(new GeoLocation("Lakewood, NJ", 40.096, -74.222, 29.02, ZoneId.of("America/New_York")));
List calendars = new ArrayList<>();
List zmanim = new ArrayList<>();
@@ -36,7 +37,7 @@ public static void main(String[] args) throws IOException {
cal.isErevYomTov(), cal.isErevRoshChodesh(), cal.isYomKippurKatan(), cal.isBeHaB(), cal.isTaanis(),
cal.isTaanisBechoros(), cal.getDayOfChanukah(), cal.isChanukah(), cal.isPurim(),
cal.isRoshChodesh(), cal.isMacharChodesh(), cal.isShabbosMevorchim(), cal.getDayOfOmer(),
- cal.isTishaBav(), cal.getMolad(), cal.getMoladAsDate(), cal.getTchilasZmanKidushLevana3Days(),
+ cal.isTishaBav(), cal.getMolad(), cal.getMoladAsInstant(), cal.getTchilasZmanKidushLevana3Days(),
cal.getTchilasZmanKidushLevana7Days(), cal.getSofZmanKidushLevanaBetweenMoldos(),
cal.getSofZmanKidushLevana15Days(), cal.getTekufasTishreiElapsedDays()));
@@ -48,9 +49,9 @@ public static void main(String[] args) throws IOException {
zcal.getShaahZmanisAteretTorah(), zcal.getShaahZmanisAlos16Point1ToTzais3Point8(),
zcal.getShaahZmanisAlos16Point1ToTzais3Point7(), zcal.getShaahZmanis96Minutes(),
zcal.getShaahZmanis120Minutes(), zcal.getShaahZmanis120MinutesZmanis(),
- zcal.getPlagHamincha120MinutesZmanis(), zcal.getPlagHamincha120Minutes(), zcal.getAlos60(),
- zcal.getAlos72Zmanis(), zcal.getAlos96(), zcal.getAlos90Zmanis(), zcal.getAlos96Zmanis(),
- zcal.getAlos90(), zcal.getAlos120(), zcal.getAlos120Zmanis(), zcal.getAlos26Degrees(),
+ zcal.getPlagHamincha120MinutesZmanis(), zcal.getPlagHamincha120Minutes(), zcal.getAlos60Minutes(),
+ zcal.getAlos72Zmanis(), zcal.getAlos96Minutes(), zcal.getAlos90Zmanis(), zcal.getAlos96Zmanis(),
+ zcal.getAlos90Minutes(), zcal.getAlos120Minutes(), zcal.getAlos120Zmanis(), zcal.getAlos26Degrees(),
zcal.getAlos18Degrees(), zcal.getAlos19Degrees(), zcal.getAlos19Point8Degrees(),
zcal.getAlos16Point1Degrees(), zcal.getMisheyakir11Point5Degrees(), zcal.getMisheyakir11Degrees(),
zcal.getMisheyakir10Point2Degrees(), zcal.getMisheyakir7Point65Degrees(),
@@ -68,7 +69,7 @@ public static void main(String[] args) throws IOException {
zcal.getSofZmanTfilaMGA96MinutesZmanis(), zcal.getSofZmanTfilaMGA120Minutes(),
zcal.getSofZmanTfila2HoursBeforeChatzos(), zcal.getMinchaGedola30Minutes(),
zcal.getMinchaGedola72Minutes(), zcal.getMinchaGedola16Point1Degrees(),
- zcal.getMinchaGedolaAhavatShalom(), zcal.getMinchaGedolaGreaterThan30(),
+ zcal.getMinchaGedolaAhavatShalom(), zcal.getMinchaGedolaGreaterThan30(zcal.getMinchaGedolaGRA()),
zcal.getMinchaKetana16Point1Degrees(), zcal.getMinchaKetanaAhavatShalom(),
zcal.getMinchaKetana72Minutes(), zcal.getPlagHamincha60Minutes(), zcal.getPlagHamincha72Minutes(),
zcal.getPlagHamincha90Minutes(), zcal.getPlagHamincha96Minutes(),
@@ -83,18 +84,18 @@ public static void main(String[] args) throws IOException {
zcal.getBainHashmashosYereim16Point875Minutes(), zcal.getBainHashmashosYereim2Point8Degrees(),
zcal.getBainHashmashosYereim13Point5Minutes(), zcal.getBainHashmashosYereim2Point1Degrees(),
zcal.getTzaisGeonim3Point7Degrees(), zcal.getTzaisGeonim3Point8Degrees(),
- zcal.getTzaisGeonim5Point95Degrees(),zcal.getTzaisGeonim4Point61Degrees(),
- zcal.getTzaisGeonim4Point37Degrees(), zcal.getTzaisGeonim5Point88Degrees(),
+ zcal.getTzaisGeonim5Point95Degrees(),zcal.getTzaisGeonim4Point66Degrees(),
+ zcal.getTzaisGeonim4Point42Degrees(),
zcal.getTzaisGeonim4Point8Degrees(), zcal.getTzaisGeonim6Point45Degrees(),
zcal.getTzaisGeonim7Point083Degrees(), zcal.getTzaisGeonim7Point67Degrees(),
zcal.getTzaisGeonim8Point5Degrees(), zcal.getTzaisGeonim9Point3Degrees(),
- zcal.getTzaisGeonim9Point75Degrees(), zcal.getTzais60(), zcal.getTzaisAteretTorah(),
+ zcal.getTzaisGeonim9Point75Degrees(), zcal.getTzais60Minutes(), zcal.getTzaisAteretTorah(),
zcal.getSofZmanShmaAteretTorah(), zcal.getSofZmanTfilaAteretTorah(),
zcal.getMinchaGedolaAteretTorah(), zcal.getMinchaKetanaAteretTorah(),
zcal.getPlagHaminchaAteretTorah(), zcal.getTzais72Zmanis(), zcal.getTzais90Zmanis(),
- zcal.getTzais96Zmanis(), zcal.getTzais90(), zcal.getTzais120(), zcal.getTzais120Zmanis(),
+ zcal.getTzais96Zmanis(), zcal.getTzais90Minutes(), zcal.getTzais120Minutes(), zcal.getTzais120Zmanis(),
zcal.getTzais16Point1Degrees(), zcal.getTzais26Degrees(), zcal.getTzais18Degrees(),
- zcal.getTzais19Point8Degrees(), zcal.getTzais96(), zcal.getFixedLocalChatzos(),
+ zcal.getTzais19Point8Degrees(), zcal.getTzais96Minutes(), zcal.getFixedLocalChatzosHayom(),
zcal.getSofZmanKidushLevanaBetweenMoldos(), zcal.getSofZmanKidushLevana15Days(),
zcal.getTchilasZmanKidushLevana3Days(), zcal.getZmanMolad(), zcal.getTchilasZmanKidushLevana7Days(),
zcal.getSofZmanAchilasChametzGRA(), zcal.getSofZmanAchilasChametzMGA72Minutes(),
@@ -103,7 +104,7 @@ public static void main(String[] args) throws IOException {
zcal.getSolarMidnight(), zcal.getShaahZmanisBaalHatanya(), zcal.getAlosBaalHatanya(),
zcal.getSofZmanShmaBaalHatanya(), zcal.getSofZmanTfilaBaalHatanya(),
zcal.getSofZmanAchilasChametzBaalHatanya(), zcal.getSofZmanBiurChametzBaalHatanya(),
- zcal.getMinchaGedolaBaalHatanya(), zcal.getMinchaGedolaBaalHatanyaGreaterThan30(),
+ zcal.getMinchaGedolaBaalHatanya(),
zcal.getMinchaKetanaBaalHatanya(), zcal.getPlagHaminchaBaalHatanya(), zcal.getTzaisBaalHatanya(),
zcal.getSofZmanShmaMGA18DegreesToFixedLocalChatzos(),
zcal.getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos(),
@@ -113,7 +114,7 @@ public static void main(String[] args) throws IOException {
zcal.getSofZmanTfilaGRASunriseToFixedLocalChatzos(),
zcal.getMinchaGedolaGRAFixedLocalChatzos30Minutes(),
zcal.getMinchaKetanaGRAFixedLocalChatzosToSunset(),
- zcal.getPlagHaminchaGRAFixedLocalChatzosToSunset(), zcal.getTzais50(),
+ zcal.getPlagHaminchaGRAFixedLocalChatzosToSunset(), zcal.getTzais50Minutes(),
zcal.getSamuchLeMinchaKetanaGRA(), zcal.getSamuchLeMinchaKetana16Point1Degrees(),
zcal.getSamuchLeMinchaKetana72Minutes()));
//deprecated
@@ -127,10 +128,10 @@ public static void main(String[] args) throws IOException {
cal.isMoridHatalRecited();*/
current = current.plusDays(1L);
- gregorian.roll(Calendar.DATE, true);
- date.forward(Calendar.DATE, 1);
- cal.setDate(current);
- zcal.setCalendar(gregorian);
+ gregorian = gregorian.plusDays(1);
+ date.plusDays(1);
+ cal.setGregorianDate(current);
+ zcal.setLocalDate(gregorian);
}
//write calendars to file:
@@ -156,7 +157,7 @@ public static void main(String[] args) throws IOException {
}
static class FullZmanim {
- public static final String fields = "getShaahZmanis19Point8Degrees,getShaahZmanis18Degrees,getShaahZmanis26Degrees,getShaahZmanis16Point1Degrees,getShaahZmanis60Minutes,getShaahZmanis72Minutes,getShaahZmanis72MinutesZmanis,getShaahZmanis90Minutes,getShaahZmanis90MinutesZmanis,getShaahZmanis96MinutesZmanis,getShaahZmanisAteretTorah,getShaahZmanisAlos16Point1ToTzais3Point8,getShaahZmanisAlos16Point1ToTzais3Point7,getShaahZmanis96Minutes,getShaahZmanis120Minutes,getShaahZmanis120MinutesZmanis,getPlagHamincha120MinutesZmanis,getPlagHamincha120Minutes,getAlos60,getAlos72Zmanis,getAlos96,getAlos90Zmanis,getAlos96Zmanis,getAlos90,getAlos120,getAlos120Zmanis,getAlos26Degrees,getAlos18Degrees,getAlos19Degrees,getAlos19Point8Degrees,getAlos16Point1Degrees,getMisheyakir11Point5Degrees,getMisheyakir11Degrees,getMisheyakir10Point2Degrees,getMisheyakir7Point65Degrees,getMisheyakir9Point5Degrees,getSofZmanShmaMGA19Point8Degrees,getSofZmanShmaMGA16Point1Degrees,getSofZmanShmaMGA18Degrees,getSofZmanShmaMGA72Minutes,getSofZmanShmaMGA72MinutesZmanis,getSofZmanShmaMGA90Minutes,getSofZmanShmaMGA90MinutesZmanis,getSofZmanShmaMGA96Minutes,getSofZmanShmaMGA96MinutesZmanis,getSofZmanShma3HoursBeforeChatzos,getSofZmanShmaMGA120Minutes,getSofZmanShmaAlos16Point1ToSunset,getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees,getSofZmanTfilaMGA19Point8Degrees,getSofZmanTfilaMGA16Point1Degrees,getSofZmanTfilaMGA18Degrees,getSofZmanTfilaMGA72Minutes,getSofZmanTfilaMGA72MinutesZmanis,getSofZmanTfilaMGA90Minutes,getSofZmanTfilaMGA90MinutesZmanis,getSofZmanTfilaMGA96Minutes,getSofZmanTfilaMGA96MinutesZmanis,getSofZmanTfilaMGA120Minutes,getSofZmanTfila2HoursBeforeChatzos,getMinchaGedola30Minutes,getMinchaGedola72Minutes,getMinchaGedola16Point1Degrees,getMinchaGedolaAhavatShalom,getMinchaGedolaGreaterThan30,getMinchaKetana16Point1Degrees,getMinchaKetanaAhavatShalom,getMinchaKetana72Minutes,getPlagHamincha60Minutes,getPlagHamincha72Minutes,getPlagHamincha90Minutes,getPlagHamincha96Minutes,getPlagHamincha96MinutesZmanis,getPlagHamincha90MinutesZmanis,getPlagHamincha72MinutesZmanis,getPlagHamincha16Point1Degrees,getPlagHamincha19Point8Degrees,getPlagHamincha26Degrees,getPlagHamincha18Degrees,getPlagAlosToSunset,getPlagAlos16Point1ToTzaisGeonim7Point083Degrees,getPlagAhavatShalom,getBainHashmashosRT58Point5Minutes,getBainHashmashosRT13Point5MinutesBefore7Point083Degrees,getBainHashmashosRT2Stars,getBainHashmashosYereim18Minutes,getBainHashmashosYereim3Point05Degrees,getBainHashmashosYereim16Point875Minutes,getBainHashmashosYereim2Point8Degrees,getBainHashmashosYereim13Point5Minutes,getBainHashmashosYereim2Point1Degrees,getTzaisGeonim3Point7Degrees,getTzaisGeonim3Point8Degrees,getTzaisGeonim5Point95Degrees,getTzaisGeonim4Point61Degrees,getTzaisGeonim4Point37Degrees,getTzaisGeonim5Point88Degrees,getTzaisGeonim4Point8Degrees,getTzaisGeonim6Point45Degrees,getTzaisGeonim7Point083Degrees,getTzaisGeonim7Point67Degrees,getTzaisGeonim8Point5Degrees,getTzaisGeonim9Point3Degrees,getTzaisGeonim9Point75Degrees,getTzais60,getTzaisAteretTorah,getSofZmanShmaAteretTorah,getSofZmanTfilahAteretTorah,getMinchaGedolaAteretTorah,getMinchaKetanaAteretTorah,getPlagHaminchaAteretTorah,getTzais72Zmanis,getTzais90Zmanis,getTzais96Zmanis,getTzais90,getTzais120,getTzais120Zmanis,getTzais16Point1Degrees,getTzais26Degrees,getTzais18Degrees,getTzais19Point8Degrees,getTzais96,getFixedLocalChatzos,getSofZmanKidushLevanaBetweenMoldos,getSofZmanKidushLevana15Days,getTchilasZmanKidushLevana3Days,getZmanMolad,getTchilasZmanKidushLevana7Days,getSofZmanAchilasChametzGRA,getSofZmanAchilasChametzMGA72Minutes,getSofZmanAchilasChametzMGA16Point1Degrees,getSofZmanBiurChametzGRA,getSofZmanBiurChametzMGA72Minutes,getSofZmanBiurChametzMGA16Point1Degrees,getSolarMidnight,getShaahZmanisBaalHatanya,getAlosBaalHatanya,getSofZmanShmaBaalHatanya,getSofZmanTfilaBaalHatanya,getSofZmanAchilasChametzBaalHatanya,getSofZmanBiurChametzBaalHatanya,getMinchaGedolaBaalHatanya,getMinchaGedolaBaalHatanyaGreaterThan30,getMinchaKetanaBaalHatanya,getPlagHaminchaBaalHatanya,getTzaisBaalHatanya,getSofZmanShmaMGA18DegreesToFixedLocalChatzos,getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos,getSofZmanShmaMGA90MinutesToFixedLocalChatzos,getSofZmanShmaMGA72MinutesToFixedLocalChatzos,getSofZmanShmaGRASunriseToFixedLocalChatzos,getSofZmanTfilaGRASunriseToFixedLocalChatzos,getMinchaGedolaGRAFixedLocalChatzos30Minutes,getMinchaKetanaGRAFixedLocalChatzosToSunset,getPlagHaminchaGRAFixedLocalChatzosToSunset,getTzais50,getSamuchLeMinchaKetanaGRA,getSamuchLeMinchaKetana16Point1Degrees,getSamuchLeMinchaKetana72Minutes";
+ public static final String fields = "getShaahZmanis19Point8Degrees,getShaahZmanis18Degrees,getShaahZmanis26Degrees,getShaahZmanis16Point1Degrees,getShaahZmanis60Minutes,getShaahZmanis72Minutes,getShaahZmanis72MinutesZmanis,getShaahZmanis90Minutes,getShaahZmanis90MinutesZmanis,getShaahZmanis96MinutesZmanis,getShaahZmanisAteretTorah,getShaahZmanisAlos16Point1ToTzais3Point8,getShaahZmanisAlos16Point1ToTzais3Point7,getShaahZmanis96Minutes,getShaahZmanis120Minutes,getShaahZmanis120MinutesZmanis,getPlagHamincha120MinutesZmanis,getPlagHamincha120Minutes,getAlos60,getAlos72Zmanis,getAlos96,getAlos90Zmanis,getAlos96Zmanis,getAlos90,getAlos120,getAlos120Zmanis,getAlos26Degrees,getAlos18Degrees,getAlos19Degrees,getAlos19Point8Degrees,getAlos16Point1Degrees,getMisheyakir11Point5Degrees,getMisheyakir11Degrees,getMisheyakir10Point2Degrees,getMisheyakir7Point65Degrees,getMisheyakir9Point5Degrees,getSofZmanShmaMGA19Point8Degrees,getSofZmanShmaMGA16Point1Degrees,getSofZmanShmaMGA18Degrees,getSofZmanShmaMGA72Minutes,getSofZmanShmaMGA72MinutesZmanis,getSofZmanShmaMGA90Minutes,getSofZmanShmaMGA90MinutesZmanis,getSofZmanShmaMGA96Minutes,getSofZmanShmaMGA96MinutesZmanis,getSofZmanShma3HoursBeforeChatzos,getSofZmanShmaMGA120Minutes,getSofZmanShmaAlos16Point1ToSunset,getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees,getSofZmanTfilaMGA19Point8Degrees,getSofZmanTfilaMGA16Point1Degrees,getSofZmanTfilaMGA18Degrees,getSofZmanTfilaMGA72Minutes,getSofZmanTfilaMGA72MinutesZmanis,getSofZmanTfilaMGA90Minutes,getSofZmanTfilaMGA90MinutesZmanis,getSofZmanTfilaMGA96Minutes,getSofZmanTfilaMGA96MinutesZmanis,getSofZmanTfilaMGA120Minutes,getSofZmanTfila2HoursBeforeChatzos,getMinchaGedola30Minutes,getMinchaGedola72Minutes,getMinchaGedola16Point1Degrees,getMinchaGedolaAhavatShalom,getMinchaGedolaGreaterThan30,getMinchaKetana16Point1Degrees,getMinchaKetanaAhavatShalom,getMinchaKetana72Minutes,getPlagHamincha60Minutes,getPlagHamincha72Minutes,getPlagHamincha90Minutes,getPlagHamincha96Minutes,getPlagHamincha96MinutesZmanis,getPlagHamincha90MinutesZmanis,getPlagHamincha72MinutesZmanis,getPlagHamincha16Point1Degrees,getPlagHamincha19Point8Degrees,getPlagHamincha26Degrees,getPlagHamincha18Degrees,getPlagAlosToSunset,getPlagAlos16Point1ToTzaisGeonim7Point083Degrees,getPlagAhavatShalom,getBainHashmashosRT58Point5Minutes,getBainHashmashosRT13Point5MinutesBefore7Point083Degrees,getBainHashmashosRT2Stars,getBainHashmashosYereim18Minutes,getBainHashmashosYereim3Point05Degrees,getBainHashmashosYereim16Point875Minutes,getBainHashmashosYereim2Point8Degrees,getBainHashmashosYereim13Point5Minutes,getBainHashmashosYereim2Point1Degrees,getTzaisGeonim3Point7Degrees,getTzaisGeonim3Point8Degrees,getTzaisGeonim5Point95Degrees,getTzaisGeonim4Point66Degrees,getTzaisGeonim4Point42Degrees,getTzaisGeonim4Point8Degrees,getTzaisGeonim6Point45Degrees,getTzaisGeonim7Point083Degrees,getTzaisGeonim7Point67Degrees,getTzaisGeonim8Point5Degrees,getTzaisGeonim9Point3Degrees,getTzaisGeonim9Point75Degrees,getTzais60,getTzaisAteretTorah,getSofZmanShmaAteretTorah,getSofZmanTfilahAteretTorah,getMinchaGedolaAteretTorah,getMinchaKetanaAteretTorah,getPlagHaminchaAteretTorah,getTzais72Zmanis,getTzais90Zmanis,getTzais96Zmanis,getTzais90,getTzais120,getTzais120Zmanis,getTzais16Point1Degrees,getTzais26Degrees,getTzais18Degrees,getTzais19Point8Degrees,getTzais96,getFixedLocalChatzosHayom,getSofZmanKidushLevanaBetweenMoldos,getSofZmanKidushLevana15Days,getTchilasZmanKidushLevana3Days,getZmanMolad,getTchilasZmanKidushLevana7Days,getSofZmanAchilasChametzGRA,getSofZmanAchilasChametzMGA72Minutes,getSofZmanAchilasChametzMGA16Point1Degrees,getSofZmanBiurChametzGRA,getSofZmanBiurChametzMGA72Minutes,getSofZmanBiurChametzMGA16Point1Degrees,getSolarMidnight,getShaahZmanisBaalHatanya,getAlosBaalHatanya,getSofZmanShmaBaalHatanya,getSofZmanTfilaBaalHatanya,getSofZmanAchilasChametzBaalHatanya,getSofZmanBiurChametzBaalHatanya,getMinchaGedolaBaalHatanya,getMinchaKetanaBaalHatanya,getPlagHaminchaBaalHatanya,getTzaisBaalHatanya,getSofZmanShmaMGA18DegreesToFixedLocalChatzos,getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos,getSofZmanShmaMGA90MinutesToFixedLocalChatzos,getSofZmanShmaMGA72MinutesToFixedLocalChatzos,getSofZmanShmaGRASunriseToFixedLocalChatzos,getSofZmanTfilaGRASunriseToFixedLocalChatzos,getMinchaGedolaGRAFixedLocalChatzos30Minutes,getMinchaKetanaGRAFixedLocalChatzosToSunset,getPlagHaminchaGRAFixedLocalChatzosToSunset,getTzais50,getSamuchLeMinchaKetanaGRA,getSamuchLeMinchaKetana16Point1Degrees,getSamuchLeMinchaKetana72Minutes";
@Override
public String toString() {
@@ -256,9 +257,8 @@ public String toString() {
.add(getTzaisGeonim3Point7Degrees.toString())
.add(getTzaisGeonim3Point8Degrees.toString())
.add(getTzaisGeonim5Point95Degrees.toString())
- .add(getTzaisGeonim4Point61Degrees.toString())
- .add(getTzaisGeonim4Point37Degrees.toString())
- .add(getTzaisGeonim5Point88Degrees.toString())
+ .add(getTzaisGeonim4Point66Degrees.toString())
+ .add(getTzaisGeonim4Point42Degrees.toString())
.add(getTzaisGeonim4Point8Degrees.toString())
.add(getTzaisGeonim6Point45Degrees.toString())
.add(getTzaisGeonim7Point083Degrees.toString())
@@ -284,7 +284,7 @@ public String toString() {
.add(getTzais18Degrees.toString())
.add(getTzais19Point8Degrees.toString())
.add(getTzais96.toString())
- .add(getFixedLocalChatzos.toString())
+ .add(getFixedLocalChatzosHayom.toString())
.add(getSofZmanKidushLevanaBetweenMoldos.toString())
.add(getSofZmanKidushLevana15Days.toString())
.add(getTchilasZmanKidushLevana3Days.toString())
@@ -304,7 +304,6 @@ public String toString() {
.add(getSofZmanAchilasChametzBaalHatanya.toString())
.add(getSofZmanBiurChametzBaalHatanya.toString())
.add(getMinchaGedolaBaalHatanya.toString())
- .add(getMinchaGedolaBaalHatanyaGreaterThan30.toString())
.add(getMinchaKetanaBaalHatanya.toString())
.add(getPlagHaminchaBaalHatanya.toString())
.add(getTzaisBaalHatanya.toString())
@@ -325,71 +324,71 @@ public String toString() {
}
public FullZmanim(long getShaahZmanis19Point8Degrees, long getShaahZmanis18Degrees,
- long getShaahZmanis26Degrees, long getShaahZmanis16Point1Degrees, long getShaahZmanis60Minutes,
- long getShaahZmanis72Minutes, long getShaahZmanis72MinutesZmanis, long getShaahZmanis90Minutes,
- long getShaahZmanis90MinutesZmanis, long getShaahZmanis96MinutesZmanis, long getShaahZmanisAteretTorah,
- long getShaahZmanisAlos16Point1ToTzais3Point8, long getShaahZmanisAlos16Point1ToTzais3Point7,
- long getShaahZmanis96Minutes, long getShaahZmanis120Minutes, long getShaahZmanis120MinutesZmanis,
- Date getPlagHamincha120MinutesZmanis, Date getPlagHamincha120Minutes, Date getAlos60,
- Date getAlos72Zmanis, Date getAlos96, Date getAlos90Zmanis, Date getAlos96Zmanis, Date getAlos90,
- Date getAlos120, Date getAlos120Zmanis, Date getAlos26Degrees, Date getAlos18Degrees,
- Date getAlos19Degrees, Date getAlos19Point8Degrees, Date getAlos16Point1Degrees,
- Date getMisheyakir11Point5Degrees, Date getMisheyakir11Degrees, Date getMisheyakir10Point2Degrees,
- Date getMisheyakir7Point65Degrees, Date getMisheyakir9Point5Degrees,
- Date getSofZmanShmaMGA19Point8Degrees, Date getSofZmanShmaMGA16Point1Degrees,
- Date getSofZmanShmaMGA18Degrees, Date getSofZmanShmaMGA72Minutes, Date getSofZmanShmaMGA72MinutesZmanis,
- Date getSofZmanShmaMGA90Minutes, Date getSofZmanShmaMGA90MinutesZmanis, Date getSofZmanShmaMGA96Minutes,
- Date getSofZmanShmaMGA96MinutesZmanis, Date getSofZmanShma3HoursBeforeChatzos,
- Date getSofZmanShmaMGA120Minutes, Date getSofZmanShmaAlos16Point1ToSunset,
- Date getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees,
- Date getSofZmanTfilaMGA19Point8Degrees, Date getSofZmanTfilaMGA16Point1Degrees,
- Date getSofZmanTfilaMGA18Degrees, Date getSofZmanTfilaMGA72Minutes,
- Date getSofZmanTfilaMGA72MinutesZmanis, Date getSofZmanTfilaMGA90Minutes,
- Date getSofZmanTfilaMGA90MinutesZmanis, Date getSofZmanTfilaMGA96Minutes,
- Date getSofZmanTfilaMGA96MinutesZmanis, Date getSofZmanTfilaMGA120Minutes,
- Date getSofZmanTfila2HoursBeforeChatzos, Date getMinchaGedola30Minutes, Date getMinchaGedola72Minutes,
- Date getMinchaGedola16Point1Degrees, Date getMinchaGedolaAhavatShalom,
- Date getMinchaGedolaGreaterThan30, Date getMinchaKetana16Point1Degrees,
- Date getMinchaKetanaAhavatShalom, Date getMinchaKetana72Minutes, Date getPlagHamincha60Minutes,
- Date getPlagHamincha72Minutes, Date getPlagHamincha90Minutes, Date getPlagHamincha96Minutes,
- Date getPlagHamincha96MinutesZmanis, Date getPlagHamincha90MinutesZmanis,
- Date getPlagHamincha72MinutesZmanis, Date getPlagHamincha16Point1Degrees,
- Date getPlagHamincha19Point8Degrees, Date getPlagHamincha26Degrees, Date getPlagHamincha18Degrees,
- Date getPlagAlosToSunset, Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees,
- Date getPlagAhavatShalom, Date getBainHashmashosRT13Point24Degrees,
- Date getBainHashmashosRT58Point5Minutes, Date getBainHashmashosRT13Point5MinutesBefore7Point083Degrees,
- Date getBainHashmashosRT2Stars, Date getBainHashmashosYereim18Minutes,
- Date getBainHashmashosYereim3Point05Degrees, Date getBainHashmashosYereim16Point875Minutes,
- Date getBainHashmashosYereim2Point8Degrees, Date getBainHashmashosYereim13Point5Minutes,
- Date getBainHashmashosYereim2Point1Degrees, Date getTzaisGeonim3Point7Degrees,
- Date getTzaisGeonim3Point8Degrees, Date getTzaisGeonim5Point95Degrees,
- Date getTzaisGeonim4Point61Degrees, Date getTzaisGeonim4Point37Degrees,
- Date getTzaisGeonim5Point88Degrees, Date getTzaisGeonim4Point8Degrees,
- Date getTzaisGeonim6Point45Degrees, Date getTzaisGeonim7Point083Degrees,
- Date getTzaisGeonim7Point67Degrees, Date getTzaisGeonim8Point5Degrees,
- Date getTzaisGeonim9Point3Degrees, Date getTzaisGeonim9Point75Degrees, Date getTzais60,
- Date getTzaisAteretTorah, Date getSofZmanShmaAteretTorah, Date getSofZmanTfilahAteretTorah,
- Date getMinchaGedolaAteretTorah, Date getMinchaKetanaAteretTorah, Date getPlagHaminchaAteretTorah,
- Date getTzais72Zmanis, Date getTzais90Zmanis, Date getTzais96Zmanis, Date getTzais90, Date getTzais120,
- Date getTzais120Zmanis, Date getTzais16Point1Degrees, Date getTzais26Degrees, Date getTzais18Degrees,
- Date getTzais19Point8Degrees, Date getTzais96, Date getFixedLocalChatzos,
- Date getSofZmanKidushLevanaBetweenMoldos,
- Date getSofZmanKidushLevana15Days, Date getTchilasZmanKidushLevana3Days, Date getZmanMolad,
- Date getTchilasZmanKidushLevana7Days, Date getSofZmanAchilasChametzGRA,
- Date getSofZmanAchilasChametzMGA72Minutes, Date getSofZmanAchilasChametzMGA16Point1Degrees,
- Date getSofZmanBiurChametzGRA, Date getSofZmanBiurChametzMGA72Minutes,
- Date getSofZmanBiurChametzMGA16Point1Degrees, Date getSolarMidnight, long getShaahZmanisBaalHatanya,
- Date getAlosBaalHatanya, Date getSofZmanShmaBaalHatanya, Date getSofZmanTfilaBaalHatanya,
- Date getSofZmanAchilasChametzBaalHatanya, Date getSofZmanBiurChametzBaalHatanya,
- Date getMinchaGedolaBaalHatanya, Date getMinchaGedolaBaalHatanyaGreaterThan30,
- Date getMinchaKetanaBaalHatanya, Date getPlagHaminchaBaalHatanya, Date getTzaisBaalHatanya,
- Date getSofZmanShmaMGA18DegreesToFixedLocalChatzos,
- Date getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos,
- Date getSofZmanShmaMGA90MinutesToFixedLocalChatzos, Date getSofZmanShmaMGA72MinutesToFixedLocalChatzos,
- Date getSofZmanShmaGRASunriseToFixedLocalChatzos, Date getSofZmanTfilaGRASunriseToFixedLocalChatzos,
- Date getMinchaGedolaGRAFixedLocalChatzos30Minutes, Date getMinchaKetanaGRAFixedLocalChatzosToSunset,
- Date getPlagHaminchaGRAFixedLocalChatzosToSunset, Date getTzais50, Date getSamuchLeMinchaKetanaGRA,
- Date getSamuchLeMinchaKetana16Point1Degrees, Date getSamuchLeMinchaKetana72Minutes) {
+ long getShaahZmanis26Degrees, long getShaahZmanis16Point1Degrees, long getShaahZmanis60Minutes,
+ long getShaahZmanis72Minutes, long getShaahZmanis72MinutesZmanis, long getShaahZmanis90Minutes,
+ long getShaahZmanis90MinutesZmanis, long getShaahZmanis96MinutesZmanis, long getShaahZmanisAteretTorah,
+ long getShaahZmanisAlos16Point1ToTzais3Point8, long getShaahZmanisAlos16Point1ToTzais3Point7,
+ long getShaahZmanis96Minutes, long getShaahZmanis120Minutes, long getShaahZmanis120MinutesZmanis,
+ Instant getPlagHamincha120MinutesZmanis, Instant getPlagHamincha120Minutes, Instant getAlos60,
+ Instant getAlos72Zmanis, Instant getAlos96, Instant getAlos90Zmanis, Instant getAlos96Zmanis, Instant getAlos90,
+ Instant getAlos120, Instant getAlos120Zmanis, Instant getAlos26Degrees, Instant getAlos18Degrees,
+ Instant getAlos19Degrees, Instant getAlos19Point8Degrees, Instant getAlos16Point1Degrees,
+ Instant getMisheyakir11Point5Degrees, Instant getMisheyakir11Degrees, Instant getMisheyakir10Point2Degrees,
+ Instant getMisheyakir7Point65Degrees, Instant getMisheyakir9Point5Degrees,
+ Instant getSofZmanShmaMGA19Point8Degrees, Instant getSofZmanShmaMGA16Point1Degrees,
+ Instant getSofZmanShmaMGA18Degrees, Instant getSofZmanShmaMGA72Minutes, Instant getSofZmanShmaMGA72MinutesZmanis,
+ Instant getSofZmanShmaMGA90Minutes, Instant getSofZmanShmaMGA90MinutesZmanis, Instant getSofZmanShmaMGA96Minutes,
+ Instant getSofZmanShmaMGA96MinutesZmanis, Instant getSofZmanShma3HoursBeforeChatzos,
+ Instant getSofZmanShmaMGA120Minutes, Instant getSofZmanShmaAlos16Point1ToSunset,
+ Instant getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees,
+ Instant getSofZmanTfilaMGA19Point8Degrees, Instant getSofZmanTfilaMGA16Point1Degrees,
+ Instant getSofZmanTfilaMGA18Degrees, Instant getSofZmanTfilaMGA72Minutes,
+ Instant getSofZmanTfilaMGA72MinutesZmanis, Instant getSofZmanTfilaMGA90Minutes,
+ Instant getSofZmanTfilaMGA90MinutesZmanis, Instant getSofZmanTfilaMGA96Minutes,
+ Instant getSofZmanTfilaMGA96MinutesZmanis, Instant getSofZmanTfilaMGA120Minutes,
+ Instant getSofZmanTfila2HoursBeforeChatzos, Instant getMinchaGedola30Minutes, Instant getMinchaGedola72Minutes,
+ Instant getMinchaGedola16Point1Degrees, Instant getMinchaGedolaAhavatShalom,
+ Instant getMinchaGedolaGreaterThan30, Instant getMinchaKetana16Point1Degrees,
+ Instant getMinchaKetanaAhavatShalom, Instant getMinchaKetana72Minutes, Instant getPlagHamincha60Minutes,
+ Instant getPlagHamincha72Minutes, Instant getPlagHamincha90Minutes, Instant getPlagHamincha96Minutes,
+ Instant getPlagHamincha96MinutesZmanis, Instant getPlagHamincha90MinutesZmanis,
+ Instant getPlagHamincha72MinutesZmanis, Instant getPlagHamincha16Point1Degrees,
+ Instant getPlagHamincha19Point8Degrees, Instant getPlagHamincha26Degrees, Instant getPlagHamincha18Degrees,
+ Instant getPlagAlosToSunset, Instant getPlagAlos16Point1ToTzaisGeonim7Point083Degrees,
+ Instant getPlagAhavatShalom, Instant getBainHashmashosRT13Point24Degrees,
+ Instant getBainHashmashosRT58Point5Minutes, Instant getBainHashmashosRT13Point5MinutesBefore7Point083Degrees,
+ Instant getBainHashmashosRT2Stars, Instant getBainHashmashosYereim18Minutes,
+ Instant getBainHashmashosYereim3Point05Degrees, Instant getBainHashmashosYereim16Point875Minutes,
+ Instant getBainHashmashosYereim2Point8Degrees, Instant getBainHashmashosYereim13Point5Minutes,
+ Instant getBainHashmashosYereim2Point1Degrees, Instant getTzaisGeonim3Point7Degrees,
+ Instant getTzaisGeonim3Point8Degrees, Instant getTzaisGeonim5Point95Degrees,
+ Instant getTzaisGeonim4Point66Degrees, Instant getTzaisGeonim4Point42Degrees,
+ Instant getTzaisGeonim4Point8Degrees,
+ Instant getTzaisGeonim6Point45Degrees, Instant getTzaisGeonim7Point083Degrees,
+ Instant getTzaisGeonim7Point67Degrees, Instant getTzaisGeonim8Point5Degrees,
+ Instant getTzaisGeonim9Point3Degrees, Instant getTzaisGeonim9Point75Degrees, Instant getTzais60,
+ Instant getTzaisAteretTorah, Instant getSofZmanShmaAteretTorah, Instant getSofZmanTfilahAteretTorah,
+ Instant getMinchaGedolaAteretTorah, Instant getMinchaKetanaAteretTorah, Instant getPlagHaminchaAteretTorah,
+ Instant getTzais72Zmanis, Instant getTzais90Zmanis, Instant getTzais96Zmanis, Instant getTzais90, Instant getTzais120,
+ Instant getTzais120Zmanis, Instant getTzais16Point1Degrees, Instant getTzais26Degrees, Instant getTzais18Degrees,
+ Instant getTzais19Point8Degrees, Instant getTzais96, Instant getFixedLocalChatzosHayom,
+ Instant getSofZmanKidushLevanaBetweenMoldos,
+ Instant getSofZmanKidushLevana15Days, Instant getTchilasZmanKidushLevana3Days, Instant getZmanMolad,
+ Instant getTchilasZmanKidushLevana7Days, Instant getSofZmanAchilasChametzGRA,
+ Instant getSofZmanAchilasChametzMGA72Minutes, Instant getSofZmanAchilasChametzMGA16Point1Degrees,
+ Instant getSofZmanBiurChametzGRA, Instant getSofZmanBiurChametzMGA72Minutes,
+ Instant getSofZmanBiurChametzMGA16Point1Degrees, Instant getSolarMidnight, long getShaahZmanisBaalHatanya,
+ Instant getAlosBaalHatanya, Instant getSofZmanShmaBaalHatanya, Instant getSofZmanTfilaBaalHatanya,
+ Instant getSofZmanAchilasChametzBaalHatanya, Instant getSofZmanBiurChametzBaalHatanya,
+ Instant getMinchaGedolaBaalHatanya,
+ Instant getMinchaKetanaBaalHatanya, Instant getPlagHaminchaBaalHatanya, Instant getTzaisBaalHatanya,
+ Instant getSofZmanShmaMGA18DegreesToFixedLocalChatzos,
+ Instant getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos,
+ Instant getSofZmanShmaMGA90MinutesToFixedLocalChatzos, Instant getSofZmanShmaMGA72MinutesToFixedLocalChatzos,
+ Instant getSofZmanShmaGRASunriseToFixedLocalChatzos, Instant getSofZmanTfilaGRASunriseToFixedLocalChatzos,
+ Instant getMinchaGedolaGRAFixedLocalChatzos30Minutes, Instant getMinchaKetanaGRAFixedLocalChatzosToSunset,
+ Instant getPlagHaminchaGRAFixedLocalChatzosToSunset, Instant getTzais50, Instant getSamuchLeMinchaKetanaGRA,
+ Instant getSamuchLeMinchaKetana16Point1Degrees, Instant getSamuchLeMinchaKetana72Minutes) {
this.getShaahZmanis19Point8Degrees = getShaahZmanis19Point8Degrees;
this.getShaahZmanis18Degrees = getShaahZmanis18Degrees;
this.getShaahZmanis26Degrees = getShaahZmanis26Degrees;
@@ -485,9 +484,8 @@ public FullZmanim(long getShaahZmanis19Point8Degrees, long getShaahZmanis18Degre
this.getTzaisGeonim3Point7Degrees = getTzaisGeonim3Point7Degrees;
this.getTzaisGeonim3Point8Degrees = getTzaisGeonim3Point8Degrees;
this.getTzaisGeonim5Point95Degrees = getTzaisGeonim5Point95Degrees;
- this.getTzaisGeonim4Point61Degrees = getTzaisGeonim4Point61Degrees;
- this.getTzaisGeonim4Point37Degrees = getTzaisGeonim4Point37Degrees;
- this.getTzaisGeonim5Point88Degrees = getTzaisGeonim5Point88Degrees;
+ this.getTzaisGeonim4Point66Degrees = getTzaisGeonim4Point66Degrees;
+ this.getTzaisGeonim4Point42Degrees = getTzaisGeonim4Point42Degrees;
this.getTzaisGeonim4Point8Degrees = getTzaisGeonim4Point8Degrees;
this.getTzaisGeonim6Point45Degrees = getTzaisGeonim6Point45Degrees;
this.getTzaisGeonim7Point083Degrees = getTzaisGeonim7Point083Degrees;
@@ -513,7 +511,7 @@ public FullZmanim(long getShaahZmanis19Point8Degrees, long getShaahZmanis18Degre
this.getTzais18Degrees = getTzais18Degrees;
this.getTzais19Point8Degrees = getTzais19Point8Degrees;
this.getTzais96 = getTzais96;
- this.getFixedLocalChatzos = getFixedLocalChatzos;
+ this.getFixedLocalChatzosHayom = getFixedLocalChatzosHayom;
this.getSofZmanKidushLevanaBetweenMoldos = getSofZmanKidushLevanaBetweenMoldos;
this.getSofZmanKidushLevana15Days = getSofZmanKidushLevana15Days;
this.getTchilasZmanKidushLevana3Days = getTchilasZmanKidushLevana3Days;
@@ -533,7 +531,6 @@ public FullZmanim(long getShaahZmanis19Point8Degrees, long getShaahZmanis18Degre
this.getSofZmanAchilasChametzBaalHatanya = getSofZmanAchilasChametzBaalHatanya;
this.getSofZmanBiurChametzBaalHatanya = getSofZmanBiurChametzBaalHatanya;
this.getMinchaGedolaBaalHatanya = getMinchaGedolaBaalHatanya;
- this.getMinchaGedolaBaalHatanyaGreaterThan30 = getMinchaGedolaBaalHatanyaGreaterThan30;
this.getMinchaKetanaBaalHatanya = getMinchaKetanaBaalHatanya;
this.getPlagHaminchaBaalHatanya = getPlagHaminchaBaalHatanya;
this.getTzaisBaalHatanya = getTzaisBaalHatanya;
@@ -568,176 +565,174 @@ public FullZmanim(long getShaahZmanis19Point8Degrees, long getShaahZmanis18Degre
public final long getShaahZmanis96Minutes;
public final long getShaahZmanis120Minutes;
public final long getShaahZmanis120MinutesZmanis;
- public final Date getPlagHamincha120MinutesZmanis;
- public final Date getPlagHamincha120Minutes;
- public final Date getAlos60;
- public final Date getAlos72Zmanis;
- public final Date getAlos96;
- public final Date getAlos90Zmanis;
- public final Date getAlos96Zmanis;
- public final Date getAlos90;
- public final Date getAlos120;
- public final Date getAlos120Zmanis;
- public final Date getAlos26Degrees;
- public final Date getAlos18Degrees;
- public final Date getAlos19Degrees;
- public final Date getAlos19Point8Degrees;
- public final Date getAlos16Point1Degrees;
- public final Date getMisheyakir11Point5Degrees;
- public final Date getMisheyakir11Degrees;
- public final Date getMisheyakir10Point2Degrees;
- public final Date getMisheyakir7Point65Degrees;
- public final Date getMisheyakir9Point5Degrees;
- public final Date getSofZmanShmaMGA19Point8Degrees;
- public final Date getSofZmanShmaMGA16Point1Degrees;
- public final Date getSofZmanShmaMGA18Degrees;
- public final Date getSofZmanShmaMGA72Minutes;
- public final Date getSofZmanShmaMGA72MinutesZmanis;
- public final Date getSofZmanShmaMGA90Minutes;
- public final Date getSofZmanShmaMGA90MinutesZmanis;
- public final Date getSofZmanShmaMGA96Minutes;
- public final Date getSofZmanShmaMGA96MinutesZmanis;
- public final Date getSofZmanShma3HoursBeforeChatzos;
- public final Date getSofZmanShmaMGA120Minutes;
- public final Date getSofZmanShmaAlos16Point1ToSunset;
- public final Date getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees;
- public final Date getSofZmanTfilaMGA19Point8Degrees;
- public final Date getSofZmanTfilaMGA16Point1Degrees;
- public final Date getSofZmanTfilaMGA18Degrees;
- public final Date getSofZmanTfilaMGA72Minutes;
- public final Date getSofZmanTfilaMGA72MinutesZmanis;
- public final Date getSofZmanTfilaMGA90Minutes;
- public final Date getSofZmanTfilaMGA90MinutesZmanis;
- public final Date getSofZmanTfilaMGA96Minutes;
- public final Date getSofZmanTfilaMGA96MinutesZmanis;
- public final Date getSofZmanTfilaMGA120Minutes;
- public final Date getSofZmanTfila2HoursBeforeChatzos;
- public final Date getMinchaGedola30Minutes;
- public final Date getMinchaGedola72Minutes;
- public final Date getMinchaGedola16Point1Degrees;
- public final Date getMinchaGedolaAhavatShalom;
- public final Date getMinchaGedolaGreaterThan30;
- public final Date getMinchaKetana16Point1Degrees;
- public final Date getMinchaKetanaAhavatShalom;
- public final Date getMinchaKetana72Minutes;
- public final Date getPlagHamincha60Minutes;
- public final Date getPlagHamincha72Minutes;
- public final Date getPlagHamincha90Minutes;
- public final Date getPlagHamincha96Minutes;
- public final Date getPlagHamincha96MinutesZmanis;
- public final Date getPlagHamincha90MinutesZmanis;
- public final Date getPlagHamincha72MinutesZmanis;
- public final Date getPlagHamincha16Point1Degrees;
- public final Date getPlagHamincha19Point8Degrees;
- public final Date getPlagHamincha26Degrees;
- public final Date getPlagHamincha18Degrees;
- public final Date getPlagAlosToSunset;
- public final Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees;
- public final Date getPlagAhavatShalom;
- public final Date getBainHashmashosRT13Point24Degrees;
- public final Date getBainHashmashosRT58Point5Minutes;
- public final Date getBainHashmashosRT13Point5MinutesBefore7Point083Degrees;
- public final Date getBainHashmashosRT2Stars;
- public final Date getBainHashmashosYereim18Minutes;
- public final Date getBainHashmashosYereim3Point05Degrees;
- public final Date getBainHashmashosYereim16Point875Minutes;
- public final Date getBainHashmashosYereim2Point8Degrees;
- public final Date getBainHashmashosYereim13Point5Minutes;
- public final Date getBainHashmashosYereim2Point1Degrees;
- public final Date getTzaisGeonim3Point7Degrees;
- public final Date getTzaisGeonim3Point8Degrees;
- public final Date getTzaisGeonim5Point95Degrees;
- public final Date getTzaisGeonim4Point61Degrees;
- public final Date getTzaisGeonim4Point37Degrees;
- public final Date getTzaisGeonim5Point88Degrees;
- public final Date getTzaisGeonim4Point8Degrees;
- public final Date getTzaisGeonim6Point45Degrees;
- public final Date getTzaisGeonim7Point083Degrees;
- public final Date getTzaisGeonim7Point67Degrees;
- public final Date getTzaisGeonim8Point5Degrees;
- public final Date getTzaisGeonim9Point3Degrees;
- public final Date getTzaisGeonim9Point75Degrees;
- public final Date getTzais60;
- public final Date getTzaisAteretTorah;
- public final Date getSofZmanShmaAteretTorah;
- public final Date getSofZmanTfilahAteretTorah;
- public final Date getMinchaGedolaAteretTorah;
- public final Date getMinchaKetanaAteretTorah;
- public final Date getPlagHaminchaAteretTorah;
- public final Date getTzais72Zmanis;
- public final Date getTzais90Zmanis;
- public final Date getTzais96Zmanis;
- public final Date getTzais90;
- public final Date getTzais120;
- public final Date getTzais120Zmanis;
- public final Date getTzais16Point1Degrees;
- public final Date getTzais26Degrees;
- public final Date getTzais18Degrees;
- public final Date getTzais19Point8Degrees;
- public final Date getTzais96;
- public final Date getFixedLocalChatzos;
- public final Date getSofZmanKidushLevanaBetweenMoldos;
- public final Date getSofZmanKidushLevana15Days;
- public final Date getTchilasZmanKidushLevana3Days;
- public final Date getZmanMolad;
- public final Date getTchilasZmanKidushLevana7Days;
- public final Date getSofZmanAchilasChametzGRA;
- public final Date getSofZmanAchilasChametzMGA72Minutes;
- public final Date getSofZmanAchilasChametzMGA16Point1Degrees;
- public final Date getSofZmanBiurChametzGRA;
- public final Date getSofZmanBiurChametzMGA72Minutes;
- public final Date getSofZmanBiurChametzMGA16Point1Degrees;
- public final Date getSolarMidnight;
+ public final Instant getPlagHamincha120MinutesZmanis;
+ public final Instant getPlagHamincha120Minutes;
+ public final Instant getAlos60;
+ public final Instant getAlos72Zmanis;
+ public final Instant getAlos96;
+ public final Instant getAlos90Zmanis;
+ public final Instant getAlos96Zmanis;
+ public final Instant getAlos90;
+ public final Instant getAlos120;
+ public final Instant getAlos120Zmanis;
+ public final Instant getAlos26Degrees;
+ public final Instant getAlos18Degrees;
+ public final Instant getAlos19Degrees;
+ public final Instant getAlos19Point8Degrees;
+ public final Instant getAlos16Point1Degrees;
+ public final Instant getMisheyakir11Point5Degrees;
+ public final Instant getMisheyakir11Degrees;
+ public final Instant getMisheyakir10Point2Degrees;
+ public final Instant getMisheyakir7Point65Degrees;
+ public final Instant getMisheyakir9Point5Degrees;
+ public final Instant getSofZmanShmaMGA19Point8Degrees;
+ public final Instant getSofZmanShmaMGA16Point1Degrees;
+ public final Instant getSofZmanShmaMGA18Degrees;
+ public final Instant getSofZmanShmaMGA72Minutes;
+ public final Instant getSofZmanShmaMGA72MinutesZmanis;
+ public final Instant getSofZmanShmaMGA90Minutes;
+ public final Instant getSofZmanShmaMGA90MinutesZmanis;
+ public final Instant getSofZmanShmaMGA96Minutes;
+ public final Instant getSofZmanShmaMGA96MinutesZmanis;
+ public final Instant getSofZmanShma3HoursBeforeChatzos;
+ public final Instant getSofZmanShmaMGA120Minutes;
+ public final Instant getSofZmanShmaAlos16Point1ToSunset;
+ public final Instant getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees;
+ public final Instant getSofZmanTfilaMGA19Point8Degrees;
+ public final Instant getSofZmanTfilaMGA16Point1Degrees;
+ public final Instant getSofZmanTfilaMGA18Degrees;
+ public final Instant getSofZmanTfilaMGA72Minutes;
+ public final Instant getSofZmanTfilaMGA72MinutesZmanis;
+ public final Instant getSofZmanTfilaMGA90Minutes;
+ public final Instant getSofZmanTfilaMGA90MinutesZmanis;
+ public final Instant getSofZmanTfilaMGA96Minutes;
+ public final Instant getSofZmanTfilaMGA96MinutesZmanis;
+ public final Instant getSofZmanTfilaMGA120Minutes;
+ public final Instant getSofZmanTfila2HoursBeforeChatzos;
+ public final Instant getMinchaGedola30Minutes;
+ public final Instant getMinchaGedola72Minutes;
+ public final Instant getMinchaGedola16Point1Degrees;
+ public final Instant getMinchaGedolaAhavatShalom;
+ public final Instant getMinchaGedolaGreaterThan30;
+ public final Instant getMinchaKetana16Point1Degrees;
+ public final Instant getMinchaKetanaAhavatShalom;
+ public final Instant getMinchaKetana72Minutes;
+ public final Instant getPlagHamincha60Minutes;
+ public final Instant getPlagHamincha72Minutes;
+ public final Instant getPlagHamincha90Minutes;
+ public final Instant getPlagHamincha96Minutes;
+ public final Instant getPlagHamincha96MinutesZmanis;
+ public final Instant getPlagHamincha90MinutesZmanis;
+ public final Instant getPlagHamincha72MinutesZmanis;
+ public final Instant getPlagHamincha16Point1Degrees;
+ public final Instant getPlagHamincha19Point8Degrees;
+ public final Instant getPlagHamincha26Degrees;
+ public final Instant getPlagHamincha18Degrees;
+ public final Instant getPlagAlosToSunset;
+ public final Instant getPlagAlos16Point1ToTzaisGeonim7Point083Degrees;
+ public final Instant getPlagAhavatShalom;
+ public final Instant getBainHashmashosRT13Point24Degrees;
+ public final Instant getBainHashmashosRT58Point5Minutes;
+ public final Instant getBainHashmashosRT13Point5MinutesBefore7Point083Degrees;
+ public final Instant getBainHashmashosRT2Stars;
+ public final Instant getBainHashmashosYereim18Minutes;
+ public final Instant getBainHashmashosYereim3Point05Degrees;
+ public final Instant getBainHashmashosYereim16Point875Minutes;
+ public final Instant getBainHashmashosYereim2Point8Degrees;
+ public final Instant getBainHashmashosYereim13Point5Minutes;
+ public final Instant getBainHashmashosYereim2Point1Degrees;
+ public final Instant getTzaisGeonim3Point7Degrees;
+ public final Instant getTzaisGeonim3Point8Degrees;
+ public final Instant getTzaisGeonim5Point95Degrees;
+ public final Instant getTzaisGeonim4Point66Degrees;
+ public final Instant getTzaisGeonim4Point42Degrees;
+ public final Instant getTzaisGeonim4Point8Degrees;
+ public final Instant getTzaisGeonim6Point45Degrees;
+ public final Instant getTzaisGeonim7Point083Degrees;
+ public final Instant getTzaisGeonim7Point67Degrees;
+ public final Instant getTzaisGeonim8Point5Degrees;
+ public final Instant getTzaisGeonim9Point3Degrees;
+ public final Instant getTzaisGeonim9Point75Degrees;
+ public final Instant getTzais60;
+ public final Instant getTzaisAteretTorah;
+ public final Instant getSofZmanShmaAteretTorah;
+ public final Instant getSofZmanTfilahAteretTorah;
+ public final Instant getMinchaGedolaAteretTorah;
+ public final Instant getMinchaKetanaAteretTorah;
+ public final Instant getPlagHaminchaAteretTorah;
+ public final Instant getTzais72Zmanis;
+ public final Instant getTzais90Zmanis;
+ public final Instant getTzais96Zmanis;
+ public final Instant getTzais90;
+ public final Instant getTzais120;
+ public final Instant getTzais120Zmanis;
+ public final Instant getTzais16Point1Degrees;
+ public final Instant getTzais26Degrees;
+ public final Instant getTzais18Degrees;
+ public final Instant getTzais19Point8Degrees;
+ public final Instant getTzais96;
+ public final Instant getFixedLocalChatzosHayom;
+ public final Instant getSofZmanKidushLevanaBetweenMoldos;
+ public final Instant getSofZmanKidushLevana15Days;
+ public final Instant getTchilasZmanKidushLevana3Days;
+ public final Instant getZmanMolad;
+ public final Instant getTchilasZmanKidushLevana7Days;
+ public final Instant getSofZmanAchilasChametzGRA;
+ public final Instant getSofZmanAchilasChametzMGA72Minutes;
+ public final Instant getSofZmanAchilasChametzMGA16Point1Degrees;
+ public final Instant getSofZmanBiurChametzGRA;
+ public final Instant getSofZmanBiurChametzMGA72Minutes;
+ public final Instant getSofZmanBiurChametzMGA16Point1Degrees;
+ public final Instant getSolarMidnight;
public final long getShaahZmanisBaalHatanya;
- public final Date getAlosBaalHatanya;
- public final Date getSofZmanShmaBaalHatanya;
- public final Date getSofZmanTfilaBaalHatanya;
- public final Date getSofZmanAchilasChametzBaalHatanya;
- public final Date getSofZmanBiurChametzBaalHatanya;
- public final Date getMinchaGedolaBaalHatanya;
- public final Date getMinchaGedolaBaalHatanyaGreaterThan30;
- public final Date getMinchaKetanaBaalHatanya;
- public final Date getPlagHaminchaBaalHatanya;
- public final Date getTzaisBaalHatanya;
- public final Date getSofZmanShmaMGA18DegreesToFixedLocalChatzos;
- public final Date getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos;
- public final Date getSofZmanShmaMGA90MinutesToFixedLocalChatzos;
- public final Date getSofZmanShmaMGA72MinutesToFixedLocalChatzos;
- public final Date getSofZmanShmaGRASunriseToFixedLocalChatzos;
- public final Date getSofZmanTfilaGRASunriseToFixedLocalChatzos;
- public final Date getMinchaGedolaGRAFixedLocalChatzos30Minutes;
- public final Date getMinchaKetanaGRAFixedLocalChatzosToSunset;
- public final Date getPlagHaminchaGRAFixedLocalChatzosToSunset;
- public final Date getTzais50;
- public final Date getSamuchLeMinchaKetanaGRA;
- public final Date getSamuchLeMinchaKetana16Point1Degrees;
- public final Date getSamuchLeMinchaKetana72Minutes;
+ public final Instant getAlosBaalHatanya;
+ public final Instant getSofZmanShmaBaalHatanya;
+ public final Instant getSofZmanTfilaBaalHatanya;
+ public final Instant getSofZmanAchilasChametzBaalHatanya;
+ public final Instant getSofZmanBiurChametzBaalHatanya;
+ public final Instant getMinchaGedolaBaalHatanya;
+ public final Instant getMinchaKetanaBaalHatanya;
+ public final Instant getPlagHaminchaBaalHatanya;
+ public final Instant getTzaisBaalHatanya;
+ public final Instant getSofZmanShmaMGA18DegreesToFixedLocalChatzos;
+ public final Instant getSofZmanShmaMGA16Point1DegreesToFixedLocalChatzos;
+ public final Instant getSofZmanShmaMGA90MinutesToFixedLocalChatzos;
+ public final Instant getSofZmanShmaMGA72MinutesToFixedLocalChatzos;
+ public final Instant getSofZmanShmaGRASunriseToFixedLocalChatzos;
+ public final Instant getSofZmanTfilaGRASunriseToFixedLocalChatzos;
+ public final Instant getMinchaGedolaGRAFixedLocalChatzos30Minutes;
+ public final Instant getMinchaKetanaGRAFixedLocalChatzosToSunset;
+ public final Instant getPlagHaminchaGRAFixedLocalChatzosToSunset;
+ public final Instant getTzais50;
+ public final Instant getSamuchLeMinchaKetanaGRA;
+ public final Instant getSamuchLeMinchaKetana16Point1Degrees;
+ public final Instant getSamuchLeMinchaKetana72Minutes;
}
/*static class FullAstronomicalCalculator {
- Date getSunrise
- Date getSeaLevelSunrise
- Date getBeginCivilTwilight
- Date getBeginNauticalTwilight
- Date getBeginAstronomicalTwilight
- Date getSunset
- Date getSeaLevelSunset
- Date getEndCivilTwilight
- Date getEndNauticalTwilight
- Date getEndAstronomicalTwilight
- Date getTimeOffset
- Date getTimeOffset
- Date getSunriseOffsetByDegrees
- Date getSunsetOffsetByDegrees
+ Instant getSunrise
+ Instant getSeaLevelSunrise
+ Instant getBeginCivilTwilight
+ Instant getBeginNauticalTwilight
+ Instant getBeginAstronomicalTwilight
+ Instant getSunset
+ Instant getSeaLevelSunset
+ Instant getEndCivilTwilight
+ Instant getEndNauticalTwilight
+ Instant getEndAstronomicalTwilight
+ Instant getTimeOffset
+ Instant getTimeOffset
+ Instant getSunriseOffsetByDegrees
+ Instant getSunsetOffsetByDegrees
double getUTCSunrise
double getUTCSeaLevelSunrise
double getUTCSunset
double getUTCSeaLevelSunset
long getTemporalHour
long getTemporalHour
- Date getSunTransit
- Date getSunTransit
- Date getDateFromTime
+ Instant getSunTransit
+ Instant getSunTransit
+ Instant getDateFromTime
double getSunriseSolarDipFromOffset
double getSunsetSolarDipFromOffset
Calendar getAdjustedCalendar
@@ -848,14 +843,14 @@ public String toString() {
private final int dayOfOmer;
private final boolean tishaBav;
private final JewishDate molad;
- private final Date moladAsDate;
- private final Date tchilasZmanKidushLevana3Days;
- private final Date tchilasZmanKidushLevana7Days;
- private final Date sofZmanKidushLevanaBetweenMoldos;
- private final Date sofZmanKidushLevana15Days;
+ private final Instant moladAsDate;
+ private final Instant tchilasZmanKidushLevana3Days;
+ private final Instant tchilasZmanKidushLevana7Days;
+ private final Instant sofZmanKidushLevanaBetweenMoldos;
+ private final Instant sofZmanKidushLevana15Days;
private final int tekufasTishreiElapsedDays;
- public FullCalendar(LocalDate current, JewishDate currentJewishDate, int yomTovIndex, Daf dafYomiBavli, Daf dafYomiYerushalmi, boolean isruChag, boolean birkasHachamah, JewishCalendar.Parsha parshah, JewishCalendar.Parsha upcomingParshah, JewishCalendar.Parsha specialShabbos, boolean yomTov, boolean yomTovAssurBemelacha, boolean assurBemelacha, boolean hasCandleLighting, boolean tomorrowShabbosOrYomTov, boolean erevYomTovSheni, boolean aseresYemeiTeshuva, boolean pesach, boolean cholHamoedPesach, boolean shavuos, boolean roshHashana, boolean yomKippur, boolean succos, boolean hoshanaRabba, boolean shminiAtzeres, boolean simchasTorah, boolean cholHamoedSuccos, boolean cholHamoed, boolean erevYomTov, boolean erevRoshChodesh, boolean yomKippurKatan, boolean beHaB, boolean taanis, boolean taanisBechoros, int dayOfChanukah, boolean chanukah, boolean purim, boolean roshChodesh, boolean macharChodesh, boolean shabbosMevorchim, int dayOfOmer, boolean tishaBav, JewishDate molad, Date moladAsDate, Date tchilasZmanKidushLevana3Days, Date tchilasZmanKidushLevana7Days, Date sofZmanKidushLevanaBetweenMoldos, Date sofZmanKidushLevana15Days, int tekufasTishreiElapsedDays) {
+ public FullCalendar(LocalDate current, JewishDate currentJewishDate, int yomTovIndex, Daf dafYomiBavli, Daf dafYomiYerushalmi, boolean isruChag, boolean birkasHachamah, JewishCalendar.Parsha parshah, JewishCalendar.Parsha upcomingParshah, JewishCalendar.Parsha specialShabbos, boolean yomTov, boolean yomTovAssurBemelacha, boolean assurBemelacha, boolean hasCandleLighting, boolean tomorrowShabbosOrYomTov, boolean erevYomTovSheni, boolean aseresYemeiTeshuva, boolean pesach, boolean cholHamoedPesach, boolean shavuos, boolean roshHashana, boolean yomKippur, boolean succos, boolean hoshanaRabba, boolean shminiAtzeres, boolean simchasTorah, boolean cholHamoedSuccos, boolean cholHamoed, boolean erevYomTov, boolean erevRoshChodesh, boolean yomKippurKatan, boolean beHaB, boolean taanis, boolean taanisBechoros, int dayOfChanukah, boolean chanukah, boolean purim, boolean roshChodesh, boolean macharChodesh, boolean shabbosMevorchim, int dayOfOmer, boolean tishaBav, JewishDate molad, Instant moladAsDate, Instant tchilasZmanKidushLevana3Days, Instant tchilasZmanKidushLevana7Days, Instant sofZmanKidushLevanaBetweenMoldos, Instant sofZmanKidushLevana15Days, int tekufasTishreiElapsedDays) {
this.current = current;
this.currentJewishDate = currentJewishDate;
this.yomTovIndex = yomTovIndex;
diff --git a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_DaysInGregorianMonth.java b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_DaysInGregorianMonth.java
deleted file mode 100644
index 4dd5ac87..00000000
--- a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_DaysInGregorianMonth.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2011. Jay R. Gindin
- */
-
-package com.kosherjava.zmanim.hebrewcalendar;
-
-import org.junit.*;
-
-import java.util.Calendar;
-
-/**
- * Verify the calculation of the number of days in a month. Not too hard...just the rules about when February
- * has 28 or 29 days...
- */
-@SuppressWarnings({ "MagicNumber" })
-public class UT_DaysInGregorianMonth {
-
-
- @Test
- public void testDaysInMonth() {
-
- JewishDate hebrewDate = new JewishDate();
-
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, 2011);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- hebrewDate.setDate(cal);
-
- assertDaysInMonth(false, hebrewDate);
- }
-
-
-
- @Test
- public void testDaysInMonthLeapYear() {
-
- JewishDate hebrewDate = new JewishDate();
-
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, 2012);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- hebrewDate.setDate(cal);
-
- assertDaysInMonth(true, hebrewDate);
- }
-
-
- @Test
- public void testDaysInMonth100Year() {
-
- JewishDate hebrewDate = new JewishDate();
-
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, 2100);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- hebrewDate.setDate(cal);
-
- assertDaysInMonth(false, hebrewDate);
- }
-
-
- @Test
- public void testDaysInMonth400Year() {
-
- JewishDate hebrewDate = new JewishDate();
-
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, 2000);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- hebrewDate.setDate(cal);
-
- assertDaysInMonth(true, hebrewDate);
- }
-
-
- private void assertDaysInMonth(
- boolean febIsLeap,
- JewishDate hebrewDate
- ) {
-
- Assert.assertEquals(31, hebrewDate.getLastDayOfGregorianMonth(1));
- Assert.assertEquals(febIsLeap ? 29 : 28, hebrewDate.getLastDayOfGregorianMonth(2));
- Assert.assertEquals(31, hebrewDate.getLastDayOfGregorianMonth(3));
- Assert.assertEquals(30, hebrewDate.getLastDayOfGregorianMonth(4));
- Assert.assertEquals(31, hebrewDate.getLastDayOfGregorianMonth(5));
- Assert.assertEquals(30, hebrewDate.getLastDayOfGregorianMonth(6));
- Assert.assertEquals(31, hebrewDate.getLastDayOfGregorianMonth(7));
- Assert.assertEquals(31, hebrewDate.getLastDayOfGregorianMonth(8));
- Assert.assertEquals(30, hebrewDate.getLastDayOfGregorianMonth(9));
- Assert.assertEquals(31, hebrewDate.getLastDayOfGregorianMonth(10));
- Assert.assertEquals(30, hebrewDate.getLastDayOfGregorianMonth(11));
- Assert.assertEquals(31, hebrewDate.getLastDayOfGregorianMonth(12));
- }
-
-
-} // End of UT_DaysInGregorianMonth class
diff --git a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_GregorianDateNavigation.java b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_GregorianDateNavigation.java
index 6feb7e38..9a5a2bfb 100644
--- a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_GregorianDateNavigation.java
+++ b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_GregorianDateNavigation.java
@@ -6,7 +6,8 @@
import org.junit.*;
-import java.util.Calendar;
+import java.time.LocalDate;
+import java.time.Month;
/**
* Checks that we can roll forward & backward the gregorian dates...
@@ -17,125 +18,111 @@ public class UT_GregorianDateNavigation {
@Test
public void gregorianForwardMonthToMonth() {
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, 2011);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- cal.set(Calendar.DATE, 31);
+ LocalDate localDate = LocalDate.of(2011, Month.JANUARY,31);
- JewishDate hebrewDate = new JewishDate(cal);
+ JewishDate hebrewDate = new JewishDate(localDate);
Assert.assertEquals(5771, hebrewDate.getJewishYear());
Assert.assertEquals(11, hebrewDate.getJewishMonth());
Assert.assertEquals(26, hebrewDate.getJewishDayOfMonth());
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(1, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(2, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(11, hebrewDate.getJewishMonth());
Assert.assertEquals(27, hebrewDate.getJewishDayOfMonth());
-
- cal.set(Calendar.MONTH, Calendar.FEBRUARY);
- cal.set(Calendar.DATE, 28);
- hebrewDate.setDate(cal);
- Assert.assertEquals(1, hebrewDate.getGregorianMonth());
- Assert.assertEquals(28, hebrewDate.getGregorianDayOfMonth());
+
+ localDate = LocalDate.of(2011, Month.FEBRUARY,28);
+ hebrewDate = new JewishDate(localDate);
+ Assert.assertEquals(2, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(28, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(12, hebrewDate.getJewishMonth());
Assert.assertEquals(24, hebrewDate.getJewishDayOfMonth());
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(2, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(3, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(12, hebrewDate.getJewishMonth());
Assert.assertEquals(25, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DATE, 31);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(3, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.MARCH,31);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(4, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(13, hebrewDate.getJewishMonth());
Assert.assertEquals(26, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.APRIL);
- cal.set(Calendar.DATE, 30);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(4, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.APRIL,30);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(5, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(1, hebrewDate.getJewishMonth());
Assert.assertEquals(27, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.MAY);
- cal.set(Calendar.DATE, 31);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(5, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.MAY,31);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(6, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(2, hebrewDate.getJewishMonth());
Assert.assertEquals(28, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.JUNE);
- cal.set(Calendar.DATE, 30);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(6, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.JUNE,30);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(7, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(3, hebrewDate.getJewishMonth());
Assert.assertEquals(29, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.JULY);
- cal.set(Calendar.DATE, 31);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(7, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.JULY,31);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(8, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(5, hebrewDate.getJewishMonth());
Assert.assertEquals(1, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.AUGUST);
- cal.set(Calendar.DATE, 31);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(8, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.AUGUST,31);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(9, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(6, hebrewDate.getJewishMonth());
Assert.assertEquals(2, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.SEPTEMBER);
- cal.set(Calendar.DATE, 30);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(9, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.SEPTEMBER,30);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(10, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(7, hebrewDate.getJewishMonth());
Assert.assertEquals(3, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.OCTOBER);
- cal.set(Calendar.DATE, 31);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(10, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.OCTOBER,31);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(11, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(5772, hebrewDate.getJewishYear());
Assert.assertEquals(8, hebrewDate.getJewishMonth());
Assert.assertEquals(4, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.NOVEMBER);
- cal.set(Calendar.DATE, 30);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(11, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.NOVEMBER,30);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(12, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(9, hebrewDate.getJewishMonth());
Assert.assertEquals(5, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.MONTH, Calendar.DECEMBER);
- cal.set(Calendar.DATE, 31);
- hebrewDate.setDate(cal);
- hebrewDate.forward(Calendar.DATE, 1);
- Assert.assertEquals(2012, hebrewDate.getGregorianYear());
- Assert.assertEquals(0, hebrewDate.getGregorianMonth());
- Assert.assertEquals(1, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2011, Month.DECEMBER,31);
+ hebrewDate = new JewishDate(localDate);
+ hebrewDate.plusDays(1);
+ Assert.assertEquals(2012, hebrewDate.getLocalDate().getYear());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(10, hebrewDate.getJewishMonth());
Assert.assertEquals(6, hebrewDate.getJewishDayOfMonth());
}
@@ -144,117 +131,101 @@ public void gregorianForwardMonthToMonth() {
@Test
public void gregorianBackwardMonthToMonth() {
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, 2011);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- cal.set(Calendar.DATE, 1);
-
- JewishDate hebrewDate = new JewishDate(cal);
- hebrewDate.back();
- Assert.assertEquals(2010, hebrewDate.getGregorianYear());
- Assert.assertEquals(11, hebrewDate.getGregorianMonth());
- Assert.assertEquals(31, hebrewDate.getGregorianDayOfMonth());
+ LocalDate localDate = LocalDate.of(2011, Month.JANUARY, 1);
+ JewishDate hebrewDate = new JewishDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(2010, hebrewDate.getLocalDate().getYear());
+ Assert.assertEquals(12, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(31, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(10, hebrewDate.getJewishMonth());
Assert.assertEquals(24, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.DECEMBER);
- cal.set(Calendar.YEAR, 2010);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(10, hebrewDate.getGregorianMonth());
- Assert.assertEquals(30, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.DECEMBER, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(11, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(30, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(9, hebrewDate.getJewishMonth());
Assert.assertEquals(23, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.NOVEMBER);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(9, hebrewDate.getGregorianMonth());
- Assert.assertEquals(31, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.NOVEMBER, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(10, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(31, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(8, hebrewDate.getJewishMonth());
Assert.assertEquals(23, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.OCTOBER);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(8, hebrewDate.getGregorianMonth());
- Assert.assertEquals(30, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.OCTOBER, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(9, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(30, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(7, hebrewDate.getJewishMonth());
Assert.assertEquals(22, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.SEPTEMBER);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(7, hebrewDate.getGregorianMonth());
- Assert.assertEquals(31, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.SEPTEMBER, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(8, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(31, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(5770, hebrewDate.getJewishYear());
Assert.assertEquals(6, hebrewDate.getJewishMonth());
Assert.assertEquals(21, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.AUGUST);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(6, hebrewDate.getGregorianMonth());
- Assert.assertEquals(31, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.AUGUST, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(7, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(31, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(5, hebrewDate.getJewishMonth());
Assert.assertEquals(20, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.JULY);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(5, hebrewDate.getGregorianMonth());
- Assert.assertEquals(30, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.JULY, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(6, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(30, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(4, hebrewDate.getJewishMonth());
Assert.assertEquals(18, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.JUNE);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(4, hebrewDate.getGregorianMonth());
- Assert.assertEquals(31, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.JUNE, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(5, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(31, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(3, hebrewDate.getJewishMonth());
Assert.assertEquals(18, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.MAY);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(3, hebrewDate.getGregorianMonth());
- Assert.assertEquals(30, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.MAY, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(4, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(30, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(2, hebrewDate.getJewishMonth());
Assert.assertEquals(16, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.APRIL);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(2, hebrewDate.getGregorianMonth());
- Assert.assertEquals(31, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.APRIL, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(3, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(31, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(1, hebrewDate.getJewishMonth());
Assert.assertEquals(16, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(1, hebrewDate.getGregorianMonth());
- Assert.assertEquals(28, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.MARCH, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(2, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(28, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(12, hebrewDate.getJewishMonth());
Assert.assertEquals(14, hebrewDate.getJewishDayOfMonth());
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.FEBRUARY);
- hebrewDate.setDate(cal);
- hebrewDate.back();
- Assert.assertEquals(0, hebrewDate.getGregorianMonth());
- Assert.assertEquals(31, hebrewDate.getGregorianDayOfMonth());
+ localDate = LocalDate.of(2010, Month.FEBRUARY, 1);
+ hebrewDate.setGregorianDate(localDate);
+ hebrewDate.minusDays(1);
+ Assert.assertEquals(1, hebrewDate.getLocalDate().getMonthValue());
+ Assert.assertEquals(31, hebrewDate.getLocalDate().getDayOfMonth());
Assert.assertEquals(11, hebrewDate.getJewishMonth());
Assert.assertEquals(16, hebrewDate.getJewishDayOfMonth());
diff --git a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_JewishDateNavigation.java b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_JewishDateNavigation.java
index 2a0d6e66..aad45602 100644
--- a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_JewishDateNavigation.java
+++ b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/UT_JewishDateNavigation.java
@@ -6,6 +6,8 @@
import org.junit.*;
+import java.time.LocalDate;
+import java.time.Month;
import java.util.Calendar;
/**
@@ -20,9 +22,10 @@ public void jewishForwardMonthToMonth() {
JewishDate jewishDate = new JewishDate();
jewishDate.setJewishDate(5771, 1, 1);
- Assert.assertEquals(5, jewishDate.getGregorianDayOfMonth());
- Assert.assertEquals(3, jewishDate.getGregorianMonth());
- Assert.assertEquals(2011, jewishDate.getGregorianYear());
+ LocalDate localDate = jewishDate.getLocalDate();
+ Assert.assertEquals(5, localDate.getDayOfMonth());
+ Assert.assertEquals(Month.APRIL, localDate.getMonth());
+ Assert.assertEquals(2011, localDate.getYear());
}
@@ -33,9 +36,28 @@ public void computeRoshHashana5771() {
JewishDate jewishDate = new JewishDate();
jewishDate.setJewishDate(5771, 7, 1);
- Assert.assertEquals(9, jewishDate.getGregorianDayOfMonth());
- Assert.assertEquals(8, jewishDate.getGregorianMonth());
- Assert.assertEquals(2010, jewishDate.getGregorianYear());
+ LocalDate localDate = jewishDate.getLocalDate();
+ Assert.assertEquals(9, localDate.getDayOfMonth());
+ Assert.assertEquals(Month.SEPTEMBER, localDate.getMonth());
+ Assert.assertEquals(2010, localDate.getYear());
+ }
+
+ @Test
+ public void addYearsUsesConfiguredAdarMonthWhenMovingToLeapYear() {
+
+ JewishDate adarAlephDate = new JewishDate();
+ adarAlephDate.setJewishDate(5783, JewishDate.ADAR, 10);
+ adarAlephDate.plusYears(1, true);
+ Assert.assertEquals(5784, adarAlephDate.getJewishYear());
+ Assert.assertEquals(JewishDate.ADAR, adarAlephDate.getJewishMonth());
+ Assert.assertEquals(10, adarAlephDate.getJewishDayOfMonth());
+
+ JewishDate adarBeisDate = new JewishDate();
+ adarBeisDate.setJewishDate(5783, JewishDate.ADAR, 10);
+ adarBeisDate.plusYears(1, false);
+ Assert.assertEquals(5784, adarBeisDate.getJewishYear());
+ Assert.assertEquals(JewishDate.ADAR_II, adarBeisDate.getJewishMonth());
+ Assert.assertEquals(10, adarBeisDate.getJewishDayOfMonth());
}
diff --git a/src/test/java/com/kosherjava/zmanim/util/SerializationRegressionTest.java b/src/test/java/com/kosherjava/zmanim/util/SerializationRegressionTest.java
new file mode 100644
index 00000000..58d2218f
--- /dev/null
+++ b/src/test/java/com/kosherjava/zmanim/util/SerializationRegressionTest.java
@@ -0,0 +1,59 @@
+package com.kosherjava.zmanim.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.time.Instant;
+import java.time.ZoneId;
+
+import org.junit.Test;
+
+import com.kosherjava.zmanim.AstronomicalCalendar;
+
+public class SerializationRegressionTest {
+
+ @Test
+ public void zmanToXmlSerializesInstantUsingGeoLocationZone() {
+ GeoLocation geoLocation = new GeoLocation("Lakewood", 40.0828, -74.2094, ZoneId.of("America/New_York"));
+ Zman zman = new Zman(Instant.parse("2026-03-23T10:56:01.123Z"), geoLocation, "Sunrise");
+
+ String xml = zman.toXML();
+
+ assertTrue(xml.contains("2026-03-23T06:56:01.123 "));
+ }
+
+ @Test
+ public void zmanWithoutGeoLocationStillSerializesAndFormats() {
+ Zman zman = new Zman(Instant.parse("2026-03-23T10:56:01.123Z"), "Sunrise");
+
+ String xml = zman.toXML();
+ String text = zman.toString();
+
+ assertTrue(xml.contains("2026-03-23T10:56:01.123 "));
+ assertTrue(text.contains("GeoLocation:\tnull"));
+ }
+
+ @Test
+ public void astronomicalCalendarPreservesSubSecondPrecision() {
+ AstronomicalCalendar astronomicalCalendar = new AstronomicalCalendar(
+ new GeoLocation("Lakewood", 40.0828, -74.2094, ZoneId.of("America/New_York")));
+
+ double utcSunrise = astronomicalCalendar.getUTCSunrise(AstronomicalCalendar.GEOMETRIC_ZENITH);
+ long expectedEpochMillis = Math.round(utcSunrise * AstronomicalCalendar.HOUR_MILLIS);
+ long actualEpochMillis = astronomicalCalendar.getSunrise().toEpochMilli()
+ % (24 * AstronomicalCalendar.HOUR_MILLIS);
+
+ assertTrue(expectedEpochMillis % 1000 != 0);
+ assertFalse(actualEpochMillis % 1000 == 0);
+ assertTrue(Math.abs(expectedEpochMillis - actualEpochMillis) < 1000);
+ }
+
+ @Test
+ public void negativeTimePreservesSignInValueAndFormatting() {
+ Time time = new Time(-90_500);
+
+ assertEquals(-90_500d, time.getTime(), 0.0);
+ assertEquals("-0:01:30.500", time.toString());
+ }
+}