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