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     * //the String parameter in getTimeZone() has to be a valid timezone listed in {@link java.util.TimeZone#getAvailableIDs()}
047     * TimeZone timeZone = TimeZone.getTimeZone(&quot;America/New_York&quot;);
048     * GeoLocation location = new GeoLocation(locationName, latitude, longitude,
049     *              timeZone);
050     * ComplexZmanimCalendar czc = new ComplexZmanimCalendar(location);
051     * </pre>
052     * 
053     * Note: For locations such as Israel where the beginning and end of daylight
054     * savings time can fluctuate from year to year create a
055     * {@link java.util.SimpleTimeZone} with the known start and end of DST. <br />
056     * To get alos calculated as 14&deg; below the horizon (as calculated in the
057     * calendars published in Montreal) use:
058     * 
059     * <pre>
060     * Date alos14 = czc.getSunriseOffsetByDegrees(14);
061     * </pre>
062     * 
063     * To get <em>mincha gedola</em> calculated based on the MGA using a <em>shaah
064     * zmanis</em>
065     * based on the day starting 16.1&deg; below the horizon (and ending 16.1&deg;
066     * after sunset the following calculation can be used:
067     * 
068     * <pre>
069     * Date minchaGedola = czc.getTimeOffset(czc.getAlos16point1Degrees(), czc
070     *              .getShaahZmanis16Point1Degrees() * 6.5);
071     * </pre>
072     * 
073     * A little more complex example would be calculating <em>plag hamincha</em>
074     * based on a shaah zmanis that was not present in this class. While a drop more
075     * complex it is still rather easy. For example if you wanted to calculate
076     * <em>plag</em> based on the day starting 12&deg; before sunrise and ending
077     * 12&deg; after sunset as calculated in the calendars in Manchester, England
078     * (there is nothing that would prevent your calculating the day using sunrise
079     * and sunset offsets that are not identical degrees, but this would lead to
080     * chatzos being a time other than the {@link #getSunTransit() solar transit}
081     * (solar midday)). The steps involved would be to first calculate the
082     * <em>shaah zmanis</em> and than use that time in milliseconds to calculate
083     * 10.75 hours after sunrise starting at 12&deg; before sunset
084     * 
085     * <pre>
086     * long shaahZmanis = czc.getSolarHour(czc.getSunriseOffsetByDegrees(12), czc
087     *              .getSunriseOffsetByDegrees(12));
088     * Date plag = getTimeOffset(czc.getSunriseOffsetByDegrees(12),
089     *              shaahZmanis * 10.75);
090     * </pre>
091     * 
092     * <h2>Disclaimer:</h2>
093     * While I did my best to get accurate results please do not rely on these
094     * zmanim for <em>halacha lemaaseh</em>
095     * 
096     * @author &copy; Eliyahu Hershfeld 2004 - 2008
097     * @version 1.1
098     */
099    public class ComplexZmanimCalendar extends ZmanimCalendar {
100            private static final long serialVersionUID = 1;
101    
102            /**
103             * The zenith of 5.95&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
104             * (90&deg;). This calculation is used for calculating <em>tzais</em>
105             * (nightfall) according to some opinions. This calculation is based on the
106             * position of the sun 24 minutes after sunset in Jerusalem in the equinox
107             * which calculates to 5.95&deg; below
108             * {@link #GEOMETRIC_ZENITH geometric zenith}
109             * 
110             * @see #getTzaisGeonim5Point95Degrees()
111             */
112            protected static final double ZENITH_5_POINT_95 = GEOMETRIC_ZENITH + 5.95;
113    
114            /**
115             * The zenith of 7.083&deg; below
116             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This is often
117             * referred to as 7&deg;5' or 7&deg; and 5 minutes. This calculation is used
118             * for calculating <em>alos</em> (dawn) and <em>tzais</em> (nightfall)
119             * according to some opinions. This calculation is based on the position of
120             * the sun 30 minutes after sunset in Jerusalem in the equinox which
121             * calculates to 7.0833333&deg; below
122             * {@link #GEOMETRIC_ZENITH geometric zenith}
123             * 
124             * @see #getTzaisGeonim7Point083Degrees()
125             * @see #getBainHasmashosRT13Point5MinutesBefore7Point083Degrees()
126             */
127            protected static final double ZENITH_7_POINT_083 = GEOMETRIC_ZENITH + 7
128                            + (5 / 60);
129    
130            /**
131             * The zenith of 10.2&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
132             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
133             * according to some opinions. This calculation is based on the position of
134             * the sun 45 minutes before {@link #getSunrise sunrise} in Jerusalem in the
135             * equinox which calculates to 10.2&deg; below
136             * {@link #GEOMETRIC_ZENITH geometric zenith}
137             * 
138             * @see #getMisheyakir10Point2Degrees()
139             */
140            protected static final double ZENITH_10_POINT_2 = GEOMETRIC_ZENITH + 10.2;
141    
142            /**
143             * The zenith of 11&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
144             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
145             * according to some opinions. This calculation is based on the position of
146             * the sun 48 minutes before {@link #getSunrise sunrise} in Jerusalem in the
147             * equinox which calculates to 11&deg; below
148             * {@link #GEOMETRIC_ZENITH geometric zenith}
149             * 
150             * @see #getMisheyakir11Degrees()
151             */
152            protected static final double ZENITH_11_DEGREES = GEOMETRIC_ZENITH + 11;
153    
154            /**
155             * The zenith of 11.5&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
156             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
157             * according to some opinions. This calculation is based on the position of
158             * the sun 52 minutes before {@link #getSunrise sunrise} in Jerusalem in the
159             * equinox which calculates to 11.5&deg; below
160             * {@link #GEOMETRIC_ZENITH geometric zenith}
161             * 
162             * @see #getMisheyakir11Point5Degrees()
163             */
164            protected static final double ZENITH_11_POINT_5 = GEOMETRIC_ZENITH + 11.5;
165    
166            /**
167             * The zenith of 13&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
168             * (90&deg;). This calculation is used for calculating
169             * <em>Rabainu Tam's bain hashmashos</em> according to some opinions.
170             * 
171             * @see #getBainHasmashosRT13Degrees
172             */
173            protected static final double ZENITH_13_DEGREES = GEOMETRIC_ZENITH + 13;
174    
175            /**
176             * The zenith of 19.8&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
177             * (90&deg;). This calculation is used for calculating <em>alos</em>
178             * (dawn) and <em>tzais</em> (nightfall) according to some opinions. This
179             * calculation is based on the position of the sun 90 minutes after sunset
180             * in Jerusalem in the equinox which calculates to 19.8&deg; below
181             * {@link #GEOMETRIC_ZENITH geometric zenith}
182             * 
183             * @see #getTzais19Point8Degrees()
184             * @see #getAlos19Point8Degrees()
185             * @see #getAlos90()
186             * @see #getTzais90()
187             */
188            protected static final double ZENITH_19_POINT_8 = GEOMETRIC_ZENITH + 19.8;
189    
190            /**
191             * The zenith of 26&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
192             * (90&deg;). This calculation is used for calculating <em>alos</em>
193             * (dawn) and <em>tzais</em> (nightfall) according to some opinions. This
194             * calculation is based on the position of the sun
195             * {@link #getAlos120() 120 minutes} after sunset in Jerusalem in the
196             * equinox which calculates to 26&deg; below
197             * {@link #GEOMETRIC_ZENITH geometric zenith}
198             * 
199             * @see #getAlos26Degrees()
200             * @see #getTzais26Degrees()
201             * @see #getAlos120()
202             * @see #getTzais120()
203             */
204            protected static final double ZENITH_26_DEGREES = GEOMETRIC_ZENITH + 26.0;
205    
206            public ComplexZmanimCalendar(GeoLocation location) {
207                    super(location);
208            }
209    
210            /**
211             * Default constructor will set a default {@link GeoLocation#GeoLocation()},
212             * a default
213             * {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} and
214             * default the calendar to the current date.
215             * 
216             * @see AstronomicalCalendar#AstronomicalCalendar()
217             */
218            public ComplexZmanimCalendar() {
219                    super();
220            }
221    
222            /**
223             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
224             * using a 19.8&deg; dip. This calculation divides the day based on the
225             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
226             * calculation is when the sun is 19.8&deg; below the eastern geometric
227             * horizon before sunrise. Dusk for this is when the sun is 19.8&deg; below
228             * the western geometric horizon after sunset. This day is split into 12
229             * equal parts with each part being a <em>shaah zmanis</em>.
230             * 
231             * @return the <code>long</code> millisecond length of a
232             *         <em>shaah zmanis</em>.
233             */
234            public long getShaahZmanis19Point8Degrees() {
235                    return getTemporalHour(getAlos19Point8Degrees(),
236                                    getTzais19Point8Degrees());
237            }
238    
239            /**
240             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
241             * using a 18&deg; dip. This calculation divides the day based on the
242             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
243             * calculation is when the sun is 18&deg; below the eastern geometric
244             * horizon before sunrise. Dusk for this is when the sun is 18&deg; below
245             * the western geometric horizon after sunset. This day is split into 12
246             * equal parts with each part being a <em>shaah zmanis</em>.
247             * 
248             * @return the <code>long</code> millisecond length of a
249             *         <em>shaah zmanis</em>.
250             */
251            public long getShaahZmanis18Degrees() {
252                    return getTemporalHour(getAlos18Degrees(), getTzais18Degrees());
253            }
254    
255            /**
256             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
257             * using a dip of 26&deg;. This calculation divides the day based on the
258             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
259             * calculation is when the sun is {@link #getAlos26Degrees() 26&deg;} below
260             * the eastern geometric horizon before sunrise. Dusk for this is when the
261             * sun is {@link #getTzais26Degrees() 26&deg;} below the western geometric
262             * horizon after sunset. This day is split into 12 equal parts with each
263             * part being a <em>shaah zmanis</em>.
264             * 
265             * @return the <code>long</code> millisecond length of a
266             *         <em>shaah zmanis</em>.
267             */
268            public long getShaahZmanis26Degrees() {
269                    return getTemporalHour(getAlos26Degrees(), getTzais26Degrees());
270            }
271    
272            /**
273             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
274             * using a dip of 16.1&deg;. This calculation divides the day based on the
275             * opinion that the day runs from dawn to dusk. Dawn for this calculation is
276             * when the sun is 16.1&deg; below the eastern geometric horizon before
277             * sunrise and dusk is when the sun is 16.1&deg; below the western geometric
278             * horizon after sunset. This day is split into 12 equal parts with each
279             * part being a <em>shaah zmanis</em>.
280             * 
281             * @return the <code>long</code> millisecond length of a
282             *         <em>shaah zmanis</em>.
283             * @see #getAlos16Point1Degrees()
284             * @see #getTzais16Point1Degrees()
285             * @see #getSofZmanShmaMGA16Point1Degrees()
286             * @see #getSofZmanTfilaMGA16Point1Degrees()
287             * @see #getMinchaGedola16Point1Degrees()
288             * @see #getMinchaKetana16Point1Degrees()
289             * @see #getPlagHamincha16Point1Degrees()
290             */
291    
292            public long getShaahZmanis16Point1Degrees() {
293                    return getTemporalHour(getAlos16Point1Degrees(),
294                                    getTzais16Point1Degrees());
295            }
296    
297            /**
298             * Method to return a <em>shaah zmanis</em> (solar hour) according to the
299             * opinion of the MGA. This calculation divides the day based on the opinion
300             * of the <em>MGA</em> that the day runs from dawn to dusk. Dawn for this
301             * calculation is 60 minutes before sunrise and dusk is 60 minutes after
302             * sunset. This day is split into 12 equal parts with each part being a
303             * <em>shaah zmanis</em>. Alternate mothods of calculating a
304             * <em>shaah zmanis</em> are available in the subclass
305             * {@link ComplexZmanimCalendar}
306             * 
307             * @return the <code>long</code> millisecond length of a
308             *         <em>shaah zmanis</em>.
309             */
310            public long getShaahZmanis60Minutes() {
311                    return getTemporalHour(getAlos60(), getTzais60());
312            }
313    
314            /**
315             * Method to return a <em>shaah zmanis</em> (solar hour) according to the
316             * opinion of the MGA. This calculation divides the day based on the opinion
317             * of the <em>MGA</em> that the day runs from dawn to dusk. Dawn for this
318             * calculation is 72 minutes before sunrise and dusk is 72 minutes after
319             * sunset. This day is split into 12 equal parts with each part being a
320             * <em>shaah zmanis</em>. Alternate mothods of calculating a
321             * <em>shaah zmanis</em> are available in the subclass
322             * {@link ComplexZmanimCalendar}
323             * 
324             * @return the <code>long</code> millisecond length of a
325             *         <em>shaah zmanis</em>.
326             */
327            public long getShaahZmanis72Minutes() {
328                    return getShaahZmanisMGA();
329            }
330    
331            /**
332             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
333             * the opinion of the MGA based on <em>alos</em> being
334             * {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> before
335             * {@link #getSunrise() sunrise}. This calculation divides the day based on
336             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
337             * Dawn for this calculation is 72 minutes <em>zmaniyos</em> before
338             * sunrise and dusk is 72 minutes <em>zmaniyos</em> after sunset. This day
339             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
340             * This is identical to 1/10th of the day from {@link #getSunrise() sunrise}
341             * to {@link #getSunset() sunset}.
342             * 
343             * @return the <code>long</code> millisecond length of a
344             *         <em>shaah zmanis</em>.
345             * @see #getAlos72Zmanis()
346             * @see #getTzais72Zmanis()
347             */
348            public long getShaahZmanis72MinutesZmanis() {
349                    return getTemporalHour(getAlos72Zmanis(), getTzais72Zmanis());
350            }
351    
352            /**
353             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
354             * using a dip of 90 minutes. This calculation divides the day based on the
355             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
356             * calculation is 90 minutes before sunrise and dusk is 90 minutes after
357             * sunset. This day is split into 12 equal parts with each part being a
358             * <em>shaah zmanis</em>.
359             * 
360             * @return the <code>long</code> millisecond length of a
361             *         <em>shaah zmanis</em>.
362             */
363            public long getShaahZmanis90Minutes() {
364                    return getTemporalHour(getAlos90(), getTzais90());
365            }
366    
367            /**
368             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
369             * the opinion of the MGA based on <em>alos</em> being
370             * {@link #getAlos90Zmanis() 90} minutes <em>zmaniyos</em> before
371             * {@link #getSunrise() sunrise}. This calculation divides the day based on
372             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
373             * Dawn for this calculation is 90 minutes <em>zmaniyos</em> before
374             * sunrise and dusk is 90 minutes <em>zmaniyos</em> after sunset. This day
375             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
376             * This is identical to 1/8th of the day from {@link #getSunrise() sunrise}
377             * to {@link #getSunset() sunset}.
378             * 
379             * @return the <code>long</code> millisecond length of a
380             *         <em>shaah zmanis</em>.
381             * @see #getAlos90Zmanis()
382             * @see #getTzais90Zmanis()
383             */
384            public long getShaahZmanis90MinutesZmanis() {
385                    return getTemporalHour(getAlos90Zmanis(), getTzais90Zmanis());
386            }
387    
388            /**
389             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
390             * the opinion of the MGA based on <em>alos</em> being
391             * {@link #getAlos96Zmanis() 96} minutes <em>zmaniyos</em> before
392             * {@link #getSunrise() sunrise}. This calculation divides the day based on
393             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
394             * Dawn for this calculation is 96 minutes <em>zmaniyos</em> before
395             * sunrise and dusk is 96 minutes <em>zmaniyos</em> after sunset. This day
396             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
397             * This is identical to 1/7.5th of the day from
398             * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
399             * 
400             * @return the <code>long</code> millisecond length of a
401             *         <em>shaah zmanis</em>.
402             * @see #getAlos96Zmanis()
403             * @see #getTzais96Zmanis()
404             */
405            public long getShaahZmanis96MinutesZmanis() {
406                    return getTemporalHour(getAlos96Zmanis(), getTzais96Zmanis());
407            }
408    
409            /**
410             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
411             * using a dip of 96 minutes. This calculation divides the day based on the
412             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
413             * calculation is 96 minutes before sunrise and dusk is 96 minutes after
414             * sunset. This day is split into 12 equal parts with each part being a
415             * <em>shaah zmanis</em>.
416             * 
417             * @return the <code>long</code> millisecond length of a
418             *         <em>shaah zmanis</em>.
419             */
420            public long getShaahZmanis96Minutes() {
421                    return getTemporalHour(getAlos96(), getTzais96());
422            }
423    
424            /**
425             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
426             * using a dip of 120 minutes. This calculation divides the day based on the
427             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
428             * calculation is 120 minutes before sunrise and dusk is 120 minutes after
429             * sunset. This day is split into 12 equal parts with each part being a
430             * <em>shaah zmanis</em>.
431             * 
432             * @return the <code>long</code> millisecond length of a
433             *         <em>shaah zmanis</em>.
434             */
435            public long getShaahZmanis120Minutes() {
436                    return getTemporalHour(getAlos120(), getTzais120());
437            }
438    
439            /**
440             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
441             * the opinion of the MGA based on <em>alos</em> being
442             * {@link #getAlos120Zmanis() 120} minutes <em>zmaniyos</em> before
443             * {@link #getSunrise() sunrise}. This calculation divides the day based on
444             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
445             * Dawn for this calculation is 120 minutes <em>zmaniyos</em> before
446             * sunrise and dusk is 120 minutes <em>zmaniyos</em> after sunset. This
447             * day is split into 12 equal parts with each part being a
448             * <em>shaah zmanis</em>. This is identical to 1/6th of the day from
449             * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
450             * 
451             * @return the <code>long</code> millisecond length of a
452             *         <em>shaah zmanis</em>.
453             * @see #getAlos120Zmanis()
454             * @see #getTzais120Zmanis()
455             */
456            public long getShaahZmanis120MinutesZmanis() {
457                    return getTemporalHour(getAlos120Zmanis(), getTzais120Zmanis());
458            }
459    
460            /**
461             * This method returns the time of <em>plag hamincha</em>. This is
462             * calculated as 10.75 hours after {@link #getAlos96Zmanis() dawn}. The
463             * formula used is:<br/> 10.75 * {@link #getShaahZmanis96MinutesZmanis()}
464             * after {@link #getAlos96Zmanis() dawn}.
465             * 
466             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
467             */
468            public Date getPlagHamincha120MinutesZmanis() {
469                    return getTimeOffset(getAlos120Zmanis(),
470                                    getShaahZmanis120MinutesZmanis() * 10.75);
471            }
472    
473            /**
474             * This method returns the time of <em>plag hamincha</em>. This is
475             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
476             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
477             * {@link #getAlos72()}.
478             * 
479             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
480             */
481            public Date getPlagHamincha120Minutes() {
482                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 10.75);
483            }
484    
485            /**
486             * Method to return <em>alos</em> (dawn) calculated using 60 minutes
487             * before {@link #getSeaLevelSunrise() sea level sunrise} on the time to
488             * walk the distance of 4 <em>Mil</em> at 15 minutes a <em>Mil</em>.
489             * This is based on the opinion of most <em>Rishonim</em> who stated that
490             * the time of the <em>Neshef</em> (time between dawn and sunrise) does
491             * not vary by the time of year or location but purely depends on the time
492             * it takes to walk the distance of 4 <em>Mil</em>.
493             * 
494             * @return the <code>Date</code> representing the time.
495             */
496            public Date getAlos60() {
497                    return getTimeOffset(getSeaLevelSunrise(), -60 * MINUTE_MILLIS);
498            }
499    
500            /**
501             * Method to return <em>alos</em> (dawn) calculated using 72 minutes
502             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
503             * or 1/10th of the day before sea level sunrise. This is based on an 18
504             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 72 minutes
505             * which is 1/10th of a day (12 * 60 = 720) based on the day starting at
506             * {@link #getSunrise() sunrise} and ending at {@link #getSunset() sunset}.
507             * The actual alculation is {@link #getSunrise()}- (
508             * {@link #getShaahZmanisGra()} * 1.2). This calculation is used in the
509             * calendars published by
510             * <em>Hisachdus Harabanim D'Artzos Habris Ve'Kanada</em>
511             * 
512             * @return the <code>Date</code> representing the time.
513             * @see #getShaahZmanisGra()
514             */
515            public Date getAlos72Zmanis() {
516                    long shaahZmanis = getShaahZmanisGra();
517                    if (shaahZmanis == Long.MIN_VALUE) {
518                            return null;
519                    }
520                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.2));
521            }
522    
523            /**
524             * Method to return <em>alos</em> (dawn) calculated using 96 minutes
525             * before {@link #getSeaLevelSunrise() sea level sunrise} based on the time
526             * to walk the distance of 4 <em>Mil</em> at 24 minutes a <em>Mil</em>.
527             * This is based on the opinion of most <em>Rishonim</em> who stated that
528             * the time of the <em>Neshef</em> (time between dawn and sunrise) does
529             * not vary by the time of year or location but purely depends on the time
530             * it takes to walk the distance of 4 <em>Mil</em>.
531             * 
532             * @return the <code>Date</code> representing the time.
533             */
534            public Date getAlos96() {
535                    return getTimeOffset(getSeaLevelSunrise(), -96 * MINUTE_MILLIS);
536            }
537    
538            /**
539             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
540             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
541             * or 1/8th of the day before sea level sunrise. This is based on a 22.5
542             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 90 minutes
543             * which is 1/8th of a day (12 * 60 = 720) /8 =90 based on the day starting
544             * at {@link #getSunrise() sunrise} and ending at
545             * {@link #getSunset() sunset}. The actual calculation is
546             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 1.5).
547             * 
548             * @return the <code>Date</code> representing the time.
549             * @see #getShaahZmanisGra()
550             */
551            public Date getAlos90Zmanis() {
552                    long shaahZmanis = getShaahZmanisGra();
553                    if (shaahZmanis == Long.MIN_VALUE) {
554                            return null;
555                    }
556                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.5));
557            }
558    
559            /**
560             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
561             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
562             * or 1/8th of the day before sea level sunrise. This is based on a 24
563             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 90 minutes
564             * which is 1/7.5th of a day (12 * 60 = 720) / 7.5 =96 based on the day
565             * starting at {@link #getSunrise() sunrise} and ending at
566             * {@link #getSunset() sunset}. The actual calculation is
567             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 1.6).
568             * 
569             * @return the <code>Date</code> representing the time.
570             * @see #getShaahZmanisGra()
571             */
572            public Date getAlos96Zmanis() {
573                    long shaahZmanis = getShaahZmanisGra();
574                    if (shaahZmanis == Long.MIN_VALUE) {
575                            return null;
576                    }
577                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.6));
578            }
579    
580            /**
581             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
582             * before {@link #getSeaLevelSunrise() sea level sunrise} on the time to
583             * walk the distance of 4 <em>Mil</em> at 22.5 minutes a <em>Mil</em>.
584             * This is based on the opinion of most <em>Rishonim</em> who stated that
585             * the time of the <em>Neshef</em> (time between dawn and sunrise) does
586             * not vary by the time of year or location but purely depends on the time
587             * it takes to walk the distance of 4 <em>Mil</em>.
588             * 
589             * @return the <code>Date</code> representing the time.
590             */
591            public Date getAlos90() {
592                    return getTimeOffset(getSeaLevelSunrise(), -90 * MINUTE_MILLIS);
593            }
594    
595            /**
596             * Method to return <em>alos</em> (dawn) calculated using 120 minutes
597             * before {@link #getSeaLevelSunrise() sea level sunrise} (no adjustment for
598             * elevation is made) based on the time to walk the distance of 5
599             * <em>Mil</em>( <em>Ula</em>) at 24 minutes a <em>Mil</em>. This
600             * is based on the opinion of most <em>Rishonim</em> who stated that the
601             * time of the <em>Neshef</em> (time between dawn and sunrise) does not
602             * vary by the time of year or location but purely depends on the time it
603             * takes to walk the distance of 5 <em>Mil</em>(<em>Ula</em>).
604             * 
605             * @return the <code>Date</code> representing the time.
606             */
607            public Date getAlos120() {
608                    return getTimeOffset(getSeaLevelSunrise(), -120 * MINUTE_MILLIS);
609            }
610    
611            /**
612             * Method to return <em>alos</em> (dawn) calculated using 120 minutes
613             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
614             * or 1/6th of the day before sea level sunrise. This is based on a 24
615             * minute <em>Mil</em> so the time for 5 <em>Mil</em> is 120 minutes
616             * which is 1/6th of a day (12 * 60 = 720) / 6 =120 based on the day
617             * starting at {@link #getSunrise() sunrise} and ending at
618             * {@link #getSunset() sunset}. The actual calculation is
619             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 2).
620             * 
621             * @return the <code>Date</code> representing the time.
622             * @see #getShaahZmanisGra()
623             */
624            public Date getAlos120Zmanis() {
625                    long shaahZmanis = getShaahZmanisGra();
626                    if (shaahZmanis == Long.MIN_VALUE) {
627                            return null;
628                    }
629                    return getTimeOffset(getSeaLevelSunrise(), shaahZmanis * -2);
630            }
631    
632            /**
633             * Method to return <em>alos</em> (dawn) calculated when the sun is
634             * {@link #ZENITH_26_DEGREES 26&deg;} below the eastern geometric horizon
635             * before sunrise. This calculation is based on the same calculation of
636             * {@link #getAlos120() 120 minutes} but uses a degree based calculation
637             * instead of 120 exact minutes. This calculation is based on the position
638             * of the sun 120 minutes before sunrise in Jerusalem in the equinox which
639             * calculates to 26&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}.
640             * 
641             * @return the <code>Date</code> representing <em>alos</em>.
642             * @see #ZENITH_26_DEGREES
643             * @see #getAlos120()
644             * @see #getTzais120()
645             */
646            public Date getAlos26Degrees() {
647                    return getSunriseOffsetByDegrees(ZENITH_26_DEGREES);
648            }
649    
650            /**
651             * to return <em>alos</em> (dawn) calculated when the sun is
652             * {@link #ASTRONOMICAL_ZENITH 18&deg;} below the eastern geometric horizon
653             * before sunrise.
654             * 
655             * @return the <code>Date</code> representing <em>alos</em>.
656             * @see #ASTRONOMICAL_ZENITH
657             */
658            public Date getAlos18Degrees() {
659                    return getSunriseOffsetByDegrees(ASTRONOMICAL_ZENITH);
660            }
661    
662            /**
663             * Method to return <em>alos</em> (dawn) calculated when the sun is
664             * {@link #ZENITH_19_POINT_8 19.8&deg;} below the eastern geometric horizon
665             * before sunrise. This calculation is based on the same calculation of
666             * {@link #getAlos90() 90 minutes} but uses a degree based calculation
667             * instead of 90 exact minutes. This calculation is based on the position of
668             * the sun 90 minutes before sunrise in Jerusalem in the equinox which
669             * calculates to 19.8&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
670             * 
671             * @return the <code>Date</code> representing <em>alos</em>.
672             * @see #ZENITH_19_POINT_8
673             * @see #getAlos90()
674             */
675            public Date getAlos19Point8Degrees() {
676                    return getSunriseOffsetByDegrees(ZENITH_19_POINT_8);
677            }
678    
679            /**
680             * Method to return <em>alos</em> (dawn) calculated when the sun is
681             * {@link #ZENITH_16_POINT_1 16.1&deg;} below the eastern geometric horizon
682             * before sunrise. This calculation is based on the same calculation of
683             * {@link #getAlos72() 72 minutes} but uses a degree based calculation
684             * instead of 72 exact minutes. This calculation is based on the position of
685             * the sun 72 minutes before sunrise in Jerusalem in the equinox which
686             * calculates to 16.1&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}.
687             * 
688             * @return the <code>Date</code> representing <em>alos</em>.
689             * @see #ZENITH_16_POINT_1
690             * @see #getAlos72()
691             */
692            public Date getAlos16Point1Degrees() {
693                    return getSunriseOffsetByDegrees(ZENITH_16_POINT_1);
694            }
695    
696            /**
697             * This method returns <em>misheyakir</em> based on the position of the
698             * sun when it is {@link #ZENITH_11_DEGREES 11.5&deg;} below
699             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
700             * is used for calculating <em>misheyakir</em> according to some opinions.
701             * This calculation is based on the position of the sun 52 minutes before
702             * {@link #getSunrise sunrise}in Jerusalem in the equinox which calculates
703             * to 11.5&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
704             * 
705             * @see #ZENITH_11_POINT_5
706             */
707            public Date getMisheyakir11Point5Degrees() {
708                    return getSunriseOffsetByDegrees(ZENITH_11_POINT_5);
709            }
710    
711            /**
712             * This method returns <em>misheyakir</em> based on the position of the
713             * sun when it is {@link #ZENITH_11_DEGREES 11&deg;} below
714             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
715             * is used for calculating <em>misheyakir</em> according to some opinions.
716             * This calculation is based on the position of the sun 48 minutes before
717             * {@link #getSunrise sunrise}in Jerusalem in the equinox which calculates
718             * to 11&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
719             * 
720             * @see #ZENITH_11_DEGREES
721             */
722            public Date getMisheyakir11Degrees() {
723                    return getSunriseOffsetByDegrees(ZENITH_11_DEGREES);
724            }
725    
726            /**
727             * This method returns <em>misheyakir</em> based on the position of the
728             * sun when it is {@link #ZENITH_10_POINT_2 10.2&deg;} below
729             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
730             * is used for calculating <em>misheyakir</em> according to some opinions.
731             * This calculation is based on the position of the sun 45 minutes before
732             * {@link #getSunrise sunrise} in Jerusalem in the equinox which calculates
733             * to 10.2&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
734             * 
735             * @see #ZENITH_10_POINT_2
736             */
737            public Date getMisheyakir10Point2Degrees() {
738                    return getSunriseOffsetByDegrees(ZENITH_10_POINT_2);
739            }
740    
741            /**
742             * This method returns the latest <em>zman krias shema</em> (time to say
743             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
744             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 19.8&deg;}
745             * before {@link #getSunrise() sunrise}. This time is 3
746             * <em>{@link #getShaahZmanis19Point8Degrees() shaos zmaniyos}</em> (solar
747             * hours) after {@link #getAlos19Point8Degrees() dawn} based on the opinion
748             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
749             * with both being 19.8&deg; below sunrise or sunset. This returns the time
750             * of 3 *{@link #getShaahZmanis19Point8Degrees()} after
751             * {@link #getAlos19Point8Degrees() dawn}.
752             * 
753             * @return the <code>Date</code> of the latest zman shema.
754             * @see #getShaahZmanis19Point8Degrees()
755             * @see #getAlos19Point8Degrees()
756             */
757            public Date getSofZmanShmaMGA19Point8Degrees() {
758                    return getTimeOffset(getAlos19Point8Degrees(),
759                                    getShaahZmanis19Point8Degrees() * 3);
760            }
761    
762            /**
763             * This method returns the latest <em>zman krias shema</em> (time to say
764             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
765             * <em>alos</em> being {@link #getAlos16Point1Degrees()() 16.1&deg;}
766             * before {@link #getSunrise() sunrise}. This time is 3
767             * <em>{@link #getShaahZmanis16Point1Degrees() shaos zmaniyos}</em> (solar
768             * hours) after {@link #getAlos16Point1Degrees() dawn} based on the opinion
769             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
770             * with both being 16.1&deg; below sunrise or sunset. This returns the time
771             * of 3 *{@link #getShaahZmanis16Point1Degrees()} after
772             * {@link #getAlos16Point1Degrees() dawn}.
773             * 
774             * @return the <code>Date</code> of the latest zman shema.
775             * @see #getShaahZmanis16Point1Degrees()
776             * @see #getAlos16Point1Degrees()
777             */
778            public Date getSofZmanShmaMGA16Point1Degrees() {
779                    return getTimeOffset(getAlos16Point1Degrees(),
780                                    getShaahZmanis16Point1Degrees() * 3);
781            }
782    
783            /**
784             * This method returns the latest <em>zman krias shema</em> (time to say
785             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
786             * <em>alos</em> being {@link #getAlos72() 72} minutes before
787             * {@link #getSunrise() sunrise}. This time is 3
788             * <em>{@link #getShaahZmanis72Minutes() shaos zmaniyos}</em> (solar
789             * hours) after {@link #getAlos72() dawn} based on the opinion of the
790             * <em>MG"A</em> that the day is calculated from a
791             * {@link #getAlos72() dawn} of 72 minutes before sunrise to
792             * {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns
793             * the time of 3 * {@link #getShaahZmanis72Minutes()} after
794             * {@link #getAlos72() dawn}. This class returns an identical time to
795             * {@link #getSofZmanShmaMGA()} and is repeated here for clarity.
796             * 
797             * @return the <code>Date</code> of the latest zman shema.
798             * @see #getShaahZmanis72Minutes()
799             * @see #getAlos72()
800             * @see #getSofZmanShmaMGA()
801             */
802            public Date getSofZmanShmaMGA72Minutes() {
803                    return getSofZmanShmaMGA();
804            }
805    
806            /**
807             * This method returns the latest <em>zman krias shema</em> (time to say
808             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
809             * <em>alos</em> being {@link #getAlos90Zmanis() 90} minutes
810             * <em>zmaniyos</em> before {@link #getSunrise() sunrise}. This time is 3
811             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
812             * hours) after {@link #getAlos90Zmanis() dawn} based on the opinion of the
813             * <em>MG"A</em> that the day is calculated from a
814             * {@link #getAlos90Zmanis() dawn} of 90 minutes <em>zmaniyos</em> before
815             * sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
816             * <em>zmaniyos</em> after sunset. This returns the time of 3 *
817             * {@link #getShaahZmanis90MinutesZmanis()} after
818             * {@link #getAlos90Zmanis() dawn}.
819             * 
820             * @return the <code>Date</code> of the latest zman shema.
821             * @see #getShaahZmanis72MinutesZmanis()
822             * @see #getAlos72Zmanis()
823             */
824            public Date getSofZmanShmaMGA72MinutesZmanis() {
825                    return getTimeOffset(getAlos72Zmanis(),
826                                    getShaahZmanis72MinutesZmanis() * 3);
827            }
828    
829            /**
830             * This method returns the latest <em>zman krias shema</em> (time to say
831             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
832             * <em>alos</em> being {@link #getAlos90() 90} minutes before
833             * {@link #getSunrise() sunrise}. This time is 3
834             * <em>{@link #getShaahZmanis90Minutes() shaos zmaniyos}</em> (solar
835             * hours) after {@link #getAlos90() dawn} based on the opinion of the
836             * <em>MG"A</em> that the day is calculated from a
837             * {@link #getAlos90() dawn} of 90 minutes before sunrise to
838             * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns
839             * the time of 3 * {@link #getShaahZmanis90Minutes()} after
840             * {@link #getAlos90() dawn}.
841             * 
842             * @return the <code>Date</code> of the latest zman shema.
843             * @see #getShaahZmanis90Minutes()
844             * @see #getAlos90()
845             */
846            public Date getSofZmanShmaMGA90Minutes() {
847                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 3);
848            }
849    
850            /**
851             * This method returns the latest <em>zman krias shema</em> (time to say
852             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
853             * <em>alos</em> being {@link #getAlos90Zmanis() 90} minutes
854             * <em>zmaniyos</em> before {@link #getSunrise() sunrise}. This time is 3
855             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
856             * hours) after {@link #getAlos90Zmanis() dawn} based on the opinion of the
857             * <em>MG"A</em> that the day is calculated from a
858             * {@link #getAlos90Zmanis() dawn} of 90 minutes <em>zmaniyos</em> before
859             * sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
860             * <em>zmaniyos</em> after sunset. This returns the time of 3 *
861             * {@link #getShaahZmanis90MinutesZmanis()} after
862             * {@link #getAlos90Zmanis() dawn}.
863             * 
864             * @return the <code>Date</code> of the latest zman shema.
865             * @see #getShaahZmanis90MinutesZmanis()
866             * @see #getAlos90Zmanis()
867             */
868            public Date getSofZmanShmaMGA90MinutesZmanis() {
869                    return getTimeOffset(getAlos90Zmanis(),
870                                    getShaahZmanis90MinutesZmanis() * 3);
871            }
872    
873            /**
874             * This method returns the latest <em>zman krias shema</em> (time to say
875             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
876             * <em>alos</em> being {@link #getAlos96() 96} minutes before
877             * {@link #getSunrise() sunrise}. This time is 3
878             * <em>{@link #getShaahZmanis96Minutes() shaos zmaniyos}</em> (solar
879             * hours) after {@link #getAlos96() dawn} based on the opinion of the
880             * <em>MG"A</em> that the day is calculated from a
881             * {@link #getAlos96() dawn} of 96 minutes before sunrise to
882             * {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns
883             * the time of 3 * {@link #getShaahZmanis96Minutes()} after
884             * {@link #getAlos96() dawn}.
885             * 
886             * @return the <code>Date</code> of the latest zman shema.
887             * @see #getShaahZmanis96Minutes()
888             * @see #getAlos96()
889             */
890            public Date getSofZmanShmaMGA96Minutes() {
891                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 3);
892            }
893    
894            /**
895             * This method returns the latest <em>zman krias shema</em> (time to say
896             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
897             * <em>alos</em> being {@link #getAlos90Zmanis() 96} minutes
898             * <em>zmaniyos</em> before {@link #getSunrise() sunrise}. This time is 3
899             * <em>{@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos}</em> (solar
900             * hours) after {@link #getAlos96Zmanis() dawn} based on the opinion of the
901             * <em>MG"A</em> that the day is calculated from a
902             * {@link #getAlos96Zmanis() dawn} of 96 minutes <em>zmaniyos</em> before
903             * sunrise to {@link #getTzais90Zmanis() nightfall} of 96 minutes
904             * <em>zmaniyos</em> after sunset. This returns the time of 3 *
905             * {@link #getShaahZmanis96MinutesZmanis()} after
906             * {@link #getAlos96Zmanis() dawn}.
907             * 
908             * @return the <code>Date</code> of the latest zman shema.
909             * @see #getShaahZmanis96MinutesZmanis()
910             * @see #getAlos96Zmanis()
911             */
912            public Date getSofZmanShmaMGA96MinutesZmanis() {
913                    return getTimeOffset(getAlos96Zmanis(),
914                                    getShaahZmanis96MinutesZmanis() * 3);
915            }
916    
917            /**
918             * This method returns the latest <em>zman krias shema</em> (time to say
919             * Shema in the morning) calculated as 3 hours before
920             * {@link ZmanimCalendar#getChatzos()}. This is the opinion of the
921             * <em>Shach</em> in the
922             * <em>Nekudas Hakesef (Yora Deah 184), Shevus Yaakov, Chasan Sofer</em>
923             * and others.This returns the time of 3 hours before
924             * {@link ZmanimCalendar#getChatzos()}.
925             * 
926             * @return the <code>Date</code> of the latest zman shema.
927             * @see ZmanimCalendar#getChatzos()
928             * @see #getSofZmanTfila2HoursBeforeChatzos()
929             */
930            public Date getSofZmanShma3HoursBeforeChatzos() {
931                    return getTimeOffset(getChatzos(), -180 * MINUTE_MILLIS);
932            }
933    
934            /**
935             * This method returns the latest <em>zman krias shema</em> (time to say
936             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
937             * <em>alos</em> being {@link #getAlos120() 120} minutes before
938             * {@link #getSunrise() sunrise}. This time is 3
939             * <em>{@link #getShaahZmanis120Minutes() shaos zmaniyos}</em> (solar
940             * hours) after {@link #getAlos120() dawn} based on the opinion of the
941             * <em>MG"A</em> that the day is calculated from a
942             * {@link #getAlos120() dawn} of 120 minutes before sunrise to
943             * {@link #getTzais120() nightfall} of 120 minutes after sunset. This
944             * returns the time of 3 *{@link #getShaahZmanis120Minutes()} after
945             * {@link #getAlos120() dawn}.
946             * 
947             * @return the <code>Date</code> of the latest zman shema.
948             * @see #getShaahZmanis120Minutes()
949             * @see #getAlos120()
950             */
951            public Date getSofZmanShmaMGA120Minutes() {
952                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 3);
953            }
954    
955            /**
956             * This method returns the latest <em>zman krias shema</em> (time to say
957             * Shema in the morning) based on the opinion that the day starts at
958             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
959             * {@link #getSunset() sunset}. 3 shaos zmaniyos are calculated based on
960             * this day and added to {@link #getAlos16Point1Degrees() alos}to reach
961             * this time. This time is 3 <em>shaos zmaniyos</em> (solar hours) after
962             * {@link #getAlos16Point1Degrees() dawn} based on the opinion that the day
963             * is calculated from a {@link #getAlos16Point1Degrees() alos 16.1&deg;} to
964             * {@link #getSunset() sunset}.<br />
965             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
966             * midday.
967             * 
968             * @return the <code>Date</code> of the latest zman shema based on this
969             *         day.
970             * @see #getAlos16Point1Degrees()
971             * @see #getSunset()
972             */
973            public Date getSofZmanShmaAlos16Point1ToSunset() {
974                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
975                                    getSunset());
976                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 3);
977            }
978    
979            /**
980             * This method returns the latest <em>zman krias shema</em> (time to say
981             * Shema in the morning) based on the opinion that the day starts at
982             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
983             * {@link #getTzaisGeonim7Point083Degrees() tzais 7.083&deg;}. 3
984             * <em>shaos zmaniyos</em> are calculated based on this day and added to
985             * {@link #getAlos16Point1Degrees() alos} to reach this time. This time is 3
986             * <em>shaos zmaniyos</em> (temporal hours) after
987             * {@link #getAlos16Point1Degrees() alos 16.1&deg;} based on the opinion
988             * that the day is calculated from a
989             * {@link #getAlos16Point1Degrees() alos 16.1&deg;} to
990             * <em>{@link #getTzaisGeonim7Point083Degrees() tzais 7.083&deg;}</em>.<br />
991             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
992             * midday.
993             * 
994             * @return the <code>Date</code> of the latest zman shema based on this
995             *         day.
996             * @see #getAlos16Point1Degrees()
997             * @see #getTzaisGeonim7Point083Degrees()
998             */
999            public Date getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees() {
1000                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1001                                    getTzaisGeonim7Point083Degrees());
1002                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 3);
1003            }
1004    
1005            public Date getSofZmanShmaKolEliyahu() {
1006                    Date chatzos = getFixedLocalChatzos();
1007                    if (chatzos == null || getSunrise() == null) {
1008                            return null;
1009                    }
1010                    long diff = (chatzos.getTime() - getSunrise().getTime()) / 2;
1011                    return getTimeOffset(chatzos, -diff);
1012            }
1013    
1014            /**
1015             * This method returns the latest <em>zman tfila</em> (time to say the
1016             * morning prayers) in the opinion of the <em>MG"A</em> based on
1017             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 19.8&deg;}
1018             * before {@link #getSunrise() sunrise}. This time is 4
1019             * <em>{@link #getShaahZmanis19Point8Degrees() shaos zmaniyos}</em> (solar
1020             * hours) after {@link #getAlos19Point8Degrees() dawn} based on the opinion
1021             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
1022             * with both being 19.8&deg; below sunrise or sunset. This returns the time
1023             * of 4 *{@link #getShaahZmanis19Point8Degrees()} after
1024             * {@link #getAlos19Point8Degrees() dawn}.
1025             * 
1026             * @return the <code>Date</code> of the latest zman shema.
1027             * 
1028             * @see #getShaahZmanis19Point8Degrees()
1029             * @see #getAlos19Point8Degrees()
1030             */
1031            public Date getSofZmanTfilaMGA19Point8Degrees() {
1032                    return getTimeOffset(getAlos19Point8Degrees(),
1033                                    getShaahZmanis19Point8Degrees() * 4);
1034            }
1035    
1036            /**
1037             * This method returns the latest <em>zman tfila</em> (time to say the
1038             * morning prayers) in the opinion of the <em>MG"A</em> based on
1039             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 16.1&deg;}
1040             * before {@link #getSunrise() sunrise}. This time is 4
1041             * <em>{@link #getShaahZmanis16Point1Degrees() shaos zmaniyos}</em> (solar
1042             * hours) after {@link #getAlos16Point1Degrees() dawn} based on the opinion
1043             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
1044             * with both being 16.1&deg; below sunrise or sunset. This returns the time
1045             * of 4 *{@link #getShaahZmanis16Point1Degrees()} after
1046             * {@link #getAlos16Point1Degrees() dawn}.
1047             * 
1048             * @return the <code>Date</code> of the latest zman shema.
1049             * 
1050             * @see #getShaahZmanis16Point1Degrees()
1051             * @see #getAlos16Point1Degrees()
1052             */
1053            public Date getSofZmanTfilaMGA16Point1Degrees() {
1054                    return getTimeOffset(getAlos16Point1Degrees(),
1055                                    getShaahZmanis16Point1Degrees() * 4);
1056            }
1057    
1058            /**
1059             * This method returns the latest <em>zman tfila</em> (time to say the
1060             * morning prayers) in the opinion of the <em>MG"A</em> based on
1061             * <em>alos</em> being {@link #getAlos72() 72} minutes before
1062             * {@link #getSunrise() sunrise}. This time is 4
1063             * <em>{@link #getShaahZmanis72Minutes() shaos zmaniyos}</em> (solar
1064             * hours) after {@link #getAlos72() dawn} based on the opinion of the
1065             * <em>MG"A</em> that the day is calculated from a
1066             * {@link #getAlos72() dawn} of 72 minutes before sunrise to
1067             * {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns
1068             * the time of 4 * {@link #getShaahZmanis72Minutes()} after
1069             * {@link #getAlos72() dawn}. This class returns an identical time to
1070             * {@link #getSofZmanTfilaMGA()} and is repeated here for clarity.
1071             * 
1072             * @return the <code>Date</code> of the latest zman tfila.
1073             * @see #getShaahZmanis72Minutes()
1074             * @see #getAlos72()
1075             * @see #getSofZmanShmaMGA()
1076             */
1077            public Date getSofZmanTfilaMGA72Minutes() {
1078                    return getSofZmanTfilaMGA();
1079            }
1080    
1081            /**
1082             * This method returns the latest <em>zman tfila</em> (time to the morning
1083             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1084             * being {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> before
1085             * {@link #getSunrise() sunrise}. This time is 4
1086             * <em>{@link #getShaahZmanis72MinutesZmanis() shaos zmaniyos}</em> (solar
1087             * hours) after {@link #getAlos72Zmanis() dawn} based on the opinion of the
1088             * <em>MG"A</em> that the day is calculated from a
1089             * {@link #getAlos72Zmanis() dawn} of 72 minutes <em>zmaniyos</em> before
1090             * sunrise to {@link #getTzais72Zmanis() nightfall} of 72 minutes
1091             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1092             * {@link #getShaahZmanis72MinutesZmanis()} after
1093             * {@link #getAlos72Zmanis() dawn}.
1094             * 
1095             * @return the <code>Date</code> of the latest zman shema.
1096             * @see #getShaahZmanis72MinutesZmanis()
1097             * @see #getAlos72Zmanis()
1098             */
1099            public Date getSofZmanTfilaMGA72MinutesZmanis() {
1100                    return getTimeOffset(getAlos72Zmanis(),
1101                                    getShaahZmanis72MinutesZmanis() * 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 #getAlos90() 90} minutes before
1108             * {@link #getSunrise() sunrise}. This time is 4
1109             * <em>{@link #getShaahZmanis90Minutes() shaos zmaniyos}</em> (solar
1110             * hours) after {@link #getAlos90() dawn} based on the opinion of the
1111             * <em>MG"A</em> that the day is calculated from a
1112             * {@link #getAlos90() dawn} of 90 minutes before sunrise to
1113             * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns
1114             * the time of 4 * {@link #getShaahZmanis90Minutes()} after
1115             * {@link #getAlos90() dawn}.
1116             * 
1117             * @return the <code>Date</code> of the latest zman tfila.
1118             * @see #getShaahZmanis90Minutes()
1119             * @see #getAlos90()
1120             */
1121            public Date getSofZmanTfilaMGA90Minutes() {
1122                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 4);
1123            }
1124    
1125            /**
1126             * This method returns the latest <em>zman tfila</em> (time to the morning
1127             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1128             * being {@link #getAlos90Zmanis() 90} minutes <em>zmaniyos</em> before
1129             * {@link #getSunrise() sunrise}. This time is 4
1130             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
1131             * hours) after {@link #getAlos90Zmanis() dawn} based on the opinion of the
1132             * <em>MG"A</em> that the day is calculated from a
1133             * {@link #getAlos90Zmanis() dawn} of 90 minutes <em>zmaniyos</em> before
1134             * sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
1135             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1136             * {@link #getShaahZmanis90MinutesZmanis()} after
1137             * {@link #getAlos90Zmanis() dawn}.
1138             * 
1139             * @return the <code>Date</code> of the latest zman shema.
1140             * @see #getShaahZmanis90MinutesZmanis()
1141             * @see #getAlos90Zmanis()
1142             */
1143            public Date getSofZmanTfilaMGA90MinutesZmanis() {
1144                    return getTimeOffset(getAlos90Zmanis(),
1145                                    getShaahZmanis90MinutesZmanis() * 4);
1146            }
1147    
1148            /**
1149             * This method returns the latest <em>zman tfila</em> (time to say the
1150             * morning prayers) in the opinion of the <em>MG"A</em> based on
1151             * <em>alos</em> being {@link #getAlos96() 96} minutes before
1152             * {@link #getSunrise() sunrise}. This time is 4
1153             * <em>{@link #getShaahZmanis96Minutes() shaos zmaniyos}</em> (solar
1154             * hours) after {@link #getAlos96() dawn} based on the opinion of the
1155             * <em>MG"A</em> that the day is calculated from a
1156             * {@link #getAlos96() dawn} of 96 minutes before sunrise to
1157             * {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns
1158             * the time of 4 * {@link #getShaahZmanis96Minutes()} after
1159             * {@link #getAlos96() dawn}.
1160             * 
1161             * @return the <code>Date</code> of the latest zman tfila.
1162             * @see #getShaahZmanis96Minutes()
1163             * @see #getAlos96()
1164             */
1165            public Date getSofZmanTfilaMGA96Minutes() {
1166                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 4);
1167            }
1168    
1169            /**
1170             * This method returns the latest <em>zman tfila</em> (time to the morning
1171             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1172             * being {@link #getAlos96Zmanis() 96} minutes <em>zmaniyos</em> before
1173             * {@link #getSunrise() sunrise}. This time is 4
1174             * <em>{@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos}</em> (solar
1175             * hours) after {@link #getAlos96Zmanis() dawn} based on the opinion of the
1176             * <em>MG"A</em> that the day is calculated from a
1177             * {@link #getAlos96Zmanis() dawn} of 96 minutes <em>zmaniyos</em> before
1178             * sunrise to {@link #getTzais96Zmanis() nightfall} of 96 minutes
1179             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1180             * {@link #getShaahZmanis96MinutesZmanis()} after
1181             * {@link #getAlos96Zmanis() dawn}.
1182             * 
1183             * @return the <code>Date</code> of the latest zman shema.
1184             * @see #getShaahZmanis90MinutesZmanis()
1185             * @see #getAlos90Zmanis()
1186             */
1187            public Date getSofZmanTfilaMGA96MinutesZmanis() {
1188                    return getTimeOffset(getAlos96Zmanis(),
1189                                    getShaahZmanis96MinutesZmanis() * 4);
1190            }
1191    
1192            /**
1193             * This method returns the latest <em>zman tfila</em> (time to say the
1194             * morning prayers) in the opinion of the <em>MG"A</em> based on
1195             * <em>alos</em> being {@link #getAlos120() 120} minutes before
1196             * {@link #getSunrise() sunrise}. This time is 4
1197             * <em>{@link #getShaahZmanis120Minutes() shaos zmaniyos}</em> (solar
1198             * hours) after {@link #getAlos120() dawn} based on the opinion of the
1199             * <em>MG"A</em> that the day is calculated from a
1200             * {@link #getAlos120() dawn} of 120 minutes before sunrise to
1201             * {@link #getTzais120() nightfall} of 120 minutes after sunset. This
1202             * returns the time of 4 *{@link #getShaahZmanis120Minutes()} after
1203             * {@link #getAlos120() dawn}.
1204             * 
1205             * @return the <code>Date</code> of the latest zman shema.
1206             * @see #getShaahZmanis120Minutes()
1207             * @see #getAlos120()
1208             */
1209            public Date getSofZmanTfilaMGA120Minutes() {
1210                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 4);
1211            }
1212    
1213            /**
1214             * This method returns the latest <em>zman tfila</em> (time to say the
1215             * morning prayers) calculated as 2 hours befor
1216             * {@link ZmanimCalendar#getChatzos()}. This is based on the opinions that
1217             * calculate <em>sof zman krias shema</em> as
1218             * {@link #getSofZmanShma3HoursBeforeChatzos()}. This returns the time of 2
1219             * hours before {@link ZmanimCalendar#getChatzos()}.
1220             * 
1221             * @return the <code>Date</code> of the latest zman shema.
1222             * @see ZmanimCalendar#getChatzos()
1223             * @see #getSofZmanShma3HoursBeforeChatzos()
1224             */
1225            public Date getSofZmanTfila2HoursBeforeChatzos() {
1226                    return getTimeOffset(getChatzos(), -120 * MINUTE_MILLIS);
1227            }
1228    
1229            /**
1230             * This method returns mincha gedola calculated as 30 minutes after
1231             * <em>{@link #getChatzos() chatzos}</em> and not 1/2 of a
1232             * <em>{@link #getShaahZmanisGra() shaah zmanis}</em> after
1233             * <em>{@link #getChatzos() chatzos}</em> as calculated by
1234             * {@link #getMinchaGedola}. Some use this time to delay the start of
1235             * mincha in the winter when 1/2 of a
1236             * <em>{@link #getShaahZmanisGra() shaah zmanis}</em> is less than 30
1237             * minutes. See {@link #getMinchaGedolaGreaterThan30()}for a conveniance
1238             * method that returns the later of the 2 calculations. One should not use
1239             * this time to start <em>mincha</em> before the standard
1240             * <em>{@link #getMinchaGedola() mincha gedola}</em>. See
1241             * <em>Shulchan Aruch
1242             * Orach Chayim Siman Raish Lamed Gimel seif alef</em>
1243             * and the <em>Shaar Hatziyon seif katan ches</em>.
1244             * 
1245             * @return the <code>Date</code> of 30 mintes after <em>chatzos</em>.
1246             * @see #getMinchaGedola()
1247             * @see #getMinchaGedolaGreaterThan30()
1248             */
1249            public Date getMinchaGedola30Minutes() {
1250                    return getTimeOffset(getChatzos(), MINUTE_MILLIS * 30);
1251            }
1252    
1253            public Date getMinchaGedola72Minutes() {
1254                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 6.5);
1255            }
1256    
1257            /**
1258             * @see ZmanimCalendar#getMinchaGedola() This method returns the time of
1259             *      <em>mincha gedola</em> according to the Magen Avraham with the day
1260             *      starting and ending 16.1&deg; below the horizon. This is the
1261             *      perfered earliest time to pray <em>mincha</em> in the opinion of
1262             *      the Ramba"m and others. For more information on this see the
1263             *      documentation on <em>{@link #getMinchaGedola() mincha gedola}</em>.
1264             *      This is calculated as 9.5 {@link #getTemporalHour() solar hours}
1265             *      after alos. The calculation used is 9.5 *
1266             *      {@link #getShaahZmanis16Point1Degrees()} after
1267             *      {@link #getAlos16Point1Degrees() alos}.
1268             * @see #getShaahZmanis16Point1Degrees()
1269             * @see #getMinchaGedola()
1270             * @see #getMinchaKetana()
1271             * @return the <code>Date</code> of the time of mincha gedola.
1272             */
1273            public Date getMinchaGedola16Point1Degrees() {
1274                    return getTimeOffset(getAlos16Point1Degrees(),
1275                                    getShaahZmanis16Point1Degrees() * 6.5);
1276            }
1277    
1278            /**
1279             * This is a conveniance methd that returns the later of
1280             * {@link #getMinchaGedola()}and {@link #getMinchaGedola30Minutes()}. In
1281             * the winter when a <em>{@link #getShaahZmanisGra() shaah zmanis}</em> is
1282             * less than 30 minutes {@link #getMinchaGedola30Minutes()}will be
1283             * returned, otherwise {@link #getMinchaGedola()} will be returned.
1284             * 
1285             * @return the <code>Date</code> of the later of
1286             *         {@link #getMinchaGedola()}and
1287             *         {@link #getMinchaGedola30Minutes()}
1288             */
1289            public Date getMinchaGedolaGreaterThan30() {
1290                    if (getMinchaGedola30Minutes() == null || getMinchaGedola() == null) {
1291                            return null;
1292                    } else {
1293                            return getMinchaGedola30Minutes().compareTo(getMinchaGedola()) > 0 ? getMinchaGedola30Minutes()
1294                                            : getMinchaGedola();
1295                    }
1296            }
1297    
1298            /**
1299             * This method returns the time of <em>mincha ketana</em> according to the
1300             * Magen Avraham with the day starting and ending 16.1&deg; below the
1301             * horizon. This is the perfered earliest time to pray <em>mincha</em> in
1302             * the opinion of the Ramba"m and others. For more information on this see
1303             * the documentation on <em>{@link #getMinchaGedola() mincha gedola}</em>.
1304             * This is calculated as 9.5 {@link #getTemporalHour() solar hours} after
1305             * alos. The calculation used is 9.5 *
1306             * {@link #getShaahZmanis16Point1Degrees()} after
1307             * {@link #getAlos16Point1Degrees() alos}.
1308             * 
1309             * @see #getShaahZmanis16Point1Degrees()
1310             * @see #getMinchaGedola()
1311             * @see #getMinchaKetana()
1312             * @return the <code>Date</code> of the time of mincha gedola.
1313             */
1314            public Date getMinchaKetana16Point1Degrees() {
1315                    return getTimeOffset(getAlos16Point1Degrees(),
1316                                    getShaahZmanis16Point1Degrees() * 9.5);
1317            }
1318    
1319            /**
1320             * This method returns the time of <em>mincha ketana</em> according to the
1321             * Magen Avraham with the day starting 72 minutes before sunrise and ending
1322             * 72 minutes after sunset. This is the perfered earliest time to pray
1323             * <em>mincha</em> in the opinion of the Ramba"m and others. For more
1324             * information on this see the documentation on
1325             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1326             * as 9.5 {@link #getShaahZmanis72Minutes()} after alos. The calculation
1327             * used is 9.5 * {@link #getShaahZmanis72Minutes()} after
1328             * {@link #getAlos72() alos}.
1329             * 
1330             * @see #getShaahZmanis16Point1Degrees()
1331             * @see #getMinchaGedola()
1332             * @see #getMinchaKetana()
1333             * @return the <code>Date</code> of the time of mincha gedola.
1334             */
1335            public Date getMinchaKetana72Minutes() {
1336                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 9.5);
1337            }
1338    
1339            /**
1340             * This method returns the time of <em>plag hamincha</em>. This is
1341             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
1342             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
1343             * {@link #getAlos72()}.
1344             * 
1345             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1346             */
1347            public Date getPlagHamincha60Minutes() {
1348                    return getTimeOffset(getAlos60(), getShaahZmanis60Minutes() * 10.75);
1349            }
1350    
1351            /**
1352             * This method returns the time of <em>plag hamincha</em>. This is
1353             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
1354             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
1355             * {@link #getAlos72()}.
1356             * 
1357             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1358             */
1359            public Date getPlagHamincha72Minutes() {
1360                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 10.75);
1361            }
1362    
1363            /**
1364             * This method returns the time of <em>plag hamincha</em>. This is
1365             * calculated as 10.75 hours after {@link #getAlos90() dawn}. The formula
1366             * used is:<br/> 10.75 *{@link #getShaahZmanis90Minutes()} after
1367             * {@link #getAlos90()}.
1368             * 
1369             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1370             */
1371            public Date getPlagHamincha90Minutes() {
1372                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 10.75);
1373            }
1374    
1375            /**
1376             * This method returns the time of <em>plag hamincha</em>. This is
1377             * calculated as 10.75 hours after {@link #getAlos96() dawn}. The formula
1378             * used is:<br/> 10.75 *{@link #getShaahZmanis96Minutes()} after
1379             * {@link #getAlos96()}.
1380             * 
1381             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1382             */
1383            public Date getPlagHamincha96Minutes() {
1384                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 10.75);
1385            }
1386    
1387            /**
1388             * This method returns the time of <em>plag hamincha</em>. This is
1389             * calculated as 10.75 hours after {@link #getAlos96Zmanis() dawn}. The
1390             * formula used is:<br/> 10.75 * {@link #getShaahZmanis96MinutesZmanis()}
1391             * after {@link #getAlos96Zmanis() dawn}.
1392             * 
1393             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1394             */
1395            public Date getPlagHamincha96MinutesZmanis() {
1396                    return getTimeOffset(getAlos96Zmanis(),
1397                                    getShaahZmanis96MinutesZmanis() * 10.75);
1398            }
1399    
1400            /**
1401             * This method returns the time of <em>plag hamincha</em>. This is
1402             * calculated as 10.75 hours after {@link #getAlos90Zmanis() dawn}. The
1403             * formula used is:<br/> 10.75 * {@link #getShaahZmanis90MinutesZmanis()}
1404             * after {@link #getAlos90Zmanis() dawn}.
1405             * 
1406             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1407             */
1408            public Date getPlagHamincha90MinutesZmanis() {
1409                    return getTimeOffset(getAlos90Zmanis(),
1410                                    getShaahZmanis90MinutesZmanis() * 10.75);
1411            }
1412    
1413            /**
1414             * This method returns the time of <em>plag hamincha</em>. This is
1415             * calculated as 10.75 hours after {@link #getAlos72Zmanis() dawn}. The
1416             * formula used is:<br/> 10.75 * {@link #getShaahZmanis72MinutesZmanis()}
1417             * after {@link #getAlos72Zmanis() dawn}.
1418             * 
1419             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1420             */
1421            public Date getPlagHamincha72MinutesZmanis() {
1422                    return getTimeOffset(getAlos72Zmanis(),
1423                                    getShaahZmanis72MinutesZmanis() * 10.75);
1424            }
1425    
1426            /**
1427             * This method returns the time of <em>plag hamincha</em> based on the
1428             * opinion that the day starts at
1429             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1430             * <em>{@link #getTzais16Point1Degrees() tzais 16.1&deg;}</em>. This is
1431             * calculated as 10.75 hours <em>zmaniyos</em> after
1432             * {@link #getAlos16Point1Degrees() dawn}. The formula is<br/>10.75 *
1433             * {@link #getShaahZmanis16Point1Degrees()} after
1434             * {@link #getAlos16Point1Degrees()}.
1435             * 
1436             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1437             */
1438            public Date getPlagHamincha16Point1Degrees() {
1439                    return getTimeOffset(getAlos16Point1Degrees(),
1440                                    getShaahZmanis16Point1Degrees() * 10.75);
1441            }
1442    
1443            /**
1444             * This method returns the time of <em>plag hamincha</em> based on the
1445             * opinion that the day starts at
1446             * <em>{@link #getAlos19Point8Degrees() alos 19.8&deg;}</em> and ends at
1447             * <em>{@link #getTzais19Point8Degrees() tzais 19.8&deg;}</em>. This is
1448             * calculated as 10.75 hours <em>zmaniyos</em> after
1449             * {@link #getAlos19Point8Degrees() dawn}. The formula is<br/>10.75 *
1450             * {@link #getShaahZmanis19Point8Degrees()} after
1451             * {@link #getAlos19Point8Degrees()}.
1452             * 
1453             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1454             */
1455            public Date getPlagHamincha19Point8Degrees() {
1456                    return getTimeOffset(getAlos19Point8Degrees(),
1457                                    getShaahZmanis19Point8Degrees() * 10.75);
1458            }
1459    
1460            /**
1461             * This method returns the time of <em>plag hamincha</em> based on the
1462             * opinion that the day starts at
1463             * <em>{@link #getAlos26Degrees() alos 26&deg;}</em> and ends at
1464             * <em>{@link #getTzais26Degrees() tzais 26&deg;}</em>. This is
1465             * calculated as 10.75 hours <em>zmaniyos</em> after
1466             * {@link #getAlos26Degrees() dawn}. The formula is<br/>10.75 *
1467             * {@link #getShaahZmanis26Degrees()} after {@link #getAlos26Degrees()}.
1468             * 
1469             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1470             */
1471            public Date getPlagHamincha26Degrees() {
1472                    return getTimeOffset(getAlos26Degrees(),
1473                                    getShaahZmanis26Degrees() * 10.75);
1474            }
1475    
1476            /**
1477             * This method returns the time of <em>plag hamincha</em> based on the
1478             * opinion that the day starts at
1479             * <em>{@link #getAlos18Degrees() alos 18&deg;}</em> and ends at
1480             * <em>{@link #getTzais18Degrees() tzais 18&deg;}</em>. This is
1481             * calculated as 10.75 hours <em>zmaniyos</em> after
1482             * {@link #getAlos18Degrees() dawn}. The formula is<br/>10.75 *
1483             * {@link #getShaahZmanis18Degrees()} after {@link #getAlos18Degrees()}.
1484             * 
1485             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1486             */
1487            public Date getPlagHamincha18Degrees() {
1488                    return getTimeOffset(getAlos18Degrees(),
1489                                    getShaahZmanis18Degrees() * 10.75);
1490            }
1491    
1492            /**
1493             * This method returns the time of <em>plag hamincha</em> based on the
1494             * opinion that the day starts at
1495             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1496             * {@link #getSunset() sunset}. 10.75 shaos zmaniyos are calculated based
1497             * on this day and added to {@link #getAlos16Point1Degrees() alos} to reach
1498             * this time. This time is 10.75 <em>shaos zmaniyos</em> (temporal hours)
1499             * after {@link #getAlos16Point1Degrees() dawn} based on the opinion that
1500             * the day is calculated from a {@link #getAlos16Point1Degrees() dawn} of
1501             * 16.1 degrees before sunrise to {@link #getSunset() sunset}. This returns
1502             * the time of 10.75 * the calculated <em>shaah zmanis</em> after
1503             * {@link #getAlos16Point1Degrees() dawn}.
1504             * 
1505             * @return the <code>Date</code> of the plag.
1506             * @see #getAlos16Point1Degrees()
1507             * @see #getSunset()
1508             */
1509            public Date getPlagAlosToSunset() {
1510                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1511                                    getSunset());
1512                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 10.75);
1513            }
1514    
1515            /**
1516             * This method returns the time of <em>plag hamincha</em> based on the
1517             * opinion that the day starts at
1518             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1519             * {@link #getTzaisGeonim7Point083Degrees() tzais}. 10.75 shaos zmaniyos
1520             * are calculated based on this day and added to
1521             * {@link #getAlos16Point1Degrees() alos} to reach this time. This time is
1522             * 10.75 <em>shaos zmaniyos</em> (temporal hours) after
1523             * {@link #getAlos16Point1Degrees() dawn} based on the opinion that the day
1524             * is calculated from a {@link #getAlos16Point1Degrees() dawn} of 16.1
1525             * degrees before sunrise to {@link #getTzaisGeonim7Point083Degrees() tzais}.
1526             * This returns the time of 10.75 * the calculated <em>shaah zmanis</em>
1527             * after {@link #getAlos16Point1Degrees() dawn}.
1528             * 
1529             * @return the <code>Date</code> of the plag.
1530             * @see #getAlos16Point1Degrees()
1531             * @see #getTzaisGeonim7Point083Degrees()
1532             */
1533            public Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() {
1534                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1535                                    getTzaisGeonim7Point083Degrees());
1536                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 10.75);
1537            }
1538    
1539            public Date getBainHasmashosRT13Degrees() {
1540                    return getSunsetOffsetByDegrees(ZENITH_13_DEGREES);
1541            }
1542    
1543            public Date getBainHasmashosRT58Point5Minutes() {
1544                    return getTimeOffset(getSeaLevelSunset(), 58.5 * MINUTE_MILLIS);
1545            }
1546    
1547            public Date getBainHasmashosRT13Point5MinutesBefore7Point083Degrees() {
1548                    return getTimeOffset(getSunsetOffsetByDegrees(ZENITH_7_POINT_083),
1549                                    -13.5 * MINUTE_MILLIS);
1550            }
1551    
1552            public Date getBainHasmashosRT2Stars() {
1553                    Date alos19Point8 = getAlos19Point8Degrees();
1554                    Date sunrise = getSunrise();
1555                    if (alos19Point8 == null || sunrise == null) {
1556                            return null;
1557                    }
1558                    return getTimeOffset(getSunset(), (sunrise.getTime() - alos19Point8
1559                                    .getTime())
1560                                    * (5 / 18d));
1561            }
1562    
1563            /**
1564             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1565             * of the <em>Geonim</em> calculated at the sun's position at
1566             * {@link #ZENITH_5_POINT_95 5.95&deg;} below the western horizon.
1567             * 
1568             * @return the <code>Date</code> representing the time when the sun is
1569             *         5.95&deg; below sea level.
1570             * @see #ZENITH_5_POINT_95
1571             */
1572            public Date getTzaisGeonim5Point95Degrees() {
1573                    return getSunsetOffsetByDegrees(ZENITH_5_POINT_95);
1574            }
1575    
1576            /**
1577             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1578             * of the <em>Geonim</em> calculated at the sun's position at
1579             * {@link #ZENITH_7_POINT_083 7.083&deg;} below the western horizon.
1580             * 
1581             * @return the <code>Date</code> representing the time when the sun is
1582             *         7.083&deg; below sea level.
1583             * @see #ZENITH_7_POINT_083
1584             */
1585            public Date getTzaisGeonim7Point083Degrees() {
1586                    return getSunsetOffsetByDegrees(ZENITH_7_POINT_083);
1587            }
1588    
1589            /**
1590             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1591             * of the <em>Geonim</em> calculated at the sun's position at
1592             * {@link #ZENITH_8_POINT_5 8.5&deg;} below the western horizon.
1593             * 
1594             * @return the <code>Date</code> representing the time when the sun is
1595             *         8.5&deg; below sea level.
1596             * @see #ZENITH_8_POINT_5
1597             */
1598            public Date getTzaisGeonim8Point5Degrees() {
1599                    return getSunsetOffsetByDegrees(ZENITH_8_POINT_5);
1600            }
1601    
1602            /**
1603             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1604             * of the Chavas Yair and Divray Malkiel that the time to walk the distance
1605             * of a Mil is 15 minutes for a total of 60 minutes for 4 mil after sea
1606             * level sunset.
1607             * 
1608             * @return the <code>Date</code> representing 60 minutes after sea level
1609             *         sunset.
1610             */
1611            public Date getTzais60() {
1612                    return getTimeOffset(getSeaLevelSunset(), 60 * MINUTE_MILLIS);
1613            }
1614    
1615            /**
1616             * Method to return <em>tzais</em> (dusk) calculated using 72 minutes
1617             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after sea
1618             * level sunset.
1619             * 
1620             * @return the <code>Date</code> representing the time.
1621             */
1622            public Date getTzais72Zmanis() {
1623                    long shaahZmanis = getShaahZmanisGra();
1624                    if (shaahZmanis == Long.MIN_VALUE) {
1625                            return null;
1626                    }
1627                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.2);
1628            }
1629    
1630            /**
1631             * Method to return <em>tzais</em> (dusk) calculated using 90 minutes
1632             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1633             * {@link #getSeaLevelSunset() sea level sunset}.
1634             * 
1635             * @return the <code>Date</code> representing the time.
1636             */
1637            public Date getTzais90Zmanis() {
1638                    long shaahZmanis = getShaahZmanisGra();
1639                    if (shaahZmanis == Long.MIN_VALUE) {
1640                            return null;
1641                    }
1642                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.5);
1643            }
1644    
1645            /**
1646             * Method to return <em>tzais</em> (dusk) calculated using 96 minutes
1647             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1648             * {@link #getSeaLevelSunset() sea level sunset}.
1649             * 
1650             * @return the <code>Date</code> representing the time.
1651             */
1652            public Date getTzais96Zmanis() {
1653                    long shaahZmanis = getShaahZmanisGra();
1654                    if (shaahZmanis == Long.MIN_VALUE) {
1655                            return null;
1656                    }
1657                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.6);
1658            }
1659    
1660            /**
1661             * Method to return <em>tzais</em> (dusk) calculated as 90 minutes after
1662             * sea level sunset. This method returns <em>tzais</em> (nightfall) based
1663             * on the opinion of the Magen Avraham that the time to walk the distance of
1664             * a Mil in the Ramba"m's opinion is 18 minutes for a total of 90 minutes
1665             * based on the opinion of <em>Ula</em> who calculated <em>tzais</em> as
1666             * 5 Mil after sea level shkiah (sunset). A similar calculation
1667             * {@link #getTzais19Point8Degrees()}uses solar position calculations based
1668             * on this time.
1669             * 
1670             * @return the <code>Date</code> representing the time.
1671             * @see #getTzais19Point8Degrees()
1672             */
1673            public Date getTzais90() {
1674                    return getTimeOffset(getSeaLevelSunset(), 90 * MINUTE_MILLIS);
1675            }
1676    
1677            /**
1678             * This method returns <em>tzais</em> (nightfall) based on the opinion of
1679             * the Magen Avraham that the time to walk the distance of a Mil in the
1680             * Ramba"ms opinion is 2/5 of an hour (24 minutes) for a total of 120
1681             * minutes based on the opinion of <em>Ula</em> who calculated
1682             * <em>tzais</em> as 5 Mil after sea level shkiah (sunset). A similar
1683             * calculation {@link #getTzais26Degrees()} uses temporal calculations based
1684             * on this time.
1685             * 
1686             * @return the <code>Date</code> representing the time.
1687             * @see #getTzais26Degrees()
1688             */
1689            public Date getTzais120() {
1690                    return getTimeOffset(getSeaLevelSunset(), 120 * MINUTE_MILLIS);
1691            }
1692    
1693            /**
1694             * Method to return <em>tzais</em> (dusk) calculated using 120 minutes
1695             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1696             * {@link #getSeaLevelSunset() sea level sunset}.
1697             * 
1698             * @return the <code>Date</code> representing the time.
1699             */
1700            public Date getTzais120Zmanis() {
1701                    long shaahZmanis = getShaahZmanisGra();
1702                    if (shaahZmanis == Long.MIN_VALUE) {
1703                            return null;
1704                    }
1705                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 2.0);
1706            }
1707    
1708            /**
1709             * For information on how this is calculated see the comments on
1710             * {@link #getAlos16Point1Degrees()}
1711             * 
1712             * @return the <code>Date</code> representing the time.
1713             * @see #getTzais72()
1714             * @see #getAlos16Point1Degrees() for more information on this calculation.
1715             */
1716            public Date getTzais16Point1Degrees() {
1717                    return getSunsetOffsetByDegrees(ZENITH_16_POINT_1);
1718            }
1719    
1720            /**
1721             * For information on how this is calculated see the comments on
1722             * {@link #getAlos26Degrees()}
1723             * 
1724             * @return the <code>Date</code> representing the time.
1725             * @see #getTzais120()
1726             * @see #getAlos26Degrees()
1727             */
1728            public Date getTzais26Degrees() {
1729                    return getSunsetOffsetByDegrees(ZENITH_26_DEGREES);
1730            }
1731    
1732            public Date getTzais18Degrees() {
1733                    return getSunsetOffsetByDegrees(ASTRONOMICAL_ZENITH);
1734            }
1735    
1736            /**
1737             * For information on how this is calculated see the comments on
1738             * {@link #getAlos19Point8Degrees()}
1739             * 
1740             * @return the <code>Date</code> representing the time.
1741             * @see #getTzais90()
1742             * @see #getAlos19Point8Degrees()
1743             */
1744            public Date getTzais19Point8Degrees() {
1745                    return getSunsetOffsetByDegrees(ZENITH_19_POINT_8);
1746            }
1747    
1748            /**
1749             * A method to return <em>tzais</em> (dusk) calculated as 96 minutes after
1750             * sea level sunset. For information on how this is calculated see the
1751             * comments on {@link #getAlos96()}.
1752             * 
1753             * @return Date
1754             * @see #getAlos96()
1755             */
1756            public Date getTzais96() {
1757                    return getTimeOffset(getSeaLevelSunset(), 96 * MINUTE_MILLIS);
1758            }
1759    
1760            /**
1761             * A method that returns the local time for fixed <em>chatzos</em>. This
1762             * time is noon and midnight adjusted from standard time to account for the
1763             * local latitude. The 360&deg; of the globe divided by 24 calculates to
1764             * 15&deg; per hour with 4 minutes per degree, so at a longitude of 0 , 15,
1765             * 30 etc Chatzos in 12:00 noon. Lakewood, NJ whose longitude is -74.2094 is
1766             * 0.7906 away from the closest multiple of 15 at -75&deg;. This is
1767             * multiplied by 4 to yeild 3 minutes and 10 seconds for a chatzos of
1768             * 11:56:50. This method is not tied to the theoretical 15&deg; timezones,
1769             * but will adjust to the actual timezone and <a
1770             * href="http://en.wikipedia.org/wiki/Daylight_saving_time">Daylight saving
1771             * time</a>.
1772             * 
1773             * @return the Date representing the local <em>chatzos</em>
1774             * @see GeoLocation#getLocalMeanTimeOffset()
1775             */
1776            public Date getFixedLocalChatzos() {
1777    //              System.out.println(getGeoLocation().getLocalMeanTimeOffset());
1778    //              System.out.println("raw offset: "
1779    //                              + getGeoLocation().getTimeZone().getRawOffset());
1780                    return getTimeOffset(getDateFromTime(12.0
1781                                    - getGeoLocation().getTimeZone().getRawOffset() / HOUR_MILLIS),
1782                                    -getGeoLocation().getLocalMeanTimeOffset());
1783            }
1784    
1785            /**
1786             * A method that returns the latest <em>zman krias shema</em> (time to say
1787             * Shema in the morning) calculated as 3 hours before
1788             * {@link #getFixedLocalChatzos()}.
1789             * 
1790             * @return the <code>Date</code> of the latest zman shema.
1791             * @see #getFixedLocalChatzos()
1792             * @see #getSofZmanTfilaFixedLocal()
1793             */
1794            public Date getSofZmanShmaFixedLocal() {
1795                    return getTimeOffset(getFixedLocalChatzos(), -180 * MINUTE_MILLIS);
1796            }
1797    
1798            /**
1799             * This method returns the latest <em>zman tfila</em> (time to say the
1800             * morning prayers) calculated as 2 hours before
1801             * {@link #getFixedLocalChatzos()}.
1802             * 
1803             * @return the <code>Date</code> of the latest zman tfila.
1804             * @see #getFixedLocalChatzos()
1805             * @see #getSofZmanShmaFixedLocal()
1806             */
1807            public Date getSofZmanTfilaFixedLocal() {
1808                    return getTimeOffset(getFixedLocalChatzos(), -120 * MINUTE_MILLIS);
1809            }
1810    
1811            /**
1812             * @see java.lang.Object#equals(Object)
1813             */
1814            public boolean equals(Object object) {
1815                    if (this == object) {
1816                            return true;
1817                    }
1818                    if (!(object instanceof ComplexZmanimCalendar)) {
1819                            return false;
1820                    }
1821                    ComplexZmanimCalendar cCal = (ComplexZmanimCalendar) object;
1822                    // return getCalendar().getTime().equals(cCal.getCalendar().getTime())
1823                    return getCalendar().equals(cCal.getCalendar())
1824                                    && getGeoLocation().equals(cCal.getGeoLocation())
1825                                    && getAstronomicalCalculator().equals(
1826                                                    cCal.getAstronomicalCalculator());
1827            }
1828    
1829            /**
1830             * @see java.lang.Object#hashCode()
1831             */
1832            public int hashCode() {
1833                    int result = 17;
1834                    // needed or this and subclasses will return identical hash
1835                    result = 37 * result + getClass().hashCode();
1836                    result += 37 * result + getCalendar().hashCode();
1837                    result += 37 * result + getGeoLocation().hashCode();
1838                    result += 37 * result + getAstronomicalCalculator().hashCode();
1839                    return result;
1840            }
1841    }