001    /*
002     * Zmanim Java API
003     * Copyright (C) 2004-2008 Eliyahu Hershfeld
004     *
005     * This program is free software; you can redistribute it and/or modify it under the terms of the
006     * GNU General Public License as published by the Free Software Foundation; either version 2 of the
007     * License, or (at your option) any later version.
008     *
009     * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
010     * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011     * General Public License for more details.
012     *
013     * You should have received a copy of the GNU General Public License along with this program; if
014     * not, write to the Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA
015     * 02111-1307, USA or connect to: http://www.fsf.org/copyleft/gpl.html
016     */
017    package net.sourceforge.zmanim;
018    
019    import java.util.Date;
020    
021    import net.sourceforge.zmanim.util.AstronomicalCalculator;
022    import net.sourceforge.zmanim.util.GeoLocation;
023    
024    /**
025     * This class extends ZmanimCalendar and provides many more zmanim than
026     * available in the ZmanimCalendar. The basis for most zmanim in this class are
027     * from the <em>sefer</em> <b>Yisroel Vehazmanim</b> by <b>Rabbi Yisroel
028     * Dovid Harfenes</b>. <br />
029     * For an example of the number of different <em>zmanim</em> made available by
030     * this class, there are methods to return 12 different calculations for
031     * <em>alos</em> (dawn) available in this class. The real power of this API is
032     * the ease in calculating <em>zmanim</em> that are not part of the API. The
033     * methods for doing <em>zmanim</em> calculations not present in this or it's
034     * superclass the {@link ZmanimCalendar} are contained in the
035     * {@link AstronomicalCalendar}, the base class of the calendars in our API
036     * since they are generic methods for calculating time based on degrees or time
037     * before or after {@link #getSunrise sunrise} and {@link #getSunset sunset} and
038     * are of interest for calculation beyond <em>zmanim</em> calculations. Here
039     * are some examples: <br />
040     * First create the Calendar for the location you would like to calculate:
041     * 
042     * <pre>
043     * String locationName = &quot;Lakewood, NJ&quot;;
044     * double latitude = 40.0828; //Lakewood, NJ
045     * double longitude = -74.2094; //Lakewood, NJ
046     * double elevation = 0;
047     * //the String parameter in getTimeZone() has to be a valid timezone listed in {@link java.util.TimeZone#getAvailableIDs()}
048     * TimeZone timeZone = TimeZone.getTimeZone(&quot;America/New_York&quot;);
049     * GeoLocation location = new GeoLocation(locationName, latitude, longitude,
050     *              elevation, timeZone);
051     * ComplexZmanimCalendar czc = new ComplexZmanimCalendar(location);
052     * </pre>
053     * 
054     * Note: For locations such as Israel where the beginning and end of daylight
055     * savings time can fluctuate from year to year create a
056     * {@link java.util.SimpleTimeZone} with the known start and end of DST. <br />
057     * To get alos calculated as 14&deg; below the horizon (as calculated in the
058     * calendars published in Montreal) use:
059     * 
060     * <pre>
061     * Date alos14 = czc.getSunriseOffsetByDegrees(14);
062     * </pre>
063     * 
064     * To get <em>mincha gedola</em> calculated based on the MGA using a <em>shaah
065     * zmanis</em>
066     * based on the day starting 16.1&deg; below the horizon (and ending 16.1&deg;
067     * after sunset the following calculation can be used:
068     * 
069     * <pre>
070     * Date minchaGedola = czc.getTimeOffset(czc.getAlos16point1Degrees(), czc
071     *              .getShaahZmanis16Point1Degrees() * 6.5);
072     * </pre>
073     * 
074     * A little more complex example would be calculating <em>plag hamincha</em>
075     * based on a shaah zmanis that was not present in this class. While a drop more
076     * complex it is still rather easy. For example if you wanted to calculate
077     * <em>plag</em> based on the day starting 12&deg; before sunrise and ending
078     * 12&deg; after sunset as calculated in the calendars in Manchester, England
079     * (there is nothing that would prevent your calculating the day using sunrise
080     * and sunset offsets that are not identical degrees, but this would lead to
081     * chatzos being a time other than the {@link #getSunTransit() solar transit}
082     * (solar midday)). The steps involved would be to first calculate the
083     * <em>shaah zmanis</em> and than use that time in milliseconds to calculate
084     * 10.75 hours after sunrise starting at 12&deg; before sunset
085     * 
086     * <pre>
087     * long shaahZmanis = czc.getTemporalHour(czc.getSunriseOffsetByDegrees(12), czc
088     *              .getSunsetOffsetByDegrees(12));
089     * Date plag = getTimeOffset(czc.getSunriseOffsetByDegrees(12),
090     *              shaahZmanis * 10.75);
091     * </pre>
092     * 
093     * <h2>Disclaimer:</h2>
094     * While I did my best to get accurate results please do not rely on these
095     * zmanim for <em>halacha lemaaseh</em>
096     * 
097     * @author &copy; Eliyahu Hershfeld 2004 - 2009
098     * @version 1.1
099     */
100    public class ComplexZmanimCalendar extends ZmanimCalendar {
101            private static final long serialVersionUID = 1;
102    
103            /**
104             * The zenith of 3.7&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
105             * (90&deg;). This calculation is used for calculating <em>tzais</em>
106             * (nightfall) according to some opinions. This calculation is based on the
107             * opinion of the Geonim that <em>tzais</em> is the time it takes to walk
108             * 3/4 of a Mil at 18 minutes a Mil, or 13.5 minutes after sunset. The sun
109             * is 3.7&deg below {@link #GEOMETRIC_ZENITH geometric zenith} at this time
110             * in Jerusalem on March 16, about 4 days before the equinox, the day that a
111             * solar hour is one hour.
112             * 
113             * TODO AT see #getTzaisGeonim3Point7Degrees()
114             */
115            protected static final double ZENITH_3_POINT_7 = GEOMETRIC_ZENITH + 3.7;
116    
117            /**
118             * The zenith of 5.95&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
119             * (90&deg;). This calculation is used for calculating <em>tzais</em>
120             * (nightfall) according to some opinions. This calculation is based on the
121             * position of the sun 24 minutes after sunset in Jerusalem on March 16,
122             * about 4 days before the equinox, the day that a solar hour is one hour,
123             * which calculates to 5.95&deg; below
124             * {@link #GEOMETRIC_ZENITH geometric zenith}
125             * 
126             * @see #getTzaisGeonim5Point95Degrees()
127             */
128            protected static final double ZENITH_5_POINT_95 = GEOMETRIC_ZENITH + 5.95;
129    
130            /**
131             * The zenith of 7.083&deg; below
132             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This is often
133             * referred to as 7&deg;5' or 7&deg; and 5 minutes. This calculation is used
134             * for calculating <em>alos</em> (dawn) and <em>tzais</em> (nightfall)
135             * according to some opinions. This calculation is based on the position of
136             * the sun 30 minutes after sunset in Jerusalem on March 16, about 4 days
137             * before the equinox, the day that a solar hour is one hour, which
138             * calculates to 7.0833333&deg; below
139             * {@link #GEOMETRIC_ZENITH geometric zenith}. This is time some opinions
140             * consider dark enough for 3 stars to be visible. This is the opinion of
141             * the Shu"t Melamed Leho'il, Shu"t Binyan Tziyon, Tenuvas Sadeh and very
142             * close to the time of the Mekor Chesed on the Sefer chasidim.
143             * 
144             * @see #getTzaisGeonim7Point083Degrees()
145             * @see #getBainHasmashosRT13Point5MinutesBefore7Point083Degrees()
146             */
147            protected static final double ZENITH_7_POINT_083 = GEOMETRIC_ZENITH + 7
148                            + (5 / 60);
149    
150            /**
151             * The zenith of 10.2&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
152             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
153             * according to some opinions. This calculation is based on the position of
154             * the sun 45 minutes before {@link #getSunrise sunrise} in Jerusalem on
155             * March 16, about 4 days before the equinox, the day that a solar hour is
156             * one hour which calculates to 10.2&deg; below
157             * {@link #GEOMETRIC_ZENITH geometric zenith}
158             * 
159             * @see #getMisheyakir10Point2Degrees()
160             */
161            protected static final double ZENITH_10_POINT_2 = GEOMETRIC_ZENITH + 10.2;
162    
163            /**
164             * The zenith of 11&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
165             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
166             * according to some opinions. This calculation is based on the position of
167             * the sun 48 minutes before {@link #getSunrise sunrise} in Jerusalem on
168             * March 16, about 4 days before the equinox, the day that a solar hour is
169             * one hour which calculates to 11&deg; below
170             * {@link #GEOMETRIC_ZENITH geometric zenith}
171             * 
172             * @see #getMisheyakir11Degrees()
173             */
174            protected static final double ZENITH_11_DEGREES = GEOMETRIC_ZENITH + 11;
175    
176            /**
177             * The zenith of 11.5&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
178             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
179             * according to some opinions. This calculation is based on the position of
180             * the sun 52 minutes before {@link #getSunrise sunrise} in Jerusalem on
181             * March 16, about 4 days before the equinox, the day that a solar hour is
182             * one hour which calculates to 11.5&deg; below
183             * {@link #GEOMETRIC_ZENITH geometric zenith}
184             * 
185             * @see #getMisheyakir11Point5Degrees()
186             */
187            protected static final double ZENITH_11_POINT_5 = GEOMETRIC_ZENITH + 11.5;
188    
189            /**
190             * The zenith of 13&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
191             * (90&deg;). This calculation is used for calculating
192             * <em>Rabainu Tam's bain hashmashos</em> according to some opinions.
193             * <br/><br/> <b>FIXME:</b> See comments on
194             * {@link #getBainHasmashosRT13Degrees}. This should be changed to 13.2477
195             * after confirmation.
196             * 
197             * @see #getBainHasmashosRT13Degrees
198             * 
199             */
200            protected static final double ZENITH_13_DEGREES = GEOMETRIC_ZENITH + 13;
201    
202            /**
203             * The zenith of 19.8&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
204             * (90&deg;). This calculation is used for calculating <em>alos</em>
205             * (dawn) and <em>tzais</em> (nightfall) according to some opinions. This
206             * calculation is based on the position of the sun 90 minutes after sunset
207             * in Jerusalem on March 16, about 4 days before the equinox, the day that a
208             * solar hour is one hour which calculates to 19.8&deg; below
209             * {@link #GEOMETRIC_ZENITH geometric zenith}
210             * 
211             * @see #getTzais19Point8Degrees()
212             * @see #getAlos19Point8Degrees()
213             * @see #getAlos90()
214             * @see #getTzais90()
215             */
216            protected static final double ZENITH_19_POINT_8 = GEOMETRIC_ZENITH + 19.8;
217    
218            /**
219             * The zenith of 26&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
220             * (90&deg;). This calculation is used for calculating <em>alos</em>
221             * (dawn) and <em>tzais</em> (nightfall) according to some opinions. This
222             * calculation is based on the position of the sun
223             * {@link #getAlos120() 120 minutes} after sunset in Jerusalem on March 16,
224             * about 4 days before the equinox, the day that a solar hour is one hour
225             * which calculates to 26&deg; below
226             * {@link #GEOMETRIC_ZENITH geometric zenith}
227             * 
228             * @see #getAlos26Degrees()
229             * @see #getTzais26Degrees()
230             * @see #getAlos120()
231             * @see #getTzais120()
232             */
233            protected static final double ZENITH_26_DEGREES = GEOMETRIC_ZENITH + 26.0;
234    
235            private double ateretTorahSunsetOffset = 40;
236    
237            public ComplexZmanimCalendar(GeoLocation location) {
238                    super(location);
239            }
240    
241            /**
242             * Default constructor will set a default {@link GeoLocation#GeoLocation()},
243             * a default
244             * {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} and
245             * default the calendar to the current date.
246             * 
247             * @see AstronomicalCalendar#AstronomicalCalendar()
248             */
249            public ComplexZmanimCalendar() {
250                    super();
251            }
252    
253            /**
254             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
255             * using a 19.8&deg; dip. This calculation divides the day based on the
256             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
257             * calculation is when the sun is 19.8&deg; below the eastern geometric
258             * horizon before sunrise. Dusk for this is when the sun is 19.8&deg; below
259             * the western geometric horizon after sunset. This day is split into 12
260             * equal parts with each part being a <em>shaah zmanis</em>.
261             * 
262             * @return the <code>long</code> millisecond length of a
263             *         <em>shaah zmanis</em>.
264             */
265            public long getShaahZmanis19Point8Degrees() {
266                    return getTemporalHour(getAlos19Point8Degrees(),
267                                    getTzais19Point8Degrees());
268            }
269    
270            /**
271             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
272             * using a 18&deg; dip. This calculation divides the day based on the
273             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
274             * calculation is when the sun is 18&deg; below the eastern geometric
275             * horizon before sunrise. Dusk for this is when the sun is 18&deg; below
276             * the western geometric horizon after sunset. This day is split into 12
277             * equal parts with each part being a <em>shaah zmanis</em>.
278             * 
279             * @return the <code>long</code> millisecond length of a
280             *         <em>shaah zmanis</em>.
281             */
282            public long getShaahZmanis18Degrees() {
283                    return getTemporalHour(getAlos18Degrees(), getTzais18Degrees());
284            }
285    
286            /**
287             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
288             * using a dip of 26&deg;. This calculation divides the day based on the
289             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
290             * calculation is when the sun is {@link #getAlos26Degrees() 26&deg;} below
291             * the eastern geometric horizon before sunrise. Dusk for this is when the
292             * sun is {@link #getTzais26Degrees() 26&deg;} below the western geometric
293             * horizon after sunset. This day is split into 12 equal parts with each
294             * part being a <em>shaah zmanis</em>.
295             * 
296             * @return the <code>long</code> millisecond length of a
297             *         <em>shaah zmanis</em>.
298             */
299            public long getShaahZmanis26Degrees() {
300                    return getTemporalHour(getAlos26Degrees(), getTzais26Degrees());
301            }
302    
303            /**
304             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
305             * using a dip of 16.1&deg;. This calculation divides the day based on the
306             * opinion that the day runs from dawn to dusk. Dawn for this calculation is
307             * when the sun is 16.1&deg; below the eastern geometric horizon before
308             * sunrise and dusk is when the sun is 16.1&deg; below the western geometric
309             * horizon after sunset. This day is split into 12 equal parts with each
310             * part being a <em>shaah zmanis</em>.
311             * 
312             * @return the <code>long</code> millisecond length of a
313             *         <em>shaah zmanis</em>.
314             * @see #getAlos16Point1Degrees()
315             * @see #getTzais16Point1Degrees()
316             * @see #getSofZmanShmaMGA16Point1Degrees()
317             * @see #getSofZmanTfilaMGA16Point1Degrees()
318             * @see #getMinchaGedola16Point1Degrees()
319             * @see #getMinchaKetana16Point1Degrees()
320             * @see #getPlagHamincha16Point1Degrees()
321             */
322    
323            public long getShaahZmanis16Point1Degrees() {
324                    return getTemporalHour(getAlos16Point1Degrees(),
325                                    getTzais16Point1Degrees());
326            }
327    
328            /**
329             * Method to return a <em>shaah zmanis</em> (solar hour) according to the
330             * opinion of the MGA. This calculation divides the day based on the opinion
331             * of the <em>MGA</em> that the day runs from dawn to dusk. Dawn for this
332             * calculation is 60 minutes before sunrise and dusk is 60 minutes after
333             * sunset. This day is split into 12 equal parts with each part being a
334             * <em>shaah zmanis</em>. Alternate mothods of calculating a
335             * <em>shaah zmanis</em> are available in the subclass
336             * {@link ComplexZmanimCalendar}
337             * 
338             * @return the <code>long</code> millisecond length of a
339             *         <em>shaah zmanis</em>.
340             */
341            public long getShaahZmanis60Minutes() {
342                    return getTemporalHour(getAlos60(), getTzais60());
343            }
344    
345            /**
346             * Method to return a <em>shaah zmanis</em> (solar hour) according to the
347             * opinion of the MGA. This calculation divides the day based on the opinion
348             * of the <em>MGA</em> that the day runs from dawn to dusk. Dawn for this
349             * calculation is 72 minutes before sunrise and dusk is 72 minutes after
350             * sunset. This day is split into 12 equal parts with each part being a
351             * <em>shaah zmanis</em>. Alternate mothods of calculating a
352             * <em>shaah zmanis</em> are available in the subclass
353             * {@link ComplexZmanimCalendar}
354             * 
355             * @return the <code>long</code> millisecond length of a
356             *         <em>shaah zmanis</em>.
357             */
358            public long getShaahZmanis72Minutes() {
359                    return getShaahZmanisMGA();
360            }
361    
362            /**
363             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
364             * the opinion of the MGA based on <em>alos</em> being
365             * {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> before
366             * {@link #getSunrise() sunrise}. This calculation divides the day based on
367             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
368             * Dawn for this calculation is 72 minutes <em>zmaniyos</em> before
369             * sunrise and dusk is 72 minutes <em>zmaniyos</em> after sunset. This day
370             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
371             * This is identical to 1/10th of the day from {@link #getSunrise() sunrise}
372             * to {@link #getSunset() sunset}.
373             * 
374             * @return the <code>long</code> millisecond length of a
375             *         <em>shaah zmanis</em>.
376             * @see #getAlos72Zmanis()
377             * @see #getTzais72Zmanis()
378             */
379            public long getShaahZmanis72MinutesZmanis() {
380                    return getTemporalHour(getAlos72Zmanis(), getTzais72Zmanis());
381            }
382    
383            /**
384             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
385             * using a dip of 90 minutes. This calculation divides the day based on the
386             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
387             * calculation is 90 minutes before sunrise and dusk is 90 minutes after
388             * sunset. This day is split into 12 equal parts with each part being a
389             * <em>shaah zmanis</em>.
390             * 
391             * @return the <code>long</code> millisecond length of a
392             *         <em>shaah zmanis</em>.
393             */
394            public long getShaahZmanis90Minutes() {
395                    return getTemporalHour(getAlos90(), getTzais90());
396            }
397    
398            /**
399             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
400             * the opinion of the MGA based on <em>alos</em> being
401             * {@link #getAlos90Zmanis() 90} minutes <em>zmaniyos</em> before
402             * {@link #getSunrise() sunrise}. This calculation divides the day based on
403             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
404             * Dawn for this calculation is 90 minutes <em>zmaniyos</em> before
405             * sunrise and dusk is 90 minutes <em>zmaniyos</em> after sunset. This day
406             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
407             * This is identical to 1/8th of the day from {@link #getSunrise() sunrise}
408             * to {@link #getSunset() sunset}.
409             * 
410             * @return the <code>long</code> millisecond length of a
411             *         <em>shaah zmanis</em>.
412             * @see #getAlos90Zmanis()
413             * @see #getTzais90Zmanis()
414             */
415            public long getShaahZmanis90MinutesZmanis() {
416                    return getTemporalHour(getAlos90Zmanis(), getTzais90Zmanis());
417            }
418    
419            /**
420             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
421             * the opinion of the MGA based on <em>alos</em> being
422             * {@link #getAlos96Zmanis() 96} minutes <em>zmaniyos</em> before
423             * {@link #getSunrise() sunrise}. This calculation divides the day based on
424             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
425             * Dawn for this calculation is 96 minutes <em>zmaniyos</em> before
426             * sunrise and dusk is 96 minutes <em>zmaniyos</em> after sunset. This day
427             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
428             * This is identical to 1/7.5th of the day from
429             * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
430             * 
431             * @return the <code>long</code> millisecond length of a
432             *         <em>shaah zmanis</em>.
433             * @see #getAlos96Zmanis()
434             * @see #getTzais96Zmanis()
435             */
436            public long getShaahZmanis96MinutesZmanis() {
437                    return getTemporalHour(getAlos96Zmanis(), getTzais96Zmanis());
438            }
439    
440            /**
441             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
442             * the opinion of the Chacham Yosef Harari-Raful of Yeshivat Ateret Torah
443             * calculated with <em>alos</em> being 1/10th of sunrise to sunset day, or
444             * {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> of such a day
445             * before {@link #getSunrise() sunrise}, and tzais is usually calculated as
446             * {@link #getTzaisAteretTorah() 40 minutes} after
447             * {@link #getSunset() sunset}. This day is split into 12 equal parts with
448             * each part being a <em>shaah zmanis</em>. Note that with this system,
449             * chatzos (mid-day) will not be the point that the sun is
450             * {@link #getSunTransit() halfway across the sky}.
451             * 
452             * @return the <code>long</code> millisecond length of a
453             *         <em>shaah zmanis</em>.
454             * @see #getAlos72Zmanis()
455             * @see #getTzaisAteretTorah()
456             * @see #getAteretTorahSunsetOffset()
457             * @see #setAteretTorahSunsetOffset(double)
458             */
459            public long getShaahZmanisAteretTorah() {
460                    return getTemporalHour(getAlos72Zmanis(), getTzaisAteretTorah());
461            }
462    
463            /**
464             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
465             * using a dip of 96 minutes. This calculation divides the day based on the
466             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
467             * calculation is 96 minutes before sunrise and dusk is 96 minutes after
468             * sunset. This day is split into 12 equal parts with each part being a
469             * <em>shaah zmanis</em>.
470             * 
471             * @return the <code>long</code> millisecond length of a
472             *         <em>shaah zmanis</em>.
473             */
474            public long getShaahZmanis96Minutes() {
475                    return getTemporalHour(getAlos96(), getTzais96());
476            }
477    
478            /**
479             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
480             * using a dip of 120 minutes. This calculation divides the day based on the
481             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
482             * calculation is 120 minutes before sunrise and dusk is 120 minutes after
483             * sunset. This day is split into 12 equal parts with each part being a
484             * <em>shaah zmanis</em>.
485             * 
486             * @return the <code>long</code> millisecond length of a
487             *         <em>shaah zmanis</em>.
488             */
489            public long getShaahZmanis120Minutes() {
490                    return getTemporalHour(getAlos120(), getTzais120());
491            }
492    
493            /**
494             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
495             * the opinion of the MGA based on <em>alos</em> being
496             * {@link #getAlos120Zmanis() 120} minutes <em>zmaniyos</em> before
497             * {@link #getSunrise() sunrise}. This calculation divides the day based on
498             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
499             * Dawn for this calculation is 120 minutes <em>zmaniyos</em> before
500             * sunrise and dusk is 120 minutes <em>zmaniyos</em> after sunset. This
501             * day is split into 12 equal parts with each part being a
502             * <em>shaah zmanis</em>. This is identical to 1/6th of the day from
503             * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
504             * 
505             * @return the <code>long</code> millisecond length of a
506             *         <em>shaah zmanis</em>.
507             * @see #getAlos120Zmanis()
508             * @see #getTzais120Zmanis()
509             */
510            public long getShaahZmanis120MinutesZmanis() {
511                    return getTemporalHour(getAlos120Zmanis(), getTzais120Zmanis());
512            }
513    
514            /**
515             * This method returns the time of <em>plag hamincha</em>. This is
516             * calculated as 10.75 hours after {@link #getAlos96Zmanis() dawn}. The
517             * formula used is:<br/> 10.75 * {@link #getShaahZmanis96MinutesZmanis()}
518             * after {@link #getAlos96Zmanis() dawn}.
519             * 
520             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
521             */
522            public Date getPlagHamincha120MinutesZmanis() {
523                    return getTimeOffset(getAlos120Zmanis(),
524                                    getShaahZmanis120MinutesZmanis() * 10.75);
525            }
526    
527            /**
528             * This method returns the time of <em>plag hamincha</em>. This is
529             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
530             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
531             * {@link #getAlos72()}.
532             * 
533             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
534             */
535            public Date getPlagHamincha120Minutes() {
536                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 10.75);
537            }
538    
539            /**
540             * Method to return <em>alos</em> (dawn) calculated using 60 minutes
541             * before {@link #getSeaLevelSunrise() sea level sunrise} on the time to
542             * walk the distance of 4 <em>Mil</em> at 15 minutes a <em>Mil</em> (the
543             * opinion of the Chavas Yair. See the Divray Malkiel). This is based on the
544             * opinion of most <em>Rishonim</em> who stated that the time of the
545             * <em>Neshef</em> (time between dawn and sunrise) does not vary by the
546             * time of year or location but purely depends on the time it takes to walk
547             * the distance of 4 <em>Mil</em>.
548             * 
549             * @return the <code>Date</code> representing the time.
550             */
551            public Date getAlos60() {
552                    return getTimeOffset(getSeaLevelSunrise(), -60 * MINUTE_MILLIS);
553            }
554    
555            /**
556             * Method to return <em>alos</em> (dawn) calculated using 72 minutes
557             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
558             * or 1/10th of the day before sea level sunrise. This is based on an 18
559             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 72 minutes
560             * which is 1/10th of a day (12 * 60 = 720) based on the day starting at
561             * {@link #getSeaLevelSunrise() sea level sunrise} and ending at
562             * {@link #getSeaLevelSunset() sea level sunset}. The actual alculation is
563             * {@link #getSeaLevelSunrise()}- ( {@link #getShaahZmanisGra()} * 1.2).
564             * This calculation is used in the calendars published by
565             * <em>Hisachdus Harabanim D'Artzos Habris Ve'Kanada</em>
566             * 
567             * @return the <code>Date</code> representing the time.
568             * @see #getShaahZmanisGra()
569             */
570            public Date getAlos72Zmanis() {
571                    long shaahZmanis = getShaahZmanisGra();
572                    if (shaahZmanis == Long.MIN_VALUE) {
573                            return null;
574                    }
575                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.2));
576            }
577    
578            /**
579             * Method to return <em>alos</em> (dawn) calculated using 96 minutes
580             * before {@link #getSeaLevelSunrise() sea level sunrise} based on the time
581             * to walk the distance of 4 <em>Mil</em> at 24 minutes a <em>Mil</em>.
582             * This is based on the opinion of most <em>Rishonim</em> who stated that
583             * the time of the <em>Neshef</em> (time between dawn and sunrise) does
584             * not vary by the time of year or location but purely depends on the time
585             * it takes to walk the distance of 4 <em>Mil</em>.
586             * 
587             * @return the <code>Date</code> representing the time.
588             */
589            public Date getAlos96() {
590                    return getTimeOffset(getSeaLevelSunrise(), -96 * MINUTE_MILLIS);
591            }
592    
593            /**
594             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
595             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
596             * or 1/8th of the day before sea level sunrise. This is based on a 22.5
597             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 90 minutes
598             * which is 1/8th of a day (12 * 60 = 720) /8 =90 based on the day starting
599             * at {@link #getSunrise() sunrise} and ending at
600             * {@link #getSunset() sunset}. The actual calculation is
601             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 1.5).
602             * 
603             * @return the <code>Date</code> representing the time.
604             * @see #getShaahZmanisGra()
605             */
606            public Date getAlos90Zmanis() {
607                    long shaahZmanis = getShaahZmanisGra();
608                    if (shaahZmanis == Long.MIN_VALUE) {
609                            return null;
610                    }
611                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.5));
612            }
613    
614            /**
615             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
616             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
617             * or 1/8th of the day before sea level sunrise. This is based on a 24
618             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 90 minutes
619             * which is 1/7.5th of a day (12 * 60 = 720) / 7.5 =96 based on the day
620             * starting at {@link #getSunrise() sunrise} and ending at
621             * {@link #getSunset() sunset}. The actual calculation is
622             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 1.6).
623             * 
624             * @return the <code>Date</code> representing the time.
625             * @see #getShaahZmanisGra()
626             */
627            public Date getAlos96Zmanis() {
628                    long shaahZmanis = getShaahZmanisGra();
629                    if (shaahZmanis == Long.MIN_VALUE) {
630                            return null;
631                    }
632                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.6));
633            }
634    
635            /**
636             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
637             * before {@link #getSeaLevelSunrise() sea level sunrise} on the time to
638             * walk the distance of 4 <em>Mil</em> at 22.5 minutes a <em>Mil</em>.
639             * This is based on the opinion of most <em>Rishonim</em> who stated that
640             * the time of the <em>Neshef</em> (time between dawn and sunrise) does
641             * not vary by the time of year or location but purely depends on the time
642             * it takes to walk the distance of 4 <em>Mil</em>.
643             * 
644             * @return the <code>Date</code> representing the time.
645             */
646            public Date getAlos90() {
647                    return getTimeOffset(getSeaLevelSunrise(), -90 * MINUTE_MILLIS);
648            }
649    
650            /**
651             * Method to return <em>alos</em> (dawn) calculated using 120 minutes
652             * before {@link #getSeaLevelSunrise() sea level sunrise} (no adjustment for
653             * elevation is made) based on the time to walk the distance of 5
654             * <em>Mil</em>( <em>Ula</em>) at 24 minutes a <em>Mil</em>. This
655             * is based on the opinion of most <em>Rishonim</em> who stated that the
656             * time of the <em>Neshef</em> (time between dawn and sunrise) does not
657             * vary by the time of year or location but purely depends on the time it
658             * takes to walk the distance of 5 <em>Mil</em>(<em>Ula</em>).
659             * 
660             * @return the <code>Date</code> representing the time.
661             */
662            public Date getAlos120() {
663                    return getTimeOffset(getSeaLevelSunrise(), -120 * MINUTE_MILLIS);
664            }
665    
666            /**
667             * Method to return <em>alos</em> (dawn) calculated using 120 minutes
668             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
669             * or 1/6th of the day before sea level sunrise. This is based on a 24
670             * minute <em>Mil</em> so the time for 5 <em>Mil</em> is 120 minutes
671             * which is 1/6th of a day (12 * 60 = 720) / 6 =120 based on the day
672             * starting at {@link #getSunrise() sunrise} and ending at
673             * {@link #getSunset() sunset}. The actual calculation is
674             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 2).
675             * 
676             * @return the <code>Date</code> representing the time.
677             * @see #getShaahZmanisGra()
678             */
679            public Date getAlos120Zmanis() {
680                    long shaahZmanis = getShaahZmanisGra();
681                    if (shaahZmanis == Long.MIN_VALUE) {
682                            return null;
683                    }
684                    return getTimeOffset(getSeaLevelSunrise(), shaahZmanis * -2);
685            }
686    
687            /**
688             * Method to return <em>alos</em> (dawn) calculated when the sun is
689             * {@link #ZENITH_26_DEGREES 26&deg;} below the eastern geometric horizon
690             * before sunrise. This calculation is based on the same calculation of
691             * {@link #getAlos120() 120 minutes} but uses a degree based calculation
692             * instead of 120 exact minutes. This calculation is based on the position
693             * of the sun 120 minutes before sunrise in Jerusalem in the equinox which
694             * calculates to 26&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}.
695             * 
696             * @return the <code>Date</code> representing <em>alos</em>.
697             * @see #ZENITH_26_DEGREES
698             * @see #getAlos120()
699             * @see #getTzais120()
700             */
701            public Date getAlos26Degrees() {
702                    return getSunriseOffsetByDegrees(ZENITH_26_DEGREES);
703            }
704    
705            /**
706             * to return <em>alos</em> (dawn) calculated when the sun is
707             * {@link #ASTRONOMICAL_ZENITH 18&deg;} below the eastern geometric horizon
708             * before sunrise.
709             * 
710             * @return the <code>Date</code> representing <em>alos</em>.
711             * @see #ASTRONOMICAL_ZENITH
712             */
713            public Date getAlos18Degrees() {
714                    return getSunriseOffsetByDegrees(ASTRONOMICAL_ZENITH);
715            }
716    
717            /**
718             * Method to return <em>alos</em> (dawn) calculated when the sun is
719             * {@link #ZENITH_19_POINT_8 19.8&deg;} below the eastern geometric horizon
720             * before sunrise. This calculation is based on the same calculation of
721             * {@link #getAlos90() 90 minutes} but uses a degree based calculation
722             * instead of 90 exact minutes. This calculation is based on the position of
723             * the sun 90 minutes before sunrise in Jerusalem in the equinox which
724             * calculates to 19.8&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
725             * 
726             * @return the <code>Date</code> representing <em>alos</em>.
727             * @see #ZENITH_19_POINT_8
728             * @see #getAlos90()
729             */
730            public Date getAlos19Point8Degrees() {
731                    return getSunriseOffsetByDegrees(ZENITH_19_POINT_8);
732            }
733    
734            /**
735             * Method to return <em>alos</em> (dawn) calculated when the sun is
736             * {@link #ZENITH_16_POINT_1 16.1&deg;} below the eastern geometric horizon
737             * before sunrise. This calculation is based on the same calculation of
738             * {@link #getAlos72() 72 minutes} but uses a degree based calculation
739             * instead of 72 exact minutes. This calculation is based on the position of
740             * the sun 72 minutes before sunrise in Jerusalem in the equinox which
741             * calculates to 16.1&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}.
742             * 
743             * @return the <code>Date</code> representing <em>alos</em>.
744             * @see #ZENITH_16_POINT_1
745             * @see #getAlos72()
746             */
747            public Date getAlos16Point1Degrees() {
748                    return getSunriseOffsetByDegrees(ZENITH_16_POINT_1);
749            }
750    
751            /**
752             * This method returns <em>misheyakir</em> based on the position of the
753             * sun when it is {@link #ZENITH_11_DEGREES 11.5&deg;} below
754             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
755             * is used for calculating <em>misheyakir</em> according to some opinions.
756             * This calculation is based on the position of the sun 52 minutes before
757             * {@link #getSunrise sunrise}in Jerusalem in the equinox which calculates
758             * to 11.5&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
759             * 
760             * @see #ZENITH_11_POINT_5
761             */
762            public Date getMisheyakir11Point5Degrees() {
763                    return getSunriseOffsetByDegrees(ZENITH_11_POINT_5);
764            }
765    
766            /**
767             * This method returns <em>misheyakir</em> based on the position of the
768             * sun when it is {@link #ZENITH_11_DEGREES 11&deg;} below
769             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
770             * is used for calculating <em>misheyakir</em> according to some opinions.
771             * This calculation is based on the position of the sun 48 minutes before
772             * {@link #getSunrise sunrise}in Jerusalem in the equinox which calculates
773             * to 11&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
774             * 
775             * @see #ZENITH_11_DEGREES
776             */
777            public Date getMisheyakir11Degrees() {
778                    return getSunriseOffsetByDegrees(ZENITH_11_DEGREES);
779            }
780    
781            /**
782             * This method returns <em>misheyakir</em> based on the position of the
783             * sun when it is {@link #ZENITH_10_POINT_2 10.2&deg;} below
784             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
785             * is used for calculating <em>misheyakir</em> according to some opinions.
786             * This calculation is based on the position of the sun 45 minutes before
787             * {@link #getSunrise sunrise} in Jerusalem in the equinox which calculates
788             * to 10.2&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
789             * 
790             * @see #ZENITH_10_POINT_2
791             */
792            public Date getMisheyakir10Point2Degrees() {
793                    return getSunriseOffsetByDegrees(ZENITH_10_POINT_2);
794            }
795    
796            /**
797             * This method returns the latest <em>zman krias shema</em> (time to say
798             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
799             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 19.8&deg;}
800             * before {@link #getSunrise() sunrise}. This time is 3
801             * <em>{@link #getShaahZmanis19Point8Degrees() shaos zmaniyos}</em> (solar
802             * hours) after {@link #getAlos19Point8Degrees() dawn} based on the opinion
803             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
804             * with both being 19.8&deg; below sunrise or sunset. This returns the time
805             * of 3 *{@link #getShaahZmanis19Point8Degrees()} after
806             * {@link #getAlos19Point8Degrees() dawn}.
807             * 
808             * @return the <code>Date</code> of the latest zman shema.
809             * @see #getShaahZmanis19Point8Degrees()
810             * @see #getAlos19Point8Degrees()
811             */
812            public Date getSofZmanShmaMGA19Point8Degrees() {
813                    return getTimeOffset(getAlos19Point8Degrees(),
814                                    getShaahZmanis19Point8Degrees() * 3);
815            }
816    
817            /**
818             * This method returns the latest <em>zman krias shema</em> (time to say
819             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
820             * <em>alos</em> being {@link #getAlos16Point1Degrees()() 16.1&deg;}
821             * before {@link #getSunrise() sunrise}. This time is 3
822             * <em>{@link #getShaahZmanis16Point1Degrees() shaos zmaniyos}</em> (solar
823             * hours) after {@link #getAlos16Point1Degrees() dawn} based on the opinion
824             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
825             * with both being 16.1&deg; below sunrise or sunset. This returns the time
826             * of 3 *{@link #getShaahZmanis16Point1Degrees()} after
827             * {@link #getAlos16Point1Degrees() dawn}.
828             * 
829             * @return the <code>Date</code> of the latest zman shema.
830             * @see #getShaahZmanis16Point1Degrees()
831             * @see #getAlos16Point1Degrees()
832             */
833            public Date getSofZmanShmaMGA16Point1Degrees() {
834                    return getTimeOffset(getAlos16Point1Degrees(),
835                                    getShaahZmanis16Point1Degrees() * 3);
836            }
837    
838            /**
839             * This method returns the latest <em>zman krias shema</em> (time to say
840             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
841             * <em>alos</em> being {@link #getAlos72() 72} minutes before
842             * {@link #getSunrise() sunrise}. This time is 3
843             * <em>{@link #getShaahZmanis72Minutes() shaos zmaniyos}</em> (solar
844             * hours) after {@link #getAlos72() dawn} based on the opinion of the
845             * <em>MG"A</em> that the day is calculated from a
846             * {@link #getAlos72() dawn} of 72 minutes before sunrise to
847             * {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns
848             * the time of 3 * {@link #getShaahZmanis72Minutes()} after
849             * {@link #getAlos72() dawn}. This class returns an identical time to
850             * {@link #getSofZmanShmaMGA()} and is repeated here for clarity.
851             * 
852             * @return the <code>Date</code> of the latest zman shema.
853             * @see #getShaahZmanis72Minutes()
854             * @see #getAlos72()
855             * @see #getSofZmanShmaMGA()
856             */
857            public Date getSofZmanShmaMGA72Minutes() {
858                    return getSofZmanShmaMGA();
859            }
860    
861            /**
862             * This method returns the latest <em>zman krias shema</em> (time to say
863             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
864             * <em>alos</em> being {@link #getAlos72Zmanis() 72} minutes
865             * <em>zmaniyos</em>, or 1/10th of the day before
866             * {@link #getSunrise() sunrise}. This time is 3
867             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
868             * hours) after {@link #getAlos72Zmanis() dawn} based on the opinion of the
869             * <em>MG"A</em> that the day is calculated from a
870             * {@link #getAlos72Zmanis() dawn} of 72 minutes <em>zmaniyos</em>, or
871             * 1/10th of the day before {@link #getSeaLevelSunrise() sea level sunrise}
872             * to {@link #getTzais72Zmanis() nightfall} of 72 minutes <em>zmaniyos</em>
873             * after {@link #getSeaLevelSunset() sea level sunset}. This returns the
874             * time of 3 * {@link #getShaahZmanis72MinutesZmanis()} after
875             * {@link #getAlos72Zmanis() dawn}.
876             * 
877             * @return the <code>Date</code> of the latest zman shema.
878             * @see #getShaahZmanis72MinutesZmanis()
879             * @see #getAlos72Zmanis()
880             */
881            public Date getSofZmanShmaMGA72MinutesZmanis() {
882                    return getTimeOffset(getAlos72Zmanis(),
883                                    getShaahZmanis72MinutesZmanis() * 3);
884            }
885    
886            /**
887             * This method returns the latest <em>zman krias shema</em> (time to say
888             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
889             * <em>alos</em> being {@link #getAlos90() 90} minutes before
890             * {@link #getSunrise() sunrise}. This time is 3
891             * <em>{@link #getShaahZmanis90Minutes() shaos zmaniyos}</em> (solar
892             * hours) after {@link #getAlos90() dawn} based on the opinion of the
893             * <em>MG"A</em> that the day is calculated from a
894             * {@link #getAlos90() dawn} of 90 minutes before sunrise to
895             * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns
896             * the time of 3 * {@link #getShaahZmanis90Minutes()} after
897             * {@link #getAlos90() dawn}.
898             * 
899             * @return the <code>Date</code> of the latest zman shema.
900             * @see #getShaahZmanis90Minutes()
901             * @see #getAlos90()
902             */
903            public Date getSofZmanShmaMGA90Minutes() {
904                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 3);
905            }
906    
907            /**
908             * This method returns the latest <em>zman krias shema</em> (time to say
909             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
910             * <em>alos</em> being {@link #getAlos90Zmanis() 90} minutes
911             * <em>zmaniyos</em> before {@link #getSunrise() sunrise}. This time is 3
912             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
913             * hours) after {@link #getAlos90Zmanis() dawn} based on the opinion of the
914             * <em>MG"A</em> that the day is calculated from a
915             * {@link #getAlos90Zmanis() dawn} of 90 minutes <em>zmaniyos</em> before
916             * sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
917             * <em>zmaniyos</em> after sunset. This returns the time of 3 *
918             * {@link #getShaahZmanis90MinutesZmanis()} after
919             * {@link #getAlos90Zmanis() dawn}.
920             * 
921             * @return the <code>Date</code> of the latest zman shema.
922             * @see #getShaahZmanis90MinutesZmanis()
923             * @see #getAlos90Zmanis()
924             */
925            public Date getSofZmanShmaMGA90MinutesZmanis() {
926                    return getTimeOffset(getAlos90Zmanis(),
927                                    getShaahZmanis90MinutesZmanis() * 3);
928            }
929    
930            /**
931             * This method returns the latest <em>zman krias shema</em> (time to say
932             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
933             * <em>alos</em> being {@link #getAlos96() 96} minutes before
934             * {@link #getSunrise() sunrise}. This time is 3
935             * <em>{@link #getShaahZmanis96Minutes() shaos zmaniyos}</em> (solar
936             * hours) after {@link #getAlos96() dawn} based on the opinion of the
937             * <em>MG"A</em> that the day is calculated from a
938             * {@link #getAlos96() dawn} of 96 minutes before sunrise to
939             * {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns
940             * the time of 3 * {@link #getShaahZmanis96Minutes()} after
941             * {@link #getAlos96() dawn}.
942             * 
943             * @return the <code>Date</code> of the latest zman shema.
944             * @see #getShaahZmanis96Minutes()
945             * @see #getAlos96()
946             */
947            public Date getSofZmanShmaMGA96Minutes() {
948                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 3);
949            }
950    
951            /**
952             * This method returns the latest <em>zman krias shema</em> (time to say
953             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
954             * <em>alos</em> being {@link #getAlos90Zmanis() 96} minutes
955             * <em>zmaniyos</em> before {@link #getSunrise() sunrise}. This time is 3
956             * <em>{@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos}</em> (solar
957             * hours) after {@link #getAlos96Zmanis() dawn} based on the opinion of the
958             * <em>MG"A</em> that the day is calculated from a
959             * {@link #getAlos96Zmanis() dawn} of 96 minutes <em>zmaniyos</em> before
960             * sunrise to {@link #getTzais90Zmanis() nightfall} of 96 minutes
961             * <em>zmaniyos</em> after sunset. This returns the time of 3 *
962             * {@link #getShaahZmanis96MinutesZmanis()} after
963             * {@link #getAlos96Zmanis() dawn}.
964             * 
965             * @return the <code>Date</code> of the latest zman shema.
966             * @see #getShaahZmanis96MinutesZmanis()
967             * @see #getAlos96Zmanis()
968             */
969            public Date getSofZmanShmaMGA96MinutesZmanis() {
970                    return getTimeOffset(getAlos96Zmanis(),
971                                    getShaahZmanis96MinutesZmanis() * 3);
972            }
973    
974            /**
975             * This method returns the latest <em>zman krias shema</em> (time to say
976             * Shema in the morning) calculated as 3 hours (regular and not zmaniyos)
977             * before {@link ZmanimCalendar#getChatzos()}. This is the opinion of the
978             * <em>Shach</em> in the
979             * <em>Nekudas Hakesef (Yora Deah 184), Shevus Yaakov, Chasan Sofer</em>
980             * and others.This returns the time of 3 hours before
981             * {@link ZmanimCalendar#getChatzos()}.
982             * 
983             * @return the <code>Date</code> of the latest zman shema.
984             * @see ZmanimCalendar#getChatzos()
985             * @see #getSofZmanTfila2HoursBeforeChatzos()
986             */
987            public Date getSofZmanShma3HoursBeforeChatzos() {
988                    return getTimeOffset(getChatzos(), -180 * MINUTE_MILLIS);
989            }
990    
991            /**
992             * This method returns the latest <em>zman krias shema</em> (time to say
993             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
994             * <em>alos</em> being {@link #getAlos120() 120} minutes or 1/6th of the
995             * day before {@link #getSunrise() sunrise}. This time is 3
996             * <em>{@link #getShaahZmanis120Minutes() shaos zmaniyos}</em> (solar
997             * hours) after {@link #getAlos120() dawn} based on the opinion of the
998             * <em>MG"A</em> that the day is calculated from a
999             * {@link #getAlos120() dawn} of 120 minutes before sunrise to
1000             * {@link #getTzais120() nightfall} of 120 minutes after sunset. This
1001             * returns the time of 3 *{@link #getShaahZmanis120Minutes()} after
1002             * {@link #getAlos120() dawn}.
1003             * 
1004             * @return the <code>Date</code> of the latest zman shema.
1005             * @see #getShaahZmanis120Minutes()
1006             * @see #getAlos120()
1007             */
1008            public Date getSofZmanShmaMGA120Minutes() {
1009                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 3);
1010            }
1011    
1012            /**
1013             * This method returns the latest <em>zman krias shema</em> (time to say
1014             * Shema in the morning) based on the opinion that the day starts at
1015             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1016             * {@link #getSunset() sunset}. 3 shaos zmaniyos are calculated based on
1017             * this day and added to {@link #getAlos16Point1Degrees() alos}to reach
1018             * this time. This time is 3 <em>shaos zmaniyos</em> (solar hours) after
1019             * {@link #getAlos16Point1Degrees() dawn} based on the opinion that the day
1020             * is calculated from a {@link #getAlos16Point1Degrees() alos 16.1&deg;} to
1021             * {@link #getSunset() sunset}.<br />
1022             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1023             * midday.
1024             * 
1025             * @return the <code>Date</code> of the latest zman shema based on this
1026             *         day.
1027             * @see #getAlos16Point1Degrees()
1028             * @see #getSunset()
1029             */
1030            public Date getSofZmanShmaAlos16Point1ToSunset() {
1031                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1032                                    getSunset());
1033                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 3);
1034            }
1035    
1036            /**
1037             * This method returns the latest <em>zman krias shema</em> (time to say
1038             * Shema in the morning) based on the opinion that the day starts at
1039             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1040             * {@link #getTzaisGeonim7Point083Degrees() tzais 7.083&deg;}. 3
1041             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1042             * {@link #getAlos16Point1Degrees() alos} to reach this time. This time is 3
1043             * <em>shaos zmaniyos</em> (temporal hours) after
1044             * {@link #getAlos16Point1Degrees() alos 16.1&deg;} based on the opinion
1045             * that the day is calculated from a
1046             * {@link #getAlos16Point1Degrees() alos 16.1&deg;} to
1047             * <em>{@link #getTzaisGeonim7Point083Degrees() tzais 7.083&deg;}</em>.<br />
1048             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1049             * midday.
1050             * 
1051             * @return the <code>Date</code> of the latest zman shema based on this
1052             *         calculation.
1053             * @see #getAlos16Point1Degrees()
1054             * @see #getTzaisGeonim7Point083Degrees()
1055             */
1056            public Date getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees() {
1057                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1058                                    getTzaisGeonim7Point083Degrees());
1059                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 3);
1060            }
1061    
1062            /**
1063             * From the GR"A in Kol Eliyahu on Berachos #173 that states that zman krias
1064             * shema is calculated as half the time from sunrise to fixed local chatzos.
1065             * The GR"A himself seems to contradic this when he stated that zman krias
1066             * shema is 1/4 of the day from sunrise to sunset. See Sarah Lamoed #25 in
1067             * Yisroel Vehazmanim Vol III page 1016.
1068             * 
1069             * @return the <code>Date</code> of the latest zman shema based on this
1070             *         calculation.
1071             * @see #getFixedLocalChatzos()
1072             */
1073            public Date getSofZmanShmaKolEliyahu() {
1074                    Date chatzos = getFixedLocalChatzos();
1075                    if (chatzos == null || getSunrise() == null) {
1076                            return null;
1077                    }
1078                    long diff = (chatzos.getTime() - getSunrise().getTime()) / 2;
1079                    return getTimeOffset(chatzos, -diff);
1080            }
1081    
1082            /**
1083             * This method returns the latest <em>zman tfila</em> (time to say the
1084             * morning prayers) in the opinion of the <em>MG"A</em> based on
1085             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 19.8&deg;}
1086             * before {@link #getSunrise() sunrise}. This time is 4
1087             * <em>{@link #getShaahZmanis19Point8Degrees() shaos zmaniyos}</em> (solar
1088             * hours) after {@link #getAlos19Point8Degrees() dawn} based on the opinion
1089             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
1090             * with both being 19.8&deg; below sunrise or sunset. This returns the time
1091             * of 4 *{@link #getShaahZmanis19Point8Degrees()} after
1092             * {@link #getAlos19Point8Degrees() dawn}.
1093             * 
1094             * @return the <code>Date</code> of the latest zman shema.
1095             * 
1096             * @see #getShaahZmanis19Point8Degrees()
1097             * @see #getAlos19Point8Degrees()
1098             */
1099            public Date getSofZmanTfilaMGA19Point8Degrees() {
1100                    return getTimeOffset(getAlos19Point8Degrees(),
1101                                    getShaahZmanis19Point8Degrees() * 4);
1102            }
1103    
1104            /**
1105             * This method returns the latest <em>zman tfila</em> (time to say the
1106             * morning prayers) in the opinion of the <em>MG"A</em> based on
1107             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 16.1&deg;}
1108             * before {@link #getSunrise() sunrise}. This time is 4
1109             * <em>{@link #getShaahZmanis16Point1Degrees() shaos zmaniyos}</em> (solar
1110             * hours) after {@link #getAlos16Point1Degrees() dawn} based on the opinion
1111             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
1112             * with both being 16.1&deg; below sunrise or sunset. This returns the time
1113             * of 4 *{@link #getShaahZmanis16Point1Degrees()} after
1114             * {@link #getAlos16Point1Degrees() dawn}.
1115             * 
1116             * @return the <code>Date</code> of the latest zman shema.
1117             * 
1118             * @see #getShaahZmanis16Point1Degrees()
1119             * @see #getAlos16Point1Degrees()
1120             */
1121            public Date getSofZmanTfilaMGA16Point1Degrees() {
1122                    return getTimeOffset(getAlos16Point1Degrees(),
1123                                    getShaahZmanis16Point1Degrees() * 4);
1124            }
1125    
1126            /**
1127             * This method returns the latest <em>zman tfila</em> (time to say the
1128             * morning prayers) in the opinion of the <em>MG"A</em> based on
1129             * <em>alos</em> being {@link #getAlos72() 72} minutes before
1130             * {@link #getSunrise() sunrise}. This time is 4
1131             * <em>{@link #getShaahZmanis72Minutes() shaos zmaniyos}</em> (solar
1132             * hours) after {@link #getAlos72() dawn} based on the opinion of the
1133             * <em>MG"A</em> that the day is calculated from a
1134             * {@link #getAlos72() dawn} of 72 minutes before sunrise to
1135             * {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns
1136             * the time of 4 * {@link #getShaahZmanis72Minutes()} after
1137             * {@link #getAlos72() dawn}. This class returns an identical time to
1138             * {@link #getSofZmanTfilaMGA()} and is repeated here for clarity.
1139             * 
1140             * @return the <code>Date</code> of the latest zman tfila.
1141             * @see #getShaahZmanis72Minutes()
1142             * @see #getAlos72()
1143             * @see #getSofZmanShmaMGA()
1144             */
1145            public Date getSofZmanTfilaMGA72Minutes() {
1146                    return getSofZmanTfilaMGA();
1147            }
1148    
1149            /**
1150             * This method returns the latest <em>zman tfila</em> (time to the morning
1151             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1152             * being {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> before
1153             * {@link #getSunrise() sunrise}. This time is 4
1154             * <em>{@link #getShaahZmanis72MinutesZmanis() shaos zmaniyos}</em> (solar
1155             * hours) after {@link #getAlos72Zmanis() dawn} based on the opinion of the
1156             * <em>MG"A</em> that the day is calculated from a
1157             * {@link #getAlos72Zmanis() dawn} of 72 minutes <em>zmaniyos</em> before
1158             * sunrise to {@link #getTzais72Zmanis() nightfall} of 72 minutes
1159             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1160             * {@link #getShaahZmanis72MinutesZmanis()} after
1161             * {@link #getAlos72Zmanis() dawn}.
1162             * 
1163             * @return the <code>Date</code> of the latest zman shema.
1164             * @see #getShaahZmanis72MinutesZmanis()
1165             * @see #getAlos72Zmanis()
1166             */
1167            public Date getSofZmanTfilaMGA72MinutesZmanis() {
1168                    return getTimeOffset(getAlos72Zmanis(),
1169                                    getShaahZmanis72MinutesZmanis() * 4);
1170            }
1171    
1172            /**
1173             * This method returns the latest <em>zman tfila</em> (time to say the
1174             * morning prayers) in the opinion of the <em>MG"A</em> based on
1175             * <em>alos</em> being {@link #getAlos90() 90} minutes before
1176             * {@link #getSunrise() sunrise}. This time is 4
1177             * <em>{@link #getShaahZmanis90Minutes() shaos zmaniyos}</em> (solar
1178             * hours) after {@link #getAlos90() dawn} based on the opinion of the
1179             * <em>MG"A</em> that the day is calculated from a
1180             * {@link #getAlos90() dawn} of 90 minutes before sunrise to
1181             * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns
1182             * the time of 4 * {@link #getShaahZmanis90Minutes()} after
1183             * {@link #getAlos90() dawn}.
1184             * 
1185             * @return the <code>Date</code> of the latest zman tfila.
1186             * @see #getShaahZmanis90Minutes()
1187             * @see #getAlos90()
1188             */
1189            public Date getSofZmanTfilaMGA90Minutes() {
1190                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 4);
1191            }
1192    
1193            /**
1194             * This method returns the latest <em>zman tfila</em> (time to the morning
1195             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1196             * being {@link #getAlos90Zmanis() 90} minutes <em>zmaniyos</em> before
1197             * {@link #getSunrise() sunrise}. This time is 4
1198             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
1199             * hours) after {@link #getAlos90Zmanis() dawn} based on the opinion of the
1200             * <em>MG"A</em> that the day is calculated from a
1201             * {@link #getAlos90Zmanis() dawn} of 90 minutes <em>zmaniyos</em> before
1202             * sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
1203             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1204             * {@link #getShaahZmanis90MinutesZmanis()} after
1205             * {@link #getAlos90Zmanis() dawn}.
1206             * 
1207             * @return the <code>Date</code> of the latest zman shema.
1208             * @see #getShaahZmanis90MinutesZmanis()
1209             * @see #getAlos90Zmanis()
1210             */
1211            public Date getSofZmanTfilaMGA90MinutesZmanis() {
1212                    return getTimeOffset(getAlos90Zmanis(),
1213                                    getShaahZmanis90MinutesZmanis() * 4);
1214            }
1215    
1216            /**
1217             * This method returns the latest <em>zman tfila</em> (time to say the
1218             * morning prayers) in the opinion of the <em>MG"A</em> based on
1219             * <em>alos</em> being {@link #getAlos96() 96} minutes before
1220             * {@link #getSunrise() sunrise}. This time is 4
1221             * <em>{@link #getShaahZmanis96Minutes() shaos zmaniyos}</em> (solar
1222             * hours) after {@link #getAlos96() dawn} based on the opinion of the
1223             * <em>MG"A</em> that the day is calculated from a
1224             * {@link #getAlos96() dawn} of 96 minutes before sunrise to
1225             * {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns
1226             * the time of 4 * {@link #getShaahZmanis96Minutes()} after
1227             * {@link #getAlos96() dawn}.
1228             * 
1229             * @return the <code>Date</code> of the latest zman tfila.
1230             * @see #getShaahZmanis96Minutes()
1231             * @see #getAlos96()
1232             */
1233            public Date getSofZmanTfilaMGA96Minutes() {
1234                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 4);
1235            }
1236    
1237            /**
1238             * This method returns the latest <em>zman tfila</em> (time to the morning
1239             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1240             * being {@link #getAlos96Zmanis() 96} minutes <em>zmaniyos</em> before
1241             * {@link #getSunrise() sunrise}. This time is 4
1242             * <em>{@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos}</em> (solar
1243             * hours) after {@link #getAlos96Zmanis() dawn} based on the opinion of the
1244             * <em>MG"A</em> that the day is calculated from a
1245             * {@link #getAlos96Zmanis() dawn} of 96 minutes <em>zmaniyos</em> before
1246             * sunrise to {@link #getTzais96Zmanis() nightfall} of 96 minutes
1247             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1248             * {@link #getShaahZmanis96MinutesZmanis()} after
1249             * {@link #getAlos96Zmanis() dawn}.
1250             * 
1251             * @return the <code>Date</code> of the latest zman shema.
1252             * @see #getShaahZmanis90MinutesZmanis()
1253             * @see #getAlos90Zmanis()
1254             */
1255            public Date getSofZmanTfilaMGA96MinutesZmanis() {
1256                    return getTimeOffset(getAlos96Zmanis(),
1257                                    getShaahZmanis96MinutesZmanis() * 4);
1258            }
1259    
1260            /**
1261             * This method returns the latest <em>zman tfila</em> (time to say the
1262             * morning prayers) in the opinion of the <em>MG"A</em> based on
1263             * <em>alos</em> being {@link #getAlos120() 120} minutes before
1264             * {@link #getSunrise() sunrise}. This time is 4
1265             * <em>{@link #getShaahZmanis120Minutes() shaos zmaniyos}</em> (solar
1266             * hours) after {@link #getAlos120() dawn} based on the opinion of the
1267             * <em>MG"A</em> that the day is calculated from a
1268             * {@link #getAlos120() dawn} of 120 minutes before sunrise to
1269             * {@link #getTzais120() nightfall} of 120 minutes after sunset. This
1270             * returns the time of 4 *{@link #getShaahZmanis120Minutes()} after
1271             * {@link #getAlos120() dawn}.
1272             * 
1273             * @return the <code>Date</code> of the latest zman shema.
1274             * @see #getShaahZmanis120Minutes()
1275             * @see #getAlos120()
1276             */
1277            public Date getSofZmanTfilaMGA120Minutes() {
1278                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 4);
1279            }
1280    
1281            /**
1282             * This method returns the latest <em>zman tfila</em> (time to say the
1283             * morning prayers) calculated as 2 hours befor
1284             * {@link ZmanimCalendar#getChatzos()}. This is based on the opinions that
1285             * calculate <em>sof zman krias shema</em> as
1286             * {@link #getSofZmanShma3HoursBeforeChatzos()}. This returns the time of 2
1287             * hours before {@link ZmanimCalendar#getChatzos()}.
1288             * 
1289             * @return the <code>Date</code> of the latest zman shema.
1290             * @see ZmanimCalendar#getChatzos()
1291             * @see #getSofZmanShma3HoursBeforeChatzos()
1292             */
1293            public Date getSofZmanTfila2HoursBeforeChatzos() {
1294                    return getTimeOffset(getChatzos(), -120 * MINUTE_MILLIS);
1295            }
1296    
1297            /**
1298             * This method returns mincha gedola calculated as 30 minutes after
1299             * <em>{@link #getChatzos() chatzos}</em> and not 1/2 of a
1300             * <em>{@link #getShaahZmanisGra() shaah zmanis}</em> after
1301             * <em>{@link #getChatzos() chatzos}</em> as calculated by
1302             * {@link #getMinchaGedola}. Some use this time to delay the start of
1303             * mincha in the winter when 1/2 of a
1304             * <em>{@link #getShaahZmanisGra() shaah zmanis}</em> is less than 30
1305             * minutes. See {@link #getMinchaGedolaGreaterThan30()}for a conveniance
1306             * method that returns the later of the 2 calculations. One should not use
1307             * this time to start <em>mincha</em> before the standard
1308             * <em>{@link #getMinchaGedola() mincha gedola}</em>. See
1309             * <em>Shulchan Aruch
1310             * Orach Chayim Siman Raish Lamed Gimel seif alef</em>
1311             * and the <em>Shaar Hatziyon seif katan ches</em>.
1312             * 
1313             * @return the <code>Date</code> of 30 mintes after <em>chatzos</em>.
1314             * @see #getMinchaGedola()
1315             * @see #getMinchaGedolaGreaterThan30()
1316             */
1317            public Date getMinchaGedola30Minutes() {
1318                    return getTimeOffset(getChatzos(), MINUTE_MILLIS * 30);
1319            }
1320    
1321            /**
1322             * This method returns the time of <em>mincha gedola</em> according to the
1323             * Magen Avraham with the day starting 72 minutes before sunrise and ending
1324             * 72 minutes after sunset. This is the earliest time to pray
1325             * <em>mincha</em>. For more information on this see the documentation on
1326             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1327             * as 6.5 {@link #getTemporalHour() solar hours} after alos. The calculation
1328             * used is 6.5 * {@link #getShaahZmanis72Minutes()} after
1329             * {@link #getAlos72() alos}.
1330             * 
1331             * @see #getAlos72()()
1332             * @see #getMinchaGedola()
1333             * @see #getMinchaKetana()
1334             * @see ZmanimCalendar#getMinchaGedola()
1335             * @return the <code>Date</code> of the time of mincha gedola.
1336             */
1337            public Date getMinchaGedola72Minutes() {
1338                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 6.5);
1339            }
1340    
1341            /**
1342             * This method returns the time of <em>mincha gedola</em> according to the
1343             * Magen Avraham with the day starting and ending 16.1&deg; below the
1344             * horizon. This is the earliest time to pray <em>mincha</em>. For more
1345             * information on this see the documentation on
1346             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1347             * as 6.5 {@link #getTemporalHour() solar hours} after alos. The calculation
1348             * used is 6.5 * {@link #getShaahZmanis16Point1Degrees()} after
1349             * {@link #getAlos16Point1Degrees() alos}.
1350             * 
1351             * @see #getShaahZmanis16Point1Degrees()
1352             * @see #getMinchaGedola()
1353             * @see #getMinchaKetana()
1354             * @return the <code>Date</code> of the time of mincha gedola.
1355             */
1356            public Date getMinchaGedola16Point1Degrees() {
1357                    return getTimeOffset(getAlos16Point1Degrees(),
1358                                    getShaahZmanis16Point1Degrees() * 6.5);
1359            }
1360    
1361            /**
1362             * This is a conveniance methd that returns the later of
1363             * {@link #getMinchaGedola()}and {@link #getMinchaGedola30Minutes()}. In
1364             * the winter when a <em>{@link #getShaahZmanisGra() shaah zmanis}</em> is
1365             * less than 30 minutes {@link #getMinchaGedola30Minutes()}will be
1366             * returned, otherwise {@link #getMinchaGedola()} will be returned.
1367             * 
1368             * @return the <code>Date</code> of the later of
1369             *         {@link #getMinchaGedola()}and
1370             *         {@link #getMinchaGedola30Minutes()}
1371             */
1372            public Date getMinchaGedolaGreaterThan30() {
1373                    if (getMinchaGedola30Minutes() == null || getMinchaGedola() == null) {
1374                            return null;
1375                    } else {
1376                            return getMinchaGedola30Minutes().compareTo(getMinchaGedola()) > 0 ? getMinchaGedola30Minutes()
1377                                            : getMinchaGedola();
1378                    }
1379            }
1380    
1381            /**
1382             * This method returns the time of <em>mincha ketana</em> according to the
1383             * Magen Avraham with the day starting and ending 16.1&deg; below the
1384             * horizon. This is the perfered earliest time to pray <em>mincha</em> in
1385             * the opinion of the Ramba"m and others. For more information on this see
1386             * the documentation on <em>{@link #getMinchaGedola() mincha gedola}</em>.
1387             * This is calculated as 9.5 {@link #getTemporalHour() solar hours} after
1388             * alos. The calculation used is 9.5 *
1389             * {@link #getShaahZmanis16Point1Degrees()} after
1390             * {@link #getAlos16Point1Degrees() alos}.
1391             * 
1392             * @see #getShaahZmanis16Point1Degrees()
1393             * @see #getMinchaGedola()
1394             * @see #getMinchaKetana()
1395             * @return the <code>Date</code> of the time of mincha ketana.
1396             */
1397            public Date getMinchaKetana16Point1Degrees() {
1398                    return getTimeOffset(getAlos16Point1Degrees(),
1399                                    getShaahZmanis16Point1Degrees() * 9.5);
1400            }
1401    
1402            /**
1403             * This method returns the time of <em>mincha ketana</em> according to the
1404             * Magen Avraham with the day starting 72 minutes before sunrise and ending
1405             * 72 minutes after sunset. This is the perfered earliest time to pray
1406             * <em>mincha</em> in the opinion of the Ramba"m and others. For more
1407             * information on this see the documentation on
1408             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1409             * as 9.5 {@link #getShaahZmanis72Minutes()} after alos. The calculation
1410             * used is 9.5 * {@link #getShaahZmanis72Minutes()} after
1411             * {@link #getAlos72() alos}.
1412             * 
1413             * @see #getShaahZmanis16Point1Degrees()
1414             * @see #getMinchaGedola()
1415             * @see #getMinchaKetana()
1416             * @return the <code>Date</code> of the time of mincha ketana.
1417             */
1418            public Date getMinchaKetana72Minutes() {
1419                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 9.5);
1420            }
1421    
1422            /**
1423             * This method returns the time of <em>plag hamincha</em>. This is
1424             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
1425             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
1426             * {@link #getAlos72()}.
1427             * 
1428             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1429             */
1430            public Date getPlagHamincha60Minutes() {
1431                    return getTimeOffset(getAlos60(), getShaahZmanis60Minutes() * 10.75);
1432            }
1433    
1434            /**
1435             * This method returns the time of <em>plag hamincha</em>. This is
1436             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
1437             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
1438             * {@link #getAlos72()}.
1439             * 
1440             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1441             */
1442            public Date getPlagHamincha72Minutes() {
1443                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 10.75);
1444            }
1445    
1446            /**
1447             * This method returns the time of <em>plag hamincha</em>. This is
1448             * calculated as 10.75 hours after {@link #getAlos90() dawn}. The formula
1449             * used is:<br/> 10.75 *{@link #getShaahZmanis90Minutes()} after
1450             * {@link #getAlos90()}.
1451             * 
1452             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1453             */
1454            public Date getPlagHamincha90Minutes() {
1455                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 10.75);
1456            }
1457    
1458            /**
1459             * This method returns the time of <em>plag hamincha</em>. This is
1460             * calculated as 10.75 hours after {@link #getAlos96() dawn}. The formula
1461             * used is:<br/> 10.75 *{@link #getShaahZmanis96Minutes()} after
1462             * {@link #getAlos96()}.
1463             * 
1464             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1465             */
1466            public Date getPlagHamincha96Minutes() {
1467                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 10.75);
1468            }
1469    
1470            /**
1471             * This method returns the time of <em>plag hamincha</em>. This is
1472             * calculated as 10.75 hours after {@link #getAlos96Zmanis() dawn}. The
1473             * formula used is:<br/> 10.75 * {@link #getShaahZmanis96MinutesZmanis()}
1474             * after {@link #getAlos96Zmanis() dawn}.
1475             * 
1476             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1477             */
1478            public Date getPlagHamincha96MinutesZmanis() {
1479                    return getTimeOffset(getAlos96Zmanis(),
1480                                    getShaahZmanis96MinutesZmanis() * 10.75);
1481            }
1482    
1483            /**
1484             * This method returns the time of <em>plag hamincha</em>. This is
1485             * calculated as 10.75 hours after {@link #getAlos90Zmanis() dawn}. The
1486             * formula used is:<br/> 10.75 * {@link #getShaahZmanis90MinutesZmanis()}
1487             * after {@link #getAlos90Zmanis() dawn}.
1488             * 
1489             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1490             */
1491            public Date getPlagHamincha90MinutesZmanis() {
1492                    return getTimeOffset(getAlos90Zmanis(),
1493                                    getShaahZmanis90MinutesZmanis() * 10.75);
1494            }
1495    
1496            /**
1497             * This method returns the time of <em>plag hamincha</em>. This is
1498             * calculated as 10.75 hours after {@link #getAlos72Zmanis() dawn}. The
1499             * formula used is:<br/> 10.75 * {@link #getShaahZmanis72MinutesZmanis()}
1500             * after {@link #getAlos72Zmanis() dawn}.
1501             * 
1502             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1503             */
1504            public Date getPlagHamincha72MinutesZmanis() {
1505                    return getTimeOffset(getAlos72Zmanis(),
1506                                    getShaahZmanis72MinutesZmanis() * 10.75);
1507            }
1508    
1509            /**
1510             * This method returns the time of <em>plag hamincha</em> based on the
1511             * opinion that the day starts at
1512             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1513             * <em>{@link #getTzais16Point1Degrees() tzais 16.1&deg;}</em>. This is
1514             * calculated as 10.75 hours <em>zmaniyos</em> after
1515             * {@link #getAlos16Point1Degrees() dawn}. The formula is<br/>10.75 *
1516             * {@link #getShaahZmanis16Point1Degrees()} after
1517             * {@link #getAlos16Point1Degrees()}.
1518             * 
1519             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1520             */
1521            public Date getPlagHamincha16Point1Degrees() {
1522                    return getTimeOffset(getAlos16Point1Degrees(),
1523                                    getShaahZmanis16Point1Degrees() * 10.75);
1524            }
1525    
1526            /**
1527             * This method returns the time of <em>plag hamincha</em> based on the
1528             * opinion that the day starts at
1529             * <em>{@link #getAlos19Point8Degrees() alos 19.8&deg;}</em> and ends at
1530             * <em>{@link #getTzais19Point8Degrees() tzais 19.8&deg;}</em>. This is
1531             * calculated as 10.75 hours <em>zmaniyos</em> after
1532             * {@link #getAlos19Point8Degrees() dawn}. The formula is<br/>10.75 *
1533             * {@link #getShaahZmanis19Point8Degrees()} after
1534             * {@link #getAlos19Point8Degrees()}.
1535             * 
1536             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1537             */
1538            public Date getPlagHamincha19Point8Degrees() {
1539                    return getTimeOffset(getAlos19Point8Degrees(),
1540                                    getShaahZmanis19Point8Degrees() * 10.75);
1541            }
1542    
1543            /**
1544             * This method returns the time of <em>plag hamincha</em> based on the
1545             * opinion that the day starts at
1546             * <em>{@link #getAlos26Degrees() alos 26&deg;}</em> and ends at
1547             * <em>{@link #getTzais26Degrees() tzais 26&deg;}</em>. This is
1548             * calculated as 10.75 hours <em>zmaniyos</em> after
1549             * {@link #getAlos26Degrees() dawn}. The formula is<br/>10.75 *
1550             * {@link #getShaahZmanis26Degrees()} after {@link #getAlos26Degrees()}.
1551             * 
1552             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1553             */
1554            public Date getPlagHamincha26Degrees() {
1555                    return getTimeOffset(getAlos26Degrees(),
1556                                    getShaahZmanis26Degrees() * 10.75);
1557            }
1558    
1559            /**
1560             * This method returns the time of <em>plag hamincha</em> based on the
1561             * opinion that the day starts at
1562             * <em>{@link #getAlos18Degrees() alos 18&deg;}</em> and ends at
1563             * <em>{@link #getTzais18Degrees() tzais 18&deg;}</em>. This is
1564             * calculated as 10.75 hours <em>zmaniyos</em> after
1565             * {@link #getAlos18Degrees() dawn}. The formula is<br/>10.75 *
1566             * {@link #getShaahZmanis18Degrees()} after {@link #getAlos18Degrees()}.
1567             * 
1568             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1569             */
1570            public Date getPlagHamincha18Degrees() {
1571                    return getTimeOffset(getAlos18Degrees(),
1572                                    getShaahZmanis18Degrees() * 10.75);
1573            }
1574    
1575            /**
1576             * This method returns the time of <em>plag hamincha</em> based on the
1577             * opinion that the day starts at
1578             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1579             * {@link #getSunset() sunset}. 10.75 shaos zmaniyos are calculated based
1580             * on this day and added to {@link #getAlos16Point1Degrees() alos} to reach
1581             * this time. This time is 10.75 <em>shaos zmaniyos</em> (temporal hours)
1582             * after {@link #getAlos16Point1Degrees() dawn} based on the opinion that
1583             * the day is calculated from a {@link #getAlos16Point1Degrees() dawn} of
1584             * 16.1 degrees before sunrise to {@link #getSunset() sunset}. This returns
1585             * the time of 10.75 * the calculated <em>shaah zmanis</em> after
1586             * {@link #getAlos16Point1Degrees() dawn}.
1587             * 
1588             * @return the <code>Date</code> of the plag.
1589             * @see #getAlos16Point1Degrees()
1590             * @see #getSunset()
1591             */
1592            public Date getPlagAlosToSunset() {
1593                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1594                                    getSunset());
1595                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 10.75);
1596            }
1597    
1598            /**
1599             * This method returns the time of <em>plag hamincha</em> based on the
1600             * opinion that the day starts at
1601             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1602             * {@link #getTzaisGeonim7Point083Degrees() tzais}. 10.75 shaos zmaniyos
1603             * are calculated based on this day and added to
1604             * {@link #getAlos16Point1Degrees() alos} to reach this time. This time is
1605             * 10.75 <em>shaos zmaniyos</em> (temporal hours) after
1606             * {@link #getAlos16Point1Degrees() dawn} based on the opinion that the day
1607             * is calculated from a {@link #getAlos16Point1Degrees() dawn} of 16.1
1608             * degrees before sunrise to {@link #getTzaisGeonim7Point083Degrees() tzais}.
1609             * This returns the time of 10.75 * the calculated <em>shaah zmanis</em>
1610             * after {@link #getAlos16Point1Degrees() dawn}.
1611             * 
1612             * @return the <code>Date</code> of the plag.
1613             * @see #getAlos16Point1Degrees()
1614             * @see #getTzaisGeonim7Point083Degrees()
1615             */
1616            public Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() {
1617                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1618                                    getTzaisGeonim7Point083Degrees());
1619                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 10.75);
1620            }
1621    
1622            /**
1623             * This method returns Bain Hashmashos of Rabainu Tam calculated as the time
1624             * the sun is 13&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
1625             * (90&deg;). <br/><br/><b>FIXME:</b> As per Yisroel Vehazmanim Vol III
1626             * page 1028 No 50, the 13&deg; is slightly inaccurate. He lists it as a
1627             * drop less than 13&deg;. Calculations show that is seems to be
1628             * 13.2477&deg; below the horizon at that time. This makes a difference of 1
1629             * minute and 10 seconds in Jerusalem in the Equinox, and 1 minute 29
1630             * seconds in the solstice. for NY in the solstice, the difference is 1
1631             * minute 56 seconds.
1632             * 
1633             * @return the <code>Date</code> of the sun being 13&deg; below
1634             *         {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;).
1635             * @see #ZENITH_13_DEGREES
1636             * 
1637             */
1638            public Date getBainHasmashosRT13Degrees() {
1639                    return getSunsetOffsetByDegrees(ZENITH_13_DEGREES);
1640            }
1641    
1642            /**
1643             * This method returns Bain Hashmashos of Rabainu Tam calculated as a 58.5
1644             * minute offset after sunset. Bain hashmashos is 3/4 of a mil before tzais
1645             * or 3 1/4 mil after sunset. With a mil calculated as 18 minutes, 3.25 * 18 =
1646             * 58.5 minutes.
1647             * 
1648             * @return the <code>Date</code> of 58.5 minutes after sunset
1649             * 
1650             */
1651            public Date getBainHasmashosRT58Point5Minutes() {
1652                    return getTimeOffset(getSeaLevelSunset(), 58.5 * MINUTE_MILLIS);
1653            }
1654    
1655            /**
1656             * This method returns the time of <em>bain hashmashos</em> based on the
1657             * calculation of 13.5 minutes (3/4 of an 18 minute mil before shkiah
1658             * calculated as {@link #getTzaisGeonim7Point083Degrees() 7.083&deg;}. 
1659             * 
1660             * @return the <code>Date</code> of the bain hashmashos of Rabainu Tam in
1661             *         this calculation.
1662             * @see #getTzaisGeonim7Point083Degrees()
1663             */
1664            public Date getBainHasmashosRT13Point5MinutesBefore7Point083Degrees() {
1665                    return getTimeOffset(getSunsetOffsetByDegrees(ZENITH_7_POINT_083),
1666                                    -13.5 * MINUTE_MILLIS);
1667            }
1668    
1669            /**
1670             * This method returns <em>bain hashmashos</em> of Rabainu Tam calculated
1671             * in the opinion of the Divray Yosef (see Yisrael Vehazmanim) calculated
1672             * 5/18th (27.77%) of the time between alos (calculated as 19.8&deg; before
1673             * sunrise) and sunrise. This is added to sunset to arrive at the time for
1674             * bain hashmashos of Rabainu Tam).
1675             * 
1676             * @return the <code>Date</code> of bain hashmashos of Rabainu Tam for
1677             *         this calculation.
1678             */
1679            public Date getBainHasmashosRT2Stars() {
1680                    Date alos19Point8 = getAlos19Point8Degrees();
1681                    Date sunrise = getSunrise();
1682                    if (alos19Point8 == null || sunrise == null) {
1683                            return null;
1684                    }
1685                    return getTimeOffset(getSunset(), (sunrise.getTime() - alos19Point8
1686                                    .getTime())
1687                                    * (5 / 18d));
1688            }
1689    
1690            /**
1691             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1692             * of the <em>Geonim</em> calculated at the sun's position at
1693             * {@link #ZENITH_5_POINT_95 5.95&deg;} below the western horizon.
1694             * 
1695             * @return the <code>Date</code> representing the time when the sun is
1696             *         5.95&deg; below sea level.
1697             * @see #ZENITH_5_POINT_95
1698             */
1699            // public Date getTzaisGeonim3Point7Degrees() {
1700            // return getSunsetOffsetByDegrees(ZENITH_3_POINT_7);
1701            // }
1702            /**
1703             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1704             * of the <em>Geonim</em> calculated at the sun's position at
1705             * {@link #ZENITH_5_POINT_95 5.95&deg;} below the western horizon.
1706             * 
1707             * @return the <code>Date</code> representing the time when the sun is
1708             *         5.95&deg; below sea level.
1709             * @see #ZENITH_5_POINT_95
1710             */
1711            public Date getTzaisGeonim5Point95Degrees() {
1712                    return getSunsetOffsetByDegrees(ZENITH_5_POINT_95);
1713            }
1714    
1715            /**
1716             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1717             * of the <em>Geonim</em> calculated at the sun's position at
1718             * {@link #ZENITH_7_POINT_083 7.083&deg;} below the western horizon.
1719             * 
1720             * @return the <code>Date</code> representing the time when the sun is
1721             *         7.083&deg; below sea level.
1722             * @see #ZENITH_7_POINT_083
1723             */
1724            public Date getTzaisGeonim7Point083Degrees() {
1725                    return getSunsetOffsetByDegrees(ZENITH_7_POINT_083);
1726            }
1727    
1728            /**
1729             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1730             * of the <em>Geonim</em> calculated at the sun's position at
1731             * {@link #ZENITH_8_POINT_5 8.5&deg;} below the western horizon.
1732             * 
1733             * @return the <code>Date</code> representing the time when the sun is
1734             *         8.5&deg; below sea level.
1735             * @see #ZENITH_8_POINT_5
1736             */
1737            public Date getTzaisGeonim8Point5Degrees() {
1738                    return getSunsetOffsetByDegrees(ZENITH_8_POINT_5);
1739            }
1740    
1741            /**
1742             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1743             * of the Chavas Yair and Divray Malkiel that the time to walk the distance
1744             * of a Mil is 15 minutes for a total of 60 minutes for 4 mil after sea
1745             * level sunset.
1746             * 
1747             * @return the <code>Date</code> representing 60 minutes after sea level
1748             *         sunset.
1749             * @see #getAlos60()
1750             */
1751            public Date getTzais60() {
1752                    return getTimeOffset(getSeaLevelSunset(), 60 * MINUTE_MILLIS);
1753            }
1754    
1755            /**
1756             * This method returns tzais usually calculated as 40 minutes after sunset.
1757             * Please note that Chacham Yosef Harari-Raful of Yeshivat Ateret Torah who
1758             * uses this time, does so only for calculating various other zmanai hayom
1759             * such as Sof Zman Krias Shema and Plag Hamincha. His calendars do not
1760             * publish a zman for Tzais. It should also be noted that Chacham
1761             * Harari-Raful provided a 25 minute zman for Israel. This API uses 40
1762             * minutes year round in any place on the globe by default. This offset can
1763             * be changed by calling {@link #setAteretTorahSunsetOffset(double)}.
1764             * 
1765             * @return the <code>Date</code> representing 40 minutes after sea level
1766             *         sunset
1767             * @see #getAteretTorahSunsetOffset()
1768             * @see #setAteretTorahSunsetOffset(double)
1769             */
1770            public Date getTzaisAteretTorah() {
1771                    return getTimeOffset(getSeaLevelSunset(), getAteretTorahSunsetOffset()
1772                                    * MINUTE_MILLIS);
1773            }
1774    
1775            /**
1776             * Returns the offset in minutes after sunset used to calculate
1777             * <em>tzais</em> for the Ateret Torah zmanim. The defaullt value is 40
1778             * minutes.
1779             * 
1780             * @return the number of minutes after sunset for Tzais.
1781             * @see #setAteretTorahSunsetOffset(double)
1782             */
1783            public double getAteretTorahSunsetOffset() {
1784                    return ateretTorahSunsetOffset;
1785            }
1786    
1787            /**
1788             * Allows setting the offset in minutes after sunset for the Ateret Torah
1789             * zmanim. The default if unset is 40 minutes. Chacham Yosef Harari-Raful of
1790             * Yeshivat Ateret Torah uses 40 minutes globally with the exception of
1791             * Israel where a 25 minute offset is used. This 25 minute (or any other)
1792             * offset can be overridden by this methd. This offset impacts all Ateret
1793             * Torah methods.
1794             * 
1795             * @param ateretTorahSunsetOffset
1796             *            the number of minutes after sunset to use as an offset for the
1797             *            Ateret Torah <em>tzais</em>
1798             * @see #getAteretTorahSunsetOffset()
1799             */
1800            public void setAteretTorahSunsetOffset(double ateretTorahSunsetOffset) {
1801                    this.ateretTorahSunsetOffset = ateretTorahSunsetOffset;
1802            }
1803    
1804            /**
1805             * This method returns the latest <em>zman krias shema</em> (time to say
1806             * Shema in the morning) based on the calculation of Chacham Yosef
1807             * Harari-Raful of Yeshivat Ateret Torah, that the day starts
1808             * {@link #getAlos72Zmanis() 1/10th of the day} before sunrise and is
1809             * usually calculated as ending
1810             * {@link #getTzaisAteretTorah() 40 minutes after sunset}.
1811             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1812             * {@link #getAlos72Zmanis() alos} to reach this time. This time is 3
1813             * <em> {@link #getShaahZmanisAteretTorah() shaos zmaniyos}</em> (temporal
1814             * hours) after {@link #getAlos72Zmanis() alos 72 zmaniyos}.<br />
1815             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1816             * midday.
1817             * 
1818             * @return the <code>Date</code> of the latest zman shema based on this
1819             *         calculation.
1820             * @see #getAlos72Zmanis()
1821             * @see #getTzaisAteretTorah()
1822             * @see #getAteretTorahSunsetOffset()
1823             * @see #setAteretTorahSunsetOffset(double)
1824             * @see #getShaahZmanisAteretTorah()
1825             */
1826            public Date getSofZmanShmaAteretTorah() {
1827                    return getTimeOffset(getAlos72Zmanis(), getShaahZmanisAteretTorah() * 3);
1828            }
1829    
1830            /**
1831             * This method returns the latest <em>zman tfila</em> (time to say the
1832             * morning prayers) based on the calculation of Chacham Yosef Harari-Raful
1833             * of Yeshivat Ateret Torah, that the day starts
1834             * {@link #getAlos72Zmanis() 1/10th of the day} before sunrise and and is
1835             * usually calculated as ending
1836             * {@link #getTzaisAteretTorah() 40 minutes after sunset}.
1837             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1838             * {@link #getAlos72Zmanis() alos} to reach this time. This time is 4
1839             * <em>{@link #getShaahZmanisAteretTorah() shaos zmaniyos}</em> (temporal
1840             * hours) after {@link #getAlos72Zmanis() alos 72 zmaniyos}.<br />
1841             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1842             * midday.
1843             * 
1844             * @return the <code>Date</code> of the latest zman shema based on this
1845             *         calculation.
1846             * @see #getAlos72Zmanis()
1847             * @see #getTzaisAteretTorah()
1848             * @see #getShaahZmanisAteretTorah()
1849             * @see #setAteretTorahSunsetOffset(double)
1850             */
1851            public Date getSofZmanTfilahAteretTorah() {
1852                    return getTimeOffset(getAlos72Zmanis(), getShaahZmanisAteretTorah() * 4);
1853            }
1854    
1855            /**
1856             * This method returns the time of <em>mincha gedola</em> based on the
1857             * calculation of Chacham Yosef Harari-Raful of Yeshivat Ateret Torah, that
1858             * the day starts {@link #getAlos72Zmanis() 1/10th of the day} before
1859             * sunrise and and is usually calculated as ending
1860             * {@link #getTzaisAteretTorah() 40 minutes after sunset}. This is the
1861             * perfered earliest time to pray <em>mincha</em> in the opinion of the
1862             * Ramba"m and others. For more information on this see the documentation on
1863             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1864             * as 6.5 {@link #getShaahZmanisAteretTorah() solar hours} after alos. The
1865             * calculation used is 6.5 * {@link #getShaahZmanisAteretTorah()} after
1866             * {@link #getAlos72Zmanis() alos}.
1867             * 
1868             * @see #getAlos72Zmanis()
1869             * @see #getTzaisAteretTorah()
1870             * @see #getShaahZmanisAteretTorah()
1871             * @see #getMinchaGedola()
1872             * @see #getMinchaKetanaAteretTorah()
1873             * @see ZmanimCalendar#getMinchaGedola()
1874             * @return the <code>Date</code> of the time of mincha gedola.
1875             */
1876            public Date getMinchaGedolaAteretTorah() {
1877                    return getTimeOffset(getAlos72Zmanis(),
1878                                    getShaahZmanisAteretTorah() * 6.5);
1879            }
1880    
1881            /**
1882             * This method returns the time of <em>mincha ketana</em> based on the
1883             * calculation of Chacham Yosef Harari-Raful of Yeshivat Ateret Torah, that
1884             * the day starts {@link #getAlos72Zmanis() 1/10th of the day} before
1885             * sunrise and and is usually calculated as ending
1886             * {@link #getTzaisAteretTorah() 40 minutes after sunset}. This is the
1887             * perfered earliest time to pray <em>mincha</em> in the opinion of the
1888             * Ramba"m and others. For more information on this see the documentation on
1889             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1890             * as 9.5 {@link #getShaahZmanisAteretTorah() solar hours} after
1891             * {@link #getAlos72Zmanis() alos}. The calculation used is 9.5 *
1892             * {@link #getShaahZmanisAteretTorah()} after
1893             * {@link #getAlos72Zmanis() alos}.
1894             * 
1895             * @see #getAlos72Zmanis()
1896             * @see #getTzaisAteretTorah()
1897             * @see #getShaahZmanisAteretTorah()
1898             * @see #getMinchaGedola()
1899             * @see #getMinchaKetana()
1900             * @return the <code>Date</code> of the time of mincha ketana.
1901             */
1902            public Date getMinchaKetanaAteretTorah() {
1903                    return getTimeOffset(getAlos72Zmanis(),
1904                                    getShaahZmanisAteretTorah() * 9.5);
1905            }
1906    
1907            /**
1908             * This method returns the time of <em>plag hamincha</em> based on the
1909             * calculation of Chacham Yosef Harari-Raful of Yeshivat Ateret Torah, that
1910             * the day starts {@link #getAlos72Zmanis() 1/10th of the day} before
1911             * sunrise and and is usually calculated as ending
1912             * {@link #getTzaisAteretTorah() 40 minutes after sunset}.
1913             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1914             * {@link #getAlos72Zmanis() alos} to reach this time. This time is 10.75
1915             * <em>{@link #getShaahZmanisAteretTorah() shaos zmaniyos}</em> (temporal
1916             * hours) after {@link #getAlos72Zmanis() dawn}.
1917             * 
1918             * @return the <code>Date</code> of the plag.
1919             * @see #getAlos72Zmanis()
1920             * @see #getTzaisAteretTorah()
1921             * @see #getShaahZmanisAteretTorah()
1922             */
1923            public Date getPlagHaminchaAteretTorah() {
1924                    return getTimeOffset(getAlos72Zmanis(),
1925                                    getShaahZmanisAteretTorah() * 10.75);
1926            }
1927    
1928            /**
1929             * This method returns the time of <em>misheyakir</em> based on the common
1930             * calculation of the Syrian community in NY that the alos is a fixed minute
1931             * offset from day starting {@link #getAlos72Zmanis() 1/10th of the day}
1932             * before sunrise. The common offsets are 6 minutes (based on th Pri
1933             * Megadim, but not linked to the calculation of Alos as 1/10th of the day),
1934             * 8 and 18 minutes (possibly attributed to Chacham Baruch Ben Haim). Since
1935             * there is no universal accepted offset, the user of this API will have to
1936             * specify one. Chacham Yosef Harari-Raful of Yeshivat Ateret Torah does not
1937             * supply any zman for misheyakir and does not endorse any specific
1938             * calculation for misheyakir.
1939             * 
1940             * @param minutes
1941             *            the number of minutes after alos calculated as
1942             *            {@link #getAlos72Zmanis() 1/10th of the day}
1943             * @return the <code>Date</code> of misheyakir
1944             * @see #getAlos72Zmanis()
1945             */
1946            // public Date getMesheyakirAteretTorah(double minutes) {
1947            // return getTimeOffset(getAlos72Zmanis(), minutes * MINUTE_MILLIS);
1948            // }
1949            /**
1950             * Method to return <em>tzais</em> (dusk) calculated as 72 minutes
1951             * zmaniyos, or 1/10th of the day after
1952             * {@link #getSeaLevelSunset() sea level sunset}.
1953             * 
1954             * @return the <code>Date</code> representing the time.
1955             * @see #getAlos72Zmanis()
1956             */
1957            public Date getTzais72Zmanis() {
1958                    long shaahZmanis = getShaahZmanisGra();
1959                    if (shaahZmanis == Long.MIN_VALUE) {
1960                            return null;
1961                    }
1962                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.2);
1963            }
1964    
1965            /**
1966             * Method to return <em>tzais</em> (dusk) calculated using 90 minutes
1967             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1968             * {@link #getSeaLevelSunset() sea level sunset}.
1969             * 
1970             * @return the <code>Date</code> representing the time.
1971             * @see #getAlos90Zmanis()
1972             */
1973            public Date getTzais90Zmanis() {
1974                    long shaahZmanis = getShaahZmanisGra();
1975                    if (shaahZmanis == Long.MIN_VALUE) {
1976                            return null;
1977                    }
1978                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.5);
1979            }
1980    
1981            /**
1982             * Method to return <em>tzais</em> (dusk) calculated using 96 minutes
1983             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1984             * {@link #getSeaLevelSunset() sea level sunset}.
1985             * 
1986             * @return the <code>Date</code> representing the time.
1987             * @see #getAlos96Zmanis()
1988             */
1989            public Date getTzais96Zmanis() {
1990                    long shaahZmanis = getShaahZmanisGra();
1991                    if (shaahZmanis == Long.MIN_VALUE) {
1992                            return null;
1993                    }
1994                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.6);
1995            }
1996    
1997            /**
1998             * Method to return <em>tzais</em> (dusk) calculated as 90 minutes after
1999             * sea level sunset. This method returns <em>tzais</em> (nightfall) based
2000             * on the opinion of the Magen Avraham that the time to walk the distance of
2001             * a Mil in the Ramba"m's opinion is 18 minutes for a total of 90 minutes
2002             * based on the opinion of <em>Ula</em> who calculated <em>tzais</em> as
2003             * 5 Mil after sea level shkiah (sunset). A similar calculation
2004             * {@link #getTzais19Point8Degrees()}uses solar position calculations based
2005             * on this time.
2006             * 
2007             * @return the <code>Date</code> representing the time.
2008             * @see #getTzais19Point8Degrees()
2009             * @see #getAlos90()
2010             */
2011            public Date getTzais90() {
2012                    return getTimeOffset(getSeaLevelSunset(), 90 * MINUTE_MILLIS);
2013            }
2014    
2015            /**
2016             * This method returns <em>tzais</em> (nightfall) based on the opinion of
2017             * the Magen Avraham that the time to walk the distance of a Mil in the
2018             * Ramba"ms opinion is 2/5 of an hour (24 minutes) for a total of 120
2019             * minutes based on the opinion of <em>Ula</em> who calculated
2020             * <em>tzais</em> as 5 Mil after sea level shkiah (sunset). A similar
2021             * calculation {@link #getTzais26Degrees()} uses temporal calculations based
2022             * on this time.
2023             * 
2024             * @return the <code>Date</code> representing the time.
2025             * @see #getTzais26Degrees()
2026             * @see #getAlos120()
2027             */
2028            public Date getTzais120() {
2029                    return getTimeOffset(getSeaLevelSunset(), 120 * MINUTE_MILLIS);
2030            }
2031    
2032            /**
2033             * Method to return <em>tzais</em> (dusk) calculated using 120 minutes
2034             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
2035             * {@link #getSeaLevelSunset() sea level sunset}.
2036             * 
2037             * @return the <code>Date</code> representing the time.
2038             * @see #getAlos120Zmanis()
2039             */
2040            public Date getTzais120Zmanis() {
2041                    long shaahZmanis = getShaahZmanisGra();
2042                    if (shaahZmanis == Long.MIN_VALUE) {
2043                            return null;
2044                    }
2045                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 2.0);
2046            }
2047    
2048            /**
2049             * For information on how this is calculated see the comments on
2050             * {@link #getAlos16Point1Degrees()}
2051             * 
2052             * @return the <code>Date</code> representing the time.
2053             * @see #getTzais72()
2054             * @see #getAlos16Point1Degrees() for more information on this calculation.
2055             */
2056            public Date getTzais16Point1Degrees() {
2057                    return getSunsetOffsetByDegrees(ZENITH_16_POINT_1);
2058            }
2059    
2060            /**
2061             * For information on how this is calculated see the comments on
2062             * {@link #getAlos26Degrees()}
2063             * 
2064             * @return the <code>Date</code> representing the time.
2065             * @see #getTzais120()
2066             * @see #getAlos26Degrees()
2067             */
2068            public Date getTzais26Degrees() {
2069                    return getSunsetOffsetByDegrees(ZENITH_26_DEGREES);
2070            }
2071    
2072            /**
2073             * For information on how this is calculated see the comments on
2074             * {@link #getAlos18Degrees()}
2075             * 
2076             * @return the <code>Date</code> representing the time.
2077             * @see #getAlos18Degrees()
2078             */
2079            public Date getTzais18Degrees() {
2080                    return getSunsetOffsetByDegrees(ASTRONOMICAL_ZENITH);
2081            }
2082    
2083            /**
2084             * For information on how this is calculated see the comments on
2085             * {@link #getAlos19Point8Degrees()}
2086             * 
2087             * @return the <code>Date</code> representing the time.
2088             * @see #getTzais90()
2089             * @see #getAlos19Point8Degrees()
2090             */
2091            public Date getTzais19Point8Degrees() {
2092                    return getSunsetOffsetByDegrees(ZENITH_19_POINT_8);
2093            }
2094    
2095            /**
2096             * A method to return <em>tzais</em> (dusk) calculated as 96 minutes after
2097             * sea level sunset. For information on how this is calculated see the
2098             * comments on {@link #getAlos96()}.
2099             * 
2100             * @return the <code>Date</code> representing the time.
2101             * @see #getAlos96()
2102             */
2103            public Date getTzais96() {
2104                    return getTimeOffset(getSeaLevelSunset(), 96 * MINUTE_MILLIS);
2105            }
2106    
2107            /**
2108             * A method that returns the local time for fixed <em>chatzos</em>. This
2109             * time is noon and midnight adjusted from standard time to account for the
2110             * local latitude. The 360&deg; of the globe divided by 24 calculates to
2111             * 15&deg; per hour with 4 minutes per degree, so at a longitude of 0 , 15,
2112             * 30 etc Chatzos in 12:00 noon. Lakewood, NJ whose longitude is -74.2094 is
2113             * 0.7906 away from the closest multiple of 15 at -75&deg;. This is
2114             * multiplied by 4 to yeild 3 minutes and 10 seconds for a chatzos of
2115             * 11:56:50. This method is not tied to the theoretical 15&deg; timezones,
2116             * but will adjust to the actual timezone and <a
2117             * href="http://en.wikipedia.org/wiki/Daylight_saving_time">Daylight saving
2118             * time</a>.
2119             * 
2120             * @return the Date representing the local <em>chatzos</em>
2121             * @see GeoLocation#getLocalMeanTimeOffset()
2122             */
2123            public Date getFixedLocalChatzos() {
2124                    return getTimeOffset(getDateFromTime(12.0
2125                                    - getGeoLocation().getTimeZone().getRawOffset() / HOUR_MILLIS),
2126                                    -getGeoLocation().getLocalMeanTimeOffset());
2127            }
2128    
2129            /**
2130             * A method that returns the latest <em>zman krias shema</em> (time to say
2131             * Shema in the morning) calculated as 3 hours before
2132             * {@link #getFixedLocalChatzos()}.
2133             * 
2134             * @return the <code>Date</code> of the latest zman shema.
2135             * @see #getFixedLocalChatzos()
2136             * @see #getSofZmanTfilaFixedLocal()
2137             */
2138            public Date getSofZmanShmaFixedLocal() {
2139                    return getTimeOffset(getFixedLocalChatzos(), -180 * MINUTE_MILLIS);
2140            }
2141    
2142            /**
2143             * This method returns the latest <em>zman tfila</em> (time to say the
2144             * morning prayers) calculated as 2 hours before
2145             * {@link #getFixedLocalChatzos()}.
2146             * 
2147             * @return the <code>Date</code> of the latest zman tfila.
2148             * @see #getFixedLocalChatzos()
2149             * @see #getSofZmanShmaFixedLocal()
2150             */
2151            public Date getSofZmanTfilaFixedLocal() {
2152                    return getTimeOffset(getFixedLocalChatzos(), -120 * MINUTE_MILLIS);
2153            }
2154    
2155            /**
2156             * @see java.lang.Object#equals(Object)
2157             */
2158            public boolean equals(Object object) {
2159                    if (this == object) {
2160                            return true;
2161                    }
2162                    if (!(object instanceof ComplexZmanimCalendar)) {
2163                            return false;
2164                    }
2165                    ComplexZmanimCalendar cCal = (ComplexZmanimCalendar) object;
2166                    // return getCalendar().getTime().equals(cCal.getCalendar().getTime())
2167                    return getCalendar().equals(cCal.getCalendar())
2168                                    && getGeoLocation().equals(cCal.getGeoLocation())
2169                                    && getAstronomicalCalculator().equals(
2170                                                    cCal.getAstronomicalCalculator());
2171            }
2172    
2173            /**
2174             * @see java.lang.Object#hashCode()
2175             */
2176            public int hashCode() {
2177                    int result = 17;
2178                    // needed or this and subclasses will return identical hash
2179                    result = 37 * result + getClass().hashCode();
2180                    result += 37 * result + getCalendar().hashCode();
2181                    result += 37 * result + getGeoLocation().hashCode();
2182                    result += 37 * result + getAstronomicalCalculator().hashCode();
2183                    return result;
2184            }
2185    }