001/*
002 * Zmanim Java API
003 * Copyright (C) 2011 - 2018 Eliyahu Hershfeld
004 * Copyright (C) September 2002 Avrom Finkelstien
005 * Copyright (C) 2019 Y Paritcher
006 *
007 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
008 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
009 * any later version.
010 *
011 * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
012 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
013 * details.
014 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
015 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA,
016 * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
017 */
018package net.sourceforge.zmanim.hebrewcalendar;
019
020import net.sourceforge.zmanim.util.GeoLocation;
021
022import java.util.Calendar;
023import java.util.Date;
024import java.util.TimeZone;
025
026/**
027 * The JewishCalendar extends the JewishDate class and adds calendar methods.
028 * 
029 * This open source Java code was originally ported by <a href="http://www.facebook.com/avromf">Avrom Finkelstien</a>
030 * from his C++ code. It was refactored to fit the KosherJava Zmanim API with simplification of the code, enhancements
031 * and some bug fixing. The class allows setting whether the holiday and parsha scheme follows the Israel scheme or outside Israel
032 * scheme. The default is the outside Israel scheme.
033 * The parsha code was ported by Y Paritcher from his <a href="https://github.com/yparitcher/libzmanim">libzmanim</a> code.
034 * 
035 * @todo Some do not belong in this class, but here is a partial list of what should still be implemented in some form:
036 * <ol>
037 * <li>Add Isru Chag</li>
038 * <li>Mishna yomis etc</li>
039 * </ol>
040 * 
041 * @see java.util.Date
042 * @see java.util.Calendar
043 * @author &copy; Y Paritcher 2019
044 * @author &copy; Avrom Finkelstien 2002
045 * @author &copy; Eliyahu Hershfeld 2011 - 2018
046 */
047public class JewishCalendar extends JewishDate {
048        public static final int EREV_PESACH = 0;
049        public static final int PESACH = 1;
050        public static final int CHOL_HAMOED_PESACH = 2;
051        public static final int PESACH_SHENI = 3;
052        public static final int EREV_SHAVUOS = 4;
053        public static final int SHAVUOS = 5;
054        public static final int SEVENTEEN_OF_TAMMUZ = 6;
055        public static final int TISHA_BEAV = 7;
056        public static final int TU_BEAV = 8;
057        public static final int EREV_ROSH_HASHANA = 9;
058        public static final int ROSH_HASHANA = 10;
059        public static final int FAST_OF_GEDALYAH = 11;
060        public static final int EREV_YOM_KIPPUR = 12;
061        public static final int YOM_KIPPUR = 13;
062        public static final int EREV_SUCCOS = 14;
063        public static final int SUCCOS = 15;
064        public static final int CHOL_HAMOED_SUCCOS = 16;
065        public static final int HOSHANA_RABBA = 17;
066        public static final int SHEMINI_ATZERES = 18;
067        public static final int SIMCHAS_TORAH = 19;
068        // public static final int EREV_CHANUKAH = 20;// probably remove this
069        public static final int CHANUKAH = 21;
070        public static final int TENTH_OF_TEVES = 22;
071        public static final int TU_BESHVAT = 23;
072        public static final int FAST_OF_ESTHER = 24;
073        public static final int PURIM = 25;
074        public static final int SHUSHAN_PURIM = 26;
075        public static final int PURIM_KATAN = 27;
076        public static final int ROSH_CHODESH = 28;
077        public static final int YOM_HASHOAH = 29;
078        public static final int YOM_HAZIKARON = 30;
079        public static final int YOM_HAATZMAUT = 31;
080        public static final int YOM_YERUSHALAYIM = 32;
081
082        private boolean inIsrael = false;
083        private boolean useModernHolidays = false;
084
085        public static enum parshah {NONE, BERESHIS, NOACH, LECH_LECHA, VAYERA, CHAYEI_SARA, TOLDOS, VAYETZEI, VAYISHLACH, VAYESHEV, MIKETZ, VAYIGASH, VAYECHI, SHEMOS, VAERA, BO, BESHALACH, YISRO, MISHPATIM, TERUMAH, TETZAVEH, KI_SISA, VAYAKHEL, PEKUDEI, VAYIKRA, TZAV, SHMINI, TAZRIA, METZORA, ACHREI_MOS, KEDOSHIM, EMOR, BEHAR, BECHUKOSAI, BAMIDBAR, NASSO, BEHAALOSCHA, SHLACH, KORACH, CHUKAS, BALAK, PINCHAS, MATOS, MASEI, DEVARIM, VAESCHANAN, EIKEV, REEH, SHOFTIM, KI_SEITZEI, KI_SAVO, NITZAVIM, VAYEILECH, HAAZINU, VZOS_HABERACHA, VAYAKHEL_PEKUDEI, TAZRIA_METZORA, ACHREI_MOS_KEDOSHIM, BEHAR_BECHUKOSAI, CHUKAS_BALAK, MATOS_MASEI, NITZAVIM_VAYEILECH, SHKALIM, ZACHOR, PARA, HACHODESH};
086        public static final parshah[][] parshahlist = {
087                {parshah.NONE, parshah.VAYEILECH, parshah.HAAZINU, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL_PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR_BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
088                {parshah.NONE, parshah.VAYEILECH, parshah.HAAZINU, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL_PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR_BECHUKOSAI, parshah.BAMIDBAR, parshah.NONE, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS_BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
089                {parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL_PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR_BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM},
090                {parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR_BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM},
091                {parshah.NONE, parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL_PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR_BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM},
092                {parshah.NONE, parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL_PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR_BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
093                {parshah.NONE, parshah.VAYEILECH, parshah.HAAZINU, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.NONE, parshah.ACHREI_MOS, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NONE, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS_BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
094                {parshah.NONE, parshah.VAYEILECH, parshah.HAAZINU, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.NONE, parshah.NONE, parshah.ACHREI_MOS, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM},
095                {parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.ACHREI_MOS, parshah.NONE, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS, parshah.MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM},
096                {parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.ACHREI_MOS, parshah.NONE, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS, parshah.MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
097                {parshah.NONE, parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.NONE, parshah.ACHREI_MOS, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
098                {parshah.NONE, parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.NONE, parshah.ACHREI_MOS, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NONE, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS_BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
099                {parshah.NONE, parshah.VAYEILECH, parshah.HAAZINU, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL_PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR_BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
100                {parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL_PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.NONE, parshah.SHMINI, parshah.TAZRIA_METZORA, parshah.ACHREI_MOS_KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM},
101                {parshah.NONE, parshah.VAYEILECH, parshah.HAAZINU, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.NONE, parshah.ACHREI_MOS, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH},
102                {parshah.NONE, parshah.VAYEILECH, parshah.HAAZINU, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.NONE, parshah.ACHREI_MOS, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS, parshah.MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM},
103                {parshah.NONE, parshah.NONE, parshah.HAAZINU, parshah.NONE, parshah.NONE, parshah.BERESHIS, parshah.NOACH, parshah.LECH_LECHA, parshah.VAYERA, parshah.CHAYEI_SARA, parshah.TOLDOS, parshah.VAYETZEI, parshah.VAYISHLACH, parshah.VAYESHEV, parshah.MIKETZ, parshah.VAYIGASH, parshah.VAYECHI, parshah.SHEMOS, parshah.VAERA, parshah.BO, parshah.BESHALACH, parshah.YISRO, parshah.MISHPATIM, parshah.TERUMAH, parshah.TETZAVEH, parshah.KI_SISA, parshah.VAYAKHEL, parshah.PEKUDEI, parshah.VAYIKRA, parshah.TZAV, parshah.SHMINI, parshah.TAZRIA, parshah.METZORA, parshah.NONE, parshah.ACHREI_MOS, parshah.KEDOSHIM, parshah.EMOR, parshah.BEHAR, parshah.BECHUKOSAI, parshah.BAMIDBAR, parshah.NASSO, parshah.BEHAALOSCHA, parshah.SHLACH, parshah.KORACH, parshah.CHUKAS, parshah.BALAK, parshah.PINCHAS, parshah.MATOS_MASEI, parshah.DEVARIM, parshah.VAESCHANAN, parshah.EIKEV, parshah.REEH, parshah.SHOFTIM, parshah.KI_SEITZEI, parshah.KI_SAVO, parshah.NITZAVIM_VAYEILECH}};
104
105        /**
106         * Is this calendar set to return modern Israeli national holidays. By default this value is false. The holidays
107         * are: "Yom HaShoah", "Yom Hazikaron", "Yom Ha'atzmaut" and "Yom Yerushalayim"
108         * 
109         * @return the useModernHolidays true if set to return modern Israeli national holidays
110         */
111        public boolean isUseModernHolidays() {
112                return useModernHolidays;
113        }
114
115        /**
116         * Seth the calendar to return modern Israeli national holidays. By default this value is false. The holidays are:
117         * "Yom HaShoah", "Yom Hazikaron", "Yom Ha'atzmaut" and "Yom Yerushalayim"
118         * 
119         * @param useModernHolidays
120         *            the useModernHolidays to set
121         */
122        public void setUseModernHolidays(boolean useModernHolidays) {
123                this.useModernHolidays = useModernHolidays;
124        }
125
126        /**
127         * Default constructor will set a default date to the current system date.
128         */
129        public JewishCalendar() {
130                super();
131        }
132
133        /**
134         * A constructor that initializes the date to the {@link java.util.Date Date} parameter.
135         * 
136         * @param date
137         *            the <code>Date</code> to set the calendar to
138         */
139        public JewishCalendar(Date date) {
140                super(date);
141        }
142
143        /**
144         * A constructor that initializes the date to the {@link java.util.Calendar Calendar} parameter.
145         * 
146         * @param calendar
147         *            the <code>Calendar</code> to set the calendar to
148         */
149        public JewishCalendar(Calendar calendar) {
150                super(calendar);
151        }
152
153        /**
154         * Creates a Jewish date based on a Jewish year, month and day of month.
155         * 
156         * @param jewishYear
157         *            the Jewish year
158         * @param jewishMonth
159         *            the Jewish month. The method expects a 1 for Nissan ... 12 for Adar and 13 for Adar II. Use the
160         *            constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar II) to avoid any
161         *            confusion.
162         * @param jewishDayOfMonth
163         *            the Jewish day of month. If 30 is passed in for a month with only 29 days (for example {@link #IYAR},
164         *            or {@link #KISLEV} in a year that {@link #isKislevShort()}), the 29th (last valid date of the month)
165         *            will be set
166         * @throws IllegalArgumentException
167         *             if the day of month is &lt; 1 or &gt; 30, or a year of &lt; 0 is passed in.
168         */
169        public JewishCalendar(int jewishYear, int jewishMonth, int jewishDayOfMonth) {
170                super(jewishYear, jewishMonth, jewishDayOfMonth);
171        }
172
173        /**
174         * Creates a Jewish date based on a Jewish date and whether in Israel
175         * 
176         * @param jewishYear
177         *            the Jewish year
178         * @param jewishMonth
179         *            the Jewish month. The method expects a 1 for Nissan ... 12 for Adar and 13 for Adar II. Use the
180         *            constants {@link #NISSAN} ... {@link #ADAR} (or {@link #ADAR_II} for a leap year Adar II) to avoid any
181         *            confusion.
182         * @param jewishDayOfMonth
183         *            the Jewish day of month. If 30 is passed in for a month with only 29 days (for example {@link #IYAR},
184         *            or {@link #KISLEV} in a year that {@link #isKislevShort()}), the 29th (last valid date of the month)
185         *            will be set
186         * @param inIsrael
187         *            whether in Israel. This affects Yom Tov calculations
188         */
189        public JewishCalendar(int jewishYear, int jewishMonth, int jewishDayOfMonth, boolean inIsrael) {
190                super(jewishYear, jewishMonth, jewishDayOfMonth);
191                setInIsrael(inIsrael);
192        }
193
194        /**
195         * Sets whether to use Israel holiday scheme or not. Default is false.
196         * 
197         * @param inIsrael
198         *            set to true for calculations for Israel
199         */
200        public void setInIsrael(boolean inIsrael) {
201                this.inIsrael = inIsrael;
202        }
203
204        /**
205         * Gets whether Israel holiday scheme is used or not. The default (if not set) is false.
206         * 
207         * @return if the if the calendar is set to Israel
208         */
209        public boolean getInIsrael() {
210                return inIsrael;
211        }
212
213        /**
214         * Return the type of year for parshah calculations.
215         * @return the type of year for parshah calculations.
216         * @todo Use constants in this class.
217         */
218        private int getYearType()
219        {
220                int yearWday = (getJewishCalendarElapsedDays(getJewishYear())+1)%7;
221                if (isJewishLeapYear())
222                {
223                        switch (yearWday)
224                        {
225                        case 2:
226                                if (isKislevShort())
227                                {
228                                        if (getInIsrael()) { return 14;}
229                                        return 6;
230                                }
231                                if (isCheshvanLong())
232                                {
233                                        if (getInIsrael()) { return 15;}
234                                        return 7;
235                                }
236                                break;
237                        case 3:
238                                if (getInIsrael()) { return 15;}
239                                return 7;
240                        case 5:
241                                if (isKislevShort()) {return 8;}
242                                if (isCheshvanLong()) {return 9;}
243                                break;
244                        case 0:
245                                if (isKislevShort()) {return 10;}
246                                if (isCheshvanLong())
247                                {
248                                        if (getInIsrael()) { return 16;}
249                                        return 11;
250                                }
251                                break;
252                        }
253                } else {
254                        switch (yearWday)
255                        {
256                        case 2:
257                                if (isKislevShort()) {return 0;}
258                                if (isCheshvanLong())
259                                {
260                                        if (getInIsrael()) { return 12;}
261                                        return 1;
262                                }
263                                break;
264                        case 3:
265                                if (getInIsrael()) { return 12;}
266                                return 1;
267                        case 5:
268                                if (isCheshvanLong()) {return 3;}
269                                if (!isKislevShort())
270                                {
271                                        if (getInIsrael()) { return 13;}
272                                        return 2;
273                                }
274                                break;
275                        case 0:
276                                if (isKislevShort()) {return 4;}
277                                if (isCheshvanLong()) {return 5;}
278                                break;
279                        }
280                }
281                return -1;
282        }
283
284        /**
285         * returns a parshah enum with the weeks parshah if it is Shabbos.
286         * returns NONE if a weekday or if there is no parshah that week (for example Yomtov is on Shabbos)
287         * @return the current parshah
288        */
289        public parshah getParshahIndex()
290        {
291                int yearType = getYearType();
292                int yearWday = getJewishCalendarElapsedDays(getJewishYear())%7;
293                int day = yearWday + getDaysSinceStartOfJewishYear();
294                if (getDayOfWeek() != 7) {return parshah.NONE;}
295                if (yearType >= 0)
296                {
297                        return parshahlist[yearType][day/7];
298                }
299                return parshah.NONE;
300        }
301
302        /**
303         * returns a parshah enum if the week is one of the four parshahs if it is Shabbos.
304         * returns NONE if a weekday
305         * @return one of the four parshahs
306        */
307        public parshah getSpecialShabbos() {
308                if(getDayOfWeek() != 7)
309                {
310                        if((getJewishMonth() == 11 && !isJewishLeapYear()) || (getJewishMonth() == 12 && isJewishLeapYear()))
311                        {
312                                if(getJewishDayOfMonth() == 25
313                                || getJewishDayOfMonth() == 27
314                                || getJewishDayOfMonth() == 29)
315                                {return parshah.SHKALIM;}
316                        }
317                        if((getJewishMonth() == 12 && !isJewishLeapYear()) || getJewishMonth() == 13)
318                        {
319                                if(getJewishDayOfMonth() == 1) {return parshah.SHKALIM;}
320                                if(getJewishDayOfMonth() == 8
321                                || getJewishDayOfMonth() == 9
322                                || getJewishDayOfMonth() == 11
323                                || getJewishDayOfMonth() == 13)
324                                {return parshah.ZACHOR;}
325                                if(getJewishDayOfMonth() == 18
326                                || getJewishDayOfMonth() == 20
327                                || getJewishDayOfMonth() == 22
328                                || getJewishDayOfMonth() == 23)
329                                {return parshah.PARA;}
330                                if(getJewishDayOfMonth() == 25
331                                || getJewishDayOfMonth() == 27
332                                || getJewishDayOfMonth() == 29)
333                                {return parshah.HACHODESH;}
334                        }
335                        if(getJewishMonth() == 1 && getJewishDayOfMonth() == 1) {return parshah.HACHODESH;}
336                }
337                return parshah.NONE;
338        }
339
340        /**
341         * Returns an index of the Jewish holiday or fast day for the current day, or a null if there is no holiday for this
342         * day.
343         * 
344         * @return A String containing the holiday name or an empty string if it is not a holiday.
345         */
346        public int getYomTovIndex() {
347                final int day = getJewishDayOfMonth();
348                final int dayOfWeek = getDayOfWeek();
349
350                // check by month (starts from Nissan)
351                switch (getJewishMonth()) {
352                case NISSAN:
353                        if (day == 14) {
354                                return EREV_PESACH;
355                        }
356                        if (day == 15 || day == 21
357                                        || (!inIsrael && (day == 16 || day == 22))) {
358                                return PESACH;
359                        }
360                        if (day >= 17 && day <= 20
361                                        || (day == 16 && inIsrael)) {
362                                return CHOL_HAMOED_PESACH;
363                        }
364                        if (isUseModernHolidays()
365                                        && ((day == 26 && dayOfWeek == 5)
366                                                        || (day == 28 && dayOfWeek == 2)
367                                                        || (day == 27 && dayOfWeek != 1 && dayOfWeek != 6))) {
368                                return YOM_HASHOAH;
369                        }
370                        break;
371                case IYAR:
372                        if (isUseModernHolidays()
373                                        && ((day == 4 && dayOfWeek == 3)
374                                                        || ((day == 3 || day == 2) && dayOfWeek == 4) || (day == 5 && dayOfWeek == 2))) {
375                                return YOM_HAZIKARON;
376                        }
377                        // if 5 Iyar falls on Wed Yom Haatzmaut is that day. If it fal1s on Friday or Shabbos it is moved back to
378                        // Thursday. If it falls on Monday it is moved to Tuesday
379                        if (isUseModernHolidays()
380                                        && ((day == 5 && dayOfWeek == 4)
381                                                        || ((day == 4 || day == 3) && dayOfWeek == 5) || (day == 6 && dayOfWeek == 3))) {
382                                return YOM_HAATZMAUT;
383                        }
384                        if (day == 14) {
385                                return PESACH_SHENI;
386                        }
387                        if (isUseModernHolidays() && day == 28) {
388                                return YOM_YERUSHALAYIM;
389                        }
390                        break;
391                case SIVAN:
392                        if (day == 5) {
393                                return EREV_SHAVUOS;
394                        }
395                        if (day == 6 || (day == 7 && !inIsrael)) {
396                                return SHAVUOS;
397                        }
398                        break;
399                case TAMMUZ:
400                        // push off the fast day if it falls on Shabbos
401                        if ((day == 17 && dayOfWeek != 7)
402                                        || (day == 18 && dayOfWeek == 1)) {
403                                return SEVENTEEN_OF_TAMMUZ;
404                        }
405                        break;
406                case AV:
407                        // if Tisha B'av falls on Shabbos, push off until Sunday
408                        if ((dayOfWeek == 1 && day == 10)
409                                        || (dayOfWeek != 7 && day == 9)) {
410                                return TISHA_BEAV;
411                        }
412                        if (day == 15) {
413                                return TU_BEAV;
414                        }
415                        break;
416                case ELUL:
417                        if (day == 29) {
418                                return EREV_ROSH_HASHANA;
419                        }
420                        break;
421                case TISHREI:
422                        if (day == 1 || day == 2) {
423                                return ROSH_HASHANA;
424                        }
425                        if ((day == 3 && dayOfWeek != 7)
426                                        || (day == 4 && dayOfWeek == 1)) {
427                                // push off Tzom Gedalia if it falls on Shabbos
428                                return FAST_OF_GEDALYAH;
429                        }
430                        if (day == 9) {
431                                return EREV_YOM_KIPPUR;
432                        }
433                        if (day == 10) {
434                                return YOM_KIPPUR;
435                        }
436                        if (day == 14) {
437                                return EREV_SUCCOS;
438                        }
439                        if (day == 15 || (day == 16 && !inIsrael)) {
440                                return SUCCOS;
441                        }
442                        if (day >= 17 && day <= 20 || (day == 16 && inIsrael)) {
443                                return CHOL_HAMOED_SUCCOS;
444                        }
445                        if (day == 21) {
446                                return HOSHANA_RABBA;
447                        }
448                        if (day == 22) {
449                                return SHEMINI_ATZERES;
450                        }
451                        if (day == 23 && !inIsrael) {
452                                return SIMCHAS_TORAH;
453                        }
454                        break;
455                case KISLEV: // no yomtov in CHESHVAN
456                        // if (day == 24) {
457                        // return EREV_CHANUKAH;
458                        // } else
459                        if (day >= 25) {
460                                return CHANUKAH;
461                        }
462                        break;
463                case TEVES:
464                        if (day == 1 || day == 2
465                                        || (day == 3 && isKislevShort())) {
466                                return CHANUKAH;
467                        }
468                        if (day == 10) {
469                                return TENTH_OF_TEVES;
470                        }
471                        break;
472                case SHEVAT:
473                        if (day == 15) {
474                                return TU_BESHVAT;
475                        }
476                        break;
477                case ADAR:
478                        if (!isJewishLeapYear()) {
479                                // if 13th Adar falls on Friday or Shabbos, push back to Thursday
480                                if (((day == 11 || day == 12) && dayOfWeek == 5)
481                                                || (day == 13 && !(dayOfWeek == 6 || dayOfWeek == 7))) {
482                                        return FAST_OF_ESTHER;
483                                }
484                                if (day == 14) {
485                                        return PURIM;
486                                }
487                                if (day == 15) {
488                                        return SHUSHAN_PURIM;
489                                }
490                        } else { // else if a leap year
491                                if (day == 14) {
492                                        return PURIM_KATAN;
493                                }
494                        }
495                        break;
496                case ADAR_II:
497                        // if 13th Adar falls on Friday or Shabbos, push back to Thursday
498                        if (((day == 11 || day == 12) && dayOfWeek == 5)
499                                        || (day == 13 && !(dayOfWeek == 6 || dayOfWeek == 7))) {
500                                return FAST_OF_ESTHER;
501                        }
502                        if (day == 14) {
503                                return PURIM;
504                        }
505                        if (day == 15) {
506                                return SHUSHAN_PURIM;
507                        }
508                        break;
509                }
510                // if we get to this stage, then there are no holidays for the given date return -1
511                return -1;
512        }
513
514        /**
515         * Returns true if the current day is Yom Tov. The method returns false for Chanukah, Erev Yom Tov (with the
516         * exception of Hoshana Rabba and Erev the second days of Pesach) and fast days.
517         * 
518         * @return true if the current day is a Yom Tov
519         * @see #isErevYomTov()
520         * @see #isErevYomTovSheni()
521         * @see #isTaanis()
522         */
523        public boolean isYomTov() {
524                int holidayIndex = getYomTovIndex();
525                if ((isErevYomTov() && (holidayIndex != HOSHANA_RABBA && (holidayIndex == CHOL_HAMOED_PESACH && getJewishDayOfMonth() != 20)))
526                                || holidayIndex == CHANUKAH || (isTaanis() && holidayIndex != YOM_KIPPUR)) {
527                        return false;
528                }
529                return getYomTovIndex() != -1;
530        }
531
532        /**
533         * Returns true if the <em>Yom Tov</em> day has a <em>melacha</em> (work)  prohibition. This method will return false for a
534         * non-<em>Yom Tov</em> day, even if it is <em>Shabbos</em>.
535         *
536         * @return if the <em>Yom Tov</em> day has a <em>melacha</em> (work)  prohibition.
537         */
538        public boolean isYomTovAssurBemelacha() {
539                int holidayIndex = getYomTovIndex();
540                return holidayIndex == PESACH || holidayIndex == SHAVUOS || holidayIndex == SUCCOS || holidayIndex == SHEMINI_ATZERES ||
541                                holidayIndex == SIMCHAS_TORAH || holidayIndex == ROSH_HASHANA  || holidayIndex == YOM_KIPPUR;
542        }
543        
544        /**
545         * Returns true if it is <em>Shabbos</em> or if it is a <em>Yom Tov</em> day that has a <em>melacha</em> (work)  prohibition.
546         * This method will return false for a.
547         * @return if the day is a <em>Yom Tov</em> that is <em>assur bemlacha</em> or <em>Shabbos</em>
548         */
549        public boolean isAssurBemelacha() {
550                return getDayOfWeek() == 7 || isYomTovAssurBemelacha();
551        }
552        
553        /**
554         * Returns true if the day has candle lighting. This will return true on erev <em>Shabbos</em>, erev <em>Yom Tov</em>, the
555         * first day of <em>Rosh Hashana</em> and the first days of <em>Yom Tov</em> out of Israel. It is identical
556         * to calling {@link isTomorrowShabbosOrYomTov()}.
557         * 
558         * @return if the day has candle lighting
559         */
560        public boolean hasCandleLighting() {
561                return isTomorrowShabbosOrYomTov();
562        }
563        
564        /**
565         * Returns true if tomorrow is <em>Shabbos</em> or <em>Yom Tov</em>. This will return true on erev <em>Shabbos</em>, erev
566         * <em>Yom Tov</em>, the first day of <em>Rosh Hashana</em> and <em>erev</em> the first days of <em>Yom Tov</em> out of
567         * Israel. It is identical to calling {@link hasCandleLighting()}.
568         * @return will return if the next day is <em>Shabbos</em> or <em>Yom Tov</em>
569         */
570        public boolean isTomorrowShabbosOrYomTov() {
571                return getDayOfWeek() == 6 || isErevYomTov() || isErevYomTovSheni();
572        }
573        
574        /**
575         * Returns true if the day is the second day of <em>Yom Tov</em>. This impacts the second day of <em>Rosh Hashana</em> everywhere and
576         * the second days of Yom Tov in <em>chutz laaretz</em> (out of Israel).
577         * 
578         * @return  if the day is the second day of <em>Yom Tov</em>.
579         */
580        public boolean isErevYomTovSheni() {
581                return (getJewishMonth() == JewishCalendar.TISHREI && (getJewishDayOfMonth() == 1))
582                || (! getInIsrael()
583                                && ((getJewishMonth() == JewishCalendar.NISSAN && (getJewishDayOfMonth() == 15 || getJewishDayOfMonth() == 21))
584                                || (getJewishMonth() == JewishCalendar.TISHREI && (getJewishDayOfMonth() == 15 || getJewishDayOfMonth() == 22))
585                                || (getJewishMonth() == JewishCalendar.SIVAN && getJewishDayOfMonth() == 6 )));
586        }
587
588        /**
589         * Returns true if the current day is <em>Aseret Yemei Teshuva</em>.
590         * 
591         * @return if the current day is <em>Aseret Yemei Teshuvah</em>
592         */
593        public boolean isAseresYemeiTeshuva(){
594                return getJewishMonth() == JewishCalendar.TISHREI && getJewishDayOfMonth() <= 10;
595        }
596
597        /**
598         * Returns true if the current day is <em>Chol Hamoed</em> of <em>Pesach</em> or <em>Succos</em>.
599         * 
600         * @return true if the current day is <em>Chol Hamoed</em> of <em>Pesach</em> or <em>Succos</em>
601         * @see #isYomTov()
602         * @see #CHOL_HAMOED_PESACH
603         * @see #CHOL_HAMOED_SUCCOS
604         */
605        public boolean isCholHamoed() {
606                return isCholHamoedPesach() || isCholHamoedSuccos();
607        }
608
609        /**
610         * Returns true if the current day is <em>Chol Hamoed</em> of <em>Pesach</em>.
611         *
612         * @return true if the current day is <em>Chol Hamoed</em> of <em>Pesach</em>
613         * @see #isYomTov()
614         * @see #CHOL_HAMOED_PESACH
615         */
616        public boolean isCholHamoedPesach() {
617                int holidayIndex = getYomTovIndex();
618                return holidayIndex == JewishCalendar.CHOL_HAMOED_PESACH;
619        }
620
621        /**
622         * Returns true if the current day is <em>Chol Hamoed</em> of <em>Succos</em>.
623         *
624         * @return true if the current day is <em>Chol Hamoed</em> of <em>Succos</em>
625         * @see #isYomTov()
626         * @see #CHOL_HAMOED_SUCCOS
627         */
628        public boolean isCholHamoedSuccos() {
629                int holidayIndex = getYomTovIndex();
630                return holidayIndex == JewishCalendar.CHOL_HAMOED_SUCCOS;
631        }
632
633        /**
634         * Returns true if the current day is erev Yom Tov. The method returns true for Erev - Pesach (first and last days),
635         * Shavuos, Rosh Hashana, Yom Kippur and Succos and Hoshana Rabba.
636         * 
637         * @return true if the current day is Erev - Pesach, Shavuos, Rosh Hashana, Yom Kippur and Succos
638         * @see #isYomTov()
639         * @see #isErevYomTovSheni()
640         */
641        public boolean isErevYomTov() {
642                int holidayIndex = getYomTovIndex();
643                return holidayIndex == EREV_PESACH || holidayIndex == EREV_SHAVUOS || holidayIndex == EREV_ROSH_HASHANA
644                                || holidayIndex == EREV_YOM_KIPPUR || holidayIndex == EREV_SUCCOS || holidayIndex == HOSHANA_RABBA
645                                || (holidayIndex == CHOL_HAMOED_PESACH && getJewishDayOfMonth() == 20);
646        }
647
648        /**
649         * Returns true if the current day is Erev Rosh Chodesh. Returns false for Erev Rosh Hashana
650         * 
651         * @return true if the current day is Erev Rosh Chodesh. Returns false for Erev Rosh Hashana
652         * @see #isRoshChodesh()
653         */
654        public boolean isErevRoshChodesh() {
655                // Erev Rosh Hashana is not Erev Rosh Chodesh.
656                return (getJewishDayOfMonth() == 29 && getJewishMonth() != ELUL);
657        }
658
659        /**
660         * Return true if the day is a Taanis (fast day). Return true for 17 of Tammuz, Tisha B'Av, Yom Kippur, Fast of
661         * Gedalyah, 10 of Teves and the Fast of Esther
662         * 
663         * @return true if today is a fast day
664         */
665        public boolean isTaanis() {
666                int holidayIndex = getYomTovIndex();
667                return holidayIndex == SEVENTEEN_OF_TAMMUZ || holidayIndex == TISHA_BEAV || holidayIndex == YOM_KIPPUR
668                                || holidayIndex == FAST_OF_GEDALYAH || holidayIndex == TENTH_OF_TEVES || holidayIndex == FAST_OF_ESTHER;
669        }
670
671        /**
672         * Returns the day of Chanukah or -1 if it is not Chanukah.
673         * 
674         * @return the day of Chanukah or -1 if it is not Chanukah.
675         */
676        public int getDayOfChanukah() {
677                final int day = getJewishDayOfMonth();
678                if (isChanukah()) {
679                        if (getJewishMonth() == KISLEV) {
680                                return day - 24;
681                        } else { // teves
682                                return isKislevShort() ? day + 5 : day + 6;
683                        }
684                } else {
685                        return -1;
686                }
687        }
688
689        public boolean isChanukah() {
690                return getYomTovIndex() == CHANUKAH;
691        }
692
693        /**
694         * Returns if the day is Rosh Chodesh. Rosh Hashana will return false
695         * 
696         * @return true if it is Rosh Chodesh. Rosh Hashana will return false
697         */
698        public boolean isRoshChodesh() {
699                // Rosh Hashana is not rosh chodesh. Elul never has 30 days
700                return (getJewishDayOfMonth() == 1 && getJewishMonth() != TISHREI) || getJewishDayOfMonth() == 30;
701        }
702
703        /**
704         * Returns if the day is Shabbos and sunday is Rosh Chodesh.
705         *
706         * @return true if it is Shabbos and sunday is Rosh Chodesh.
707         */
708        public boolean isMacharChodesh() {
709                return (getDayOfWeek() == 7 && (getJewishDayOfMonth() == 30 || getJewishDayOfMonth() == 29));
710        }
711
712        /**
713         * Returns if the day is Shabbos Mevorchim.
714         *
715         * @return true if it is Shabbos Mevorchim.
716         */
717        public boolean isShabbosMevorchim() {
718                return (getDayOfWeek() == 7 && getJewishDayOfMonth() >= 23 && getJewishDayOfMonth() <= 29);
719        }
720
721        /**
722         * Returns the int value of the Omer day or -1 if the day is not in the omer
723         * 
724         * @return The Omer count as an int or -1 if it is not a day of the Omer.
725         */
726        public int getDayOfOmer() {
727                int omer = -1; // not a day of the Omer
728                int month = getJewishMonth();
729                int day = getJewishDayOfMonth();
730
731                // if Nissan and second day of Pesach and on
732                if (month == NISSAN && day >= 16) {
733                        omer = day - 15;
734                        // if Iyar
735                } else if (month == IYAR) {
736                        omer = day + 15;
737                        // if Sivan and before Shavuos
738                } else if (month == SIVAN && day < 6) {
739                        omer = day + 44;
740                }
741                return omer;
742        }
743
744        /**
745         * Returns the molad in Standard Time in Yerushalayim as a Date. The traditional calculation uses local time. This
746         * method subtracts 20.94 minutes (20 minutes and 56.496 seconds) from the local time (Har Habayis with a longitude
747         * of 35.2354&deg; is 5.2354&deg; away from the %15 timezone longitude) to get to standard time. This method
748         * intentionally uses standard time and not dailight savings time. Java will implicitly format the time to the
749         * default (or set) Timezone.
750         * 
751         * @return the Date representing the moment of the molad in Yerushalayim standard time (GMT + 2)
752         */
753        public Date getMoladAsDate() {
754                JewishDate molad = getMolad();
755                String locationName = "Jerusalem, Israel";
756
757                double latitude = 31.778; // Har Habayis latitude
758                double longitude = 35.2354; // Har Habayis longitude
759
760                // The molad calculation always expects output in standard time. Using "Asia/Jerusalem" timezone will incorrect
761                // adjust for DST.
762                TimeZone yerushalayimStandardTZ = TimeZone.getTimeZone("GMT+2");
763                GeoLocation geo = new GeoLocation(locationName, latitude, longitude, yerushalayimStandardTZ);
764                Calendar cal = Calendar.getInstance(geo.getTimeZone());
765                cal.clear();
766                double moladSeconds = molad.getMoladChalakim() * 10 / (double) 3;
767                cal.set(molad.getGregorianYear(), molad.getGregorianMonth(), molad.getGregorianDayOfMonth(),
768                                molad.getMoladHours(), molad.getMoladMinutes(), (int) moladSeconds);
769                cal.set(Calendar.MILLISECOND, (int) (1000 * (moladSeconds - (int) moladSeconds)));
770                // subtract local time difference of 20.94 minutes (20 minutes and 56.496 seconds) to get to Standard time
771                cal.add(Calendar.MILLISECOND, -1 * (int) geo.getLocalMeanTimeOffset());
772                return cal.getTime();
773        }
774
775        /**
776         * Returns the earliest time of <em>Kiddush Levana</em> calculated as 3 days after the molad. This method returns the time
777         * even if it is during the day when <em>Kiddush Levana</em> can't be said. Callers of this method should consider
778         * displaying the next <em>tzais</em> if the zman is between <em>alos</em> and <em>tzais</em>.
779         * 
780         * @return the Date representing the moment 3 days after the molad.
781         * 
782         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getTchilasZmanKidushLevana3Days()
783         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getTchilasZmanKidushLevana3Days(Date, Date)
784         */
785        public Date getTchilasZmanKidushLevana3Days() {
786                Date molad = getMoladAsDate();
787                Calendar cal = Calendar.getInstance();
788                cal.setTime(molad);
789                cal.add(Calendar.HOUR, 72); // 3 days after the molad
790                return cal.getTime();
791        }
792
793        /**
794         * Returns the earliest time of Kiddush Levana calculated as 7 days after the molad as mentioned by the <a
795         * href="http://en.wikipedia.org/wiki/Yosef_Karo">Mechaber</a>. See the <a
796         * href="http://en.wikipedia.org/wiki/Yoel_Sirkis">Bach's</a> opinion on this time. This method returns the time
797         * even if it is during the day when <em>Kiddush Levana</em> can't be said. Callers of this method should consider
798         * displaying the next <em>tzais</em> if the zman is between <em>alos</em> and <em>tzais</em>.
799         * 
800         * @return the Date representing the moment 7 days after the molad.
801         * 
802         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getTchilasZmanKidushLevana7Days()
803         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getTchilasZmanKidushLevana7Days(Date, Date)
804         */
805        public Date getTchilasZmanKidushLevana7Days() {
806                Date molad = getMoladAsDate();
807                Calendar cal = Calendar.getInstance();
808                cal.setTime(molad);
809                cal.add(Calendar.HOUR, 168); // 7 days after the molad
810                return cal.getTime();
811        }
812
813        /**
814         * Returns the latest time of Kiddush Levana according to the <a
815         * href="http://en.wikipedia.org/wiki/Yaakov_ben_Moshe_Levi_Moelin">Maharil's</a> opinion that it is calculated as
816         * halfway between molad and molad. This adds half the 29 days, 12 hours and 793 chalakim time between molad and
817         * molad (14 days, 18 hours, 22 minutes and 666 milliseconds) to the month's molad. This method returns the time
818         * even if it is during the day when <em>Kiddush Levana</em> can't be said. Callers of this method should consider
819         * displaying <em>alos</em> before this time if the zman is between <em>alos</em> and <em>tzais</em>.
820         * 
821         * @return the Date representing the moment halfway between molad and molad.
822         * @see #getSofZmanKidushLevana15Days()
823         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getSofZmanKidushLevanaBetweenMoldos()
824         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getSofZmanKidushLevanaBetweenMoldos(Date, Date)
825         */
826        public Date getSofZmanKidushLevanaBetweenMoldos() {
827                Date molad = getMoladAsDate();
828                Calendar cal = Calendar.getInstance();
829                cal.setTime(molad);
830                // add half the time between molad and molad (half of 29 days, 12 hours and 793 chalakim (44 minutes, 3.3
831                // seconds), or 14 days, 18 hours, 22 minutes and 666 milliseconds)
832                cal.add(Calendar.DAY_OF_MONTH, 14);
833                cal.add(Calendar.HOUR_OF_DAY, 18);
834                cal.add(Calendar.MINUTE, 22);
835                cal.add(Calendar.SECOND, 1);
836                cal.add(Calendar.MILLISECOND, 666);
837                return cal.getTime();
838        }
839
840        /**
841         * Returns the latest time of Kiddush Levana calculated as 15 days after the molad. This is the opinion brought down
842         * in the Shulchan Aruch (Orach Chaim 426). It should be noted that some opinions hold that the
843         * <a href="http://en.wikipedia.org/wiki/Moses_Isserles">Rema</a> who brings down the opinion of the <a
844         * href="http://en.wikipedia.org/wiki/Yaakov_ben_Moshe_Levi_Moelin">Maharil's</a> of calculating
845         * {@link #getSofZmanKidushLevanaBetweenMoldos() half way between molad and mold} is of the opinion that Mechaber
846         * agrees to his opinion. Also see the Aruch Hashulchan. For additional details on the subject, See Rabbi Dovid
847         * Heber's very detailed writeup in Siman Daled (chapter 4) of <a
848         * href="http://www.worldcat.org/oclc/461326125">Shaarei Zmanim</a>. This method returns the time even if it is during
849         * the day when <em>Kiddush Levana</em> can't be said. Callers of this method should consider displaying <em>alos</em>
850         * before this time if the zman is between <em>alos</em> and <em>tzais</em>.
851         * 
852         * @return the Date representing the moment 15 days after the molad.
853         * @see #getSofZmanKidushLevanaBetweenMoldos()
854         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getSofZmanKidushLevana15Days()
855         * @see net.sourceforge.zmanim.ComplexZmanimCalendar#getSofZmanKidushLevana15Days(Date, Date)
856         */
857        public Date getSofZmanKidushLevana15Days() {
858                Date molad = getMoladAsDate();
859                Calendar cal = Calendar.getInstance();
860                cal.setTime(molad);
861                cal.add(Calendar.DAY_OF_YEAR, 15); // 15 days after the molad
862                return cal.getTime();
863        }
864
865        /**
866         * Returns the Daf Yomi (Bavli) for the date that the calendar is set to. See the
867         * {@link HebrewDateFormatter#formatDafYomiBavli(Daf)} for the ability to format the daf in Hebrew or transliterated
868         * masechta names.
869         * 
870         * @return the daf as a {@link Daf}
871         */
872        public Daf getDafYomiBavli() {
873                return YomiCalculator.getDafYomiBavli(this);
874        }
875        /**
876         * Returns the Daf Yomi (Yerushalmi) for the date that the calendar is set to. See the
877         * {@link HebrewDateFormatter#formatDafYomiYerushalmi(Daf)} for the ability to format the daf in Hebrew or transliterated
878         * masechta names.
879         *
880         * @return the daf as a {@link Daf}
881         */
882        public Daf getDafYomiYerushalmi() {
883                return YerushalmiYomiCalculator.getDafYomiYerushalmi(this);
884        }
885
886
887        /**
888         * @see Object#equals(Object)
889         */
890        public boolean equals(Object object) {
891                if (this == object) {
892                        return true;
893                }
894                if (!(object instanceof JewishCalendar)) {
895                        return false;
896                }
897                JewishCalendar jewishCalendar = (JewishCalendar) object;
898                return getAbsDate() == jewishCalendar.getAbsDate() && getInIsrael() == jewishCalendar.getInIsrael();
899        }
900
901        /**
902         * @see Object#hashCode()
903         */
904        public int hashCode() {
905                int result = 17;
906                result = 37 * result + getClass().hashCode(); // needed or this and subclasses will return identical hash
907                result += 37 * result + getAbsDate() + (getInIsrael() ? 1 : 3);
908                return result;
909        }
910}