001/* 002 * Zmanim Java API 003 * Copyright (C) 2011 - 2026 Eliyahu Hershfeld 004 * 005 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 006 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied 010 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 011 * details. 012 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 013 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA, 014 * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 015 */ 016package com.kosherjava.zmanim.hebrewcalendar; 017 018import java.time.format.DateTimeFormatter; 019import java.util.EnumMap; 020 021/** 022 * The HebrewDateFormatter class formats a {@link JewishDate}. 023 * 024 * The class formats Jewish dates, numbers, <em>Daf Yomi</em> (<em>Bavli</em> and <em>Yerushalmi</em>), the <em>Omer</em>, 025 * <em>Parshas Hashavua</em> (including the special <em>parshiyos</em> of <em>Shekalim</em>, <em>Zachor</em>, <em>Parah</em> 026 * and <em>Hachodesh</em>), <em>Yomim Tovim</em> in Hebrew or Latin chars, and has various settings. Sample full date output 027 * includes (using various options): 028 * <ul> 029 * <li>21 Shevat, 5729</li> 030 * <li>כא שבט תשכט</li> 031 * <li>כ״א שבט ה׳תשכ״ט</li> 032 * <li>כ״א שבט תש״פ or 033 * כ״א שבט תש״ף</li> 034 * <li>כ׳ שבט ו׳ אלפים</li> 035 * </ul> 036 * 037 * @see JewishDate 038 * @see JewishCalendar 039 * 040 * @author © Eliyahu Hershfeld 2011 - 2026 041 */ 042public class HebrewDateFormatter { 043 044 /** 045 * See {@link #isHebrewFormat()} and {@link #setHebrewFormat(boolean)}. 046 */ 047 private boolean hebrewFormat = false; 048 049 /** 050 * See {@link #isUseLongHebrewYears()} and {@link #setUseLongHebrewYears(boolean)}. 051 */ 052 private boolean useLonghebrewYears = false; 053 054 /** 055 * See {@link #isUseGershGershayim()} and {@link #setUseGershGershayim(boolean)}. 056 */ 057 private boolean useGershGershayim = true; 058 059 /** 060 * See {@link #isLongWeekFormat()} and {@link #setLongWeekFormat(boolean)}. 061 */ 062 private boolean longWeekFormat = true; 063 064 /** 065 * See {@link #isUseFinalFormLetters()} and {@link #setUseFinalFormLetters(boolean)}. 066 */ 067 private boolean useFinalFormLetters = false; 068 069 /** 070 * The internal DateFormat. See {@link #isLongWeekFormat()} and {@link #setLongWeekFormat(boolean)}. 071 */ 072 private DateTimeFormatter weekFormat; 073 074 /** 075 * List of transliterated parshiyos using the default <em>Ashkenazi</em> pronunciation. For information on the format, see 076 * {@link #getTransliteratedParshiosList()}. 077 * 078 * @see #getTransliteratedParshiosList() 079 * @see #setTransliteratedParshiosList(EnumMap) 080 * @see #HebrewDateFormatter() where the map is initially set. 081 */ 082 private EnumMap<JewishCalendar.Parsha, String> transliteratedParshaMap; 083 084 /** 085 * An {@link EnumMap} of Hebrew <em>parshiyos</em>. The list includes double and special <em>parshiyos</em> and 086 * contains <code>‏בראשית, נח, לך לך, 087 * וירא, חיי שרה, 088 * תולדות, ויצא, וישלח, 089 * וישב, מקץ, ויגש, ויחי, 090 * שמות, וארא, בא, בשלח, 091 * יתרו, משפטים, תרומה, 092 * תצוה, כי תשא, ויקהל, 093 * פקודי, ויקרא, צו, 094 * שמיני, תזריע, מצרע, 095 * אחרי מות, קדושים, 096 * אמור, בהר, בחקתי, 097 * במדבר, נשא, בהעלתך, 098 * שלח לך, קרח, חוקת, בלק, 099 * פינחס, מטות, מסעי, 100 * דברים, ואתחנן, עקב, 101 * ראה, שופטים, כי תצא, 102 * כי תבוא, נצבים, וילך, 103 * האזינו, וזאת הברכה, 104 * ויקהל פקודי, תזריע 105 * מצרע, אחרי מות 106 * קדושים, בהר בחקתי, 107 * חוקת בלק, מטות מסעי, 108 * נצבים וילך, שקלים, 109 * זכור, פרה, החדש, 110 * שובה,שירה,הגדול, 111 * חזון,נחמו</code> 112 */ 113 private final EnumMap<JewishCalendar.Parsha, String> hebrewParshaMap; 114 115 /** 116 * Default constructor sets the {@link EnumMap}s of Hebrew and default transliterated parshiyos. 117 */ 118 public HebrewDateFormatter() { 119 weekFormat = DateTimeFormatter.ofPattern("EEEE"); 120 transliteratedParshaMap = new EnumMap<>(JewishCalendar.Parsha.class); 121 transliteratedParshaMap.put(JewishCalendar.Parsha.NONE, ""); 122 transliteratedParshaMap.put(JewishCalendar.Parsha.BERESHIS, "Bereshis"); 123 transliteratedParshaMap.put(JewishCalendar.Parsha.NOACH, "Noach"); 124 transliteratedParshaMap.put(JewishCalendar.Parsha.LECH_LECHA, "Lech Lecha"); 125 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYERA, "Vayera"); 126 transliteratedParshaMap.put(JewishCalendar.Parsha.CHAYEI_SARA, "Chayei Sara"); 127 transliteratedParshaMap.put(JewishCalendar.Parsha.TOLDOS, "Toldos"); 128 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYETZEI, "Vayetzei"); 129 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYISHLACH, "Vayishlach"); 130 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYESHEV, "Vayeshev"); 131 transliteratedParshaMap.put(JewishCalendar.Parsha.MIKETZ, "Miketz"); 132 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYIGASH, "Vayigash"); 133 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYECHI, "Vayechi"); 134 transliteratedParshaMap.put(JewishCalendar.Parsha.SHEMOS, "Shemos"); 135 transliteratedParshaMap.put(JewishCalendar.Parsha.VAERA, "Vaera"); 136 transliteratedParshaMap.put(JewishCalendar.Parsha.BO, "Bo"); 137 transliteratedParshaMap.put(JewishCalendar.Parsha.BESHALACH, "Beshalach"); 138 transliteratedParshaMap.put(JewishCalendar.Parsha.YISRO, "Yisro"); 139 transliteratedParshaMap.put(JewishCalendar.Parsha.MISHPATIM, "Mishpatim"); 140 transliteratedParshaMap.put(JewishCalendar.Parsha.TERUMAH, "Terumah"); 141 transliteratedParshaMap.put(JewishCalendar.Parsha.TETZAVEH, "Tetzaveh"); 142 transliteratedParshaMap.put(JewishCalendar.Parsha.KI_SISA, "Ki Sisa"); 143 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYAKHEL, "Vayakhel"); 144 transliteratedParshaMap.put(JewishCalendar.Parsha.PEKUDEI, "Pekudei"); 145 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYIKRA, "Vayikra"); 146 transliteratedParshaMap.put(JewishCalendar.Parsha.TZAV, "Tzav"); 147 transliteratedParshaMap.put(JewishCalendar.Parsha.SHMINI, "Shmini"); 148 transliteratedParshaMap.put(JewishCalendar.Parsha.TAZRIA, "Tazria"); 149 transliteratedParshaMap.put(JewishCalendar.Parsha.METZORA, "Metzora"); 150 transliteratedParshaMap.put(JewishCalendar.Parsha.ACHREI_MOS, "Achrei Mos"); 151 transliteratedParshaMap.put(JewishCalendar.Parsha.KEDOSHIM, "Kedoshim"); 152 transliteratedParshaMap.put(JewishCalendar.Parsha.EMOR, "Emor"); 153 transliteratedParshaMap.put(JewishCalendar.Parsha.BEHAR, "Behar"); 154 transliteratedParshaMap.put(JewishCalendar.Parsha.BECHUKOSAI, "Bechukosai"); 155 transliteratedParshaMap.put(JewishCalendar.Parsha.BAMIDBAR, "Bamidbar"); 156 transliteratedParshaMap.put(JewishCalendar.Parsha.NASSO, "Nasso"); 157 transliteratedParshaMap.put(JewishCalendar.Parsha.BEHAALOSCHA, "Beha'aloscha"); 158 transliteratedParshaMap.put(JewishCalendar.Parsha.SHLACH, "Sh'lach"); 159 transliteratedParshaMap.put(JewishCalendar.Parsha.KORACH, "Korach"); 160 transliteratedParshaMap.put(JewishCalendar.Parsha.CHUKAS, "Chukas"); 161 transliteratedParshaMap.put(JewishCalendar.Parsha.BALAK, "Balak"); 162 transliteratedParshaMap.put(JewishCalendar.Parsha.PINCHAS, "Pinchas"); 163 transliteratedParshaMap.put(JewishCalendar.Parsha.MATOS, "Matos"); 164 transliteratedParshaMap.put(JewishCalendar.Parsha.MASEI, "Masei"); 165 transliteratedParshaMap.put(JewishCalendar.Parsha.DEVARIM, "Devarim"); 166 transliteratedParshaMap.put(JewishCalendar.Parsha.VAESCHANAN, "Vaeschanan"); 167 transliteratedParshaMap.put(JewishCalendar.Parsha.EIKEV, "Eikev"); 168 transliteratedParshaMap.put(JewishCalendar.Parsha.REEH, "Re'eh"); 169 transliteratedParshaMap.put(JewishCalendar.Parsha.SHOFTIM, "Shoftim"); 170 transliteratedParshaMap.put(JewishCalendar.Parsha.KI_SEITZEI, "Ki Seitzei"); 171 transliteratedParshaMap.put(JewishCalendar.Parsha.KI_SAVO, "Ki Savo"); 172 transliteratedParshaMap.put(JewishCalendar.Parsha.NITZAVIM, "Nitzavim"); 173 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYEILECH, "Vayeilech"); 174 transliteratedParshaMap.put(JewishCalendar.Parsha.HAAZINU, "Ha'Azinu"); 175 transliteratedParshaMap.put(JewishCalendar.Parsha.VZOS_HABERACHA, "Vezos Habracha"); 176 transliteratedParshaMap.put(JewishCalendar.Parsha.VAYAKHEL_PEKUDEI, "Vayakhel Pekudei"); 177 transliteratedParshaMap.put(JewishCalendar.Parsha.TAZRIA_METZORA, "Tazria Metzora"); 178 transliteratedParshaMap.put(JewishCalendar.Parsha.ACHREI_MOS_KEDOSHIM, "Achrei Mos Kedoshim"); 179 transliteratedParshaMap.put(JewishCalendar.Parsha.BEHAR_BECHUKOSAI, "Behar Bechukosai"); 180 transliteratedParshaMap.put(JewishCalendar.Parsha.CHUKAS_BALAK, "Chukas Balak"); 181 transliteratedParshaMap.put(JewishCalendar.Parsha.MATOS_MASEI, "Matos Masei"); 182 transliteratedParshaMap.put(JewishCalendar.Parsha.NITZAVIM_VAYEILECH, "Nitzavim Vayeilech"); 183 transliteratedParshaMap.put(JewishCalendar.Parsha.SHKALIM, "Shekalim"); 184 transliteratedParshaMap.put(JewishCalendar.Parsha.ZACHOR, "Zachor"); 185 transliteratedParshaMap.put(JewishCalendar.Parsha.PARA, "Parah"); 186 transliteratedParshaMap.put(JewishCalendar.Parsha.HACHODESH, "Hachodesh"); 187 transliteratedParshaMap.put(JewishCalendar.Parsha.SHUVA, "Shuva"); 188 transliteratedParshaMap.put(JewishCalendar.Parsha.SHIRA, "Shira"); 189 transliteratedParshaMap.put(JewishCalendar.Parsha.HAGADOL, "Hagadol"); 190 transliteratedParshaMap.put(JewishCalendar.Parsha.CHAZON, "Chazon"); 191 transliteratedParshaMap.put(JewishCalendar.Parsha.NACHAMU, "Nachamu"); 192 193 hebrewParshaMap = new EnumMap<>(JewishCalendar.Parsha.class); 194 hebrewParshaMap.put(JewishCalendar.Parsha.NONE, ""); 195 hebrewParshaMap.put(JewishCalendar.Parsha.BERESHIS, "\u05D1\u05E8\u05D0\u05E9\u05D9\u05EA"); 196 hebrewParshaMap.put(JewishCalendar.Parsha.NOACH, "\u05E0\u05D7"); 197 hebrewParshaMap.put(JewishCalendar.Parsha.LECH_LECHA, "\u05DC\u05DA \u05DC\u05DA"); 198 hebrewParshaMap.put(JewishCalendar.Parsha.VAYERA, "\u05D5\u05D9\u05E8\u05D0"); 199 hebrewParshaMap.put(JewishCalendar.Parsha.CHAYEI_SARA, "\u05D7\u05D9\u05D9 \u05E9\u05E8\u05D4"); 200 hebrewParshaMap.put(JewishCalendar.Parsha.TOLDOS, "\u05EA\u05D5\u05DC\u05D3\u05D5\u05EA"); 201 hebrewParshaMap.put(JewishCalendar.Parsha.VAYETZEI, "\u05D5\u05D9\u05E6\u05D0"); 202 hebrewParshaMap.put(JewishCalendar.Parsha.VAYISHLACH, "\u05D5\u05D9\u05E9\u05DC\u05D7"); 203 hebrewParshaMap.put(JewishCalendar.Parsha.VAYESHEV, "\u05D5\u05D9\u05E9\u05D1"); 204 hebrewParshaMap.put(JewishCalendar.Parsha.MIKETZ, "\u05DE\u05E7\u05E5"); 205 hebrewParshaMap.put(JewishCalendar.Parsha.VAYIGASH, "\u05D5\u05D9\u05D2\u05E9"); 206 hebrewParshaMap.put(JewishCalendar.Parsha.VAYECHI, "\u05D5\u05D9\u05D7\u05D9"); 207 hebrewParshaMap.put(JewishCalendar.Parsha.SHEMOS, "\u05E9\u05DE\u05D5\u05EA"); 208 hebrewParshaMap.put(JewishCalendar.Parsha.VAERA, "\u05D5\u05D0\u05E8\u05D0"); 209 hebrewParshaMap.put(JewishCalendar.Parsha.BO, "\u05D1\u05D0"); 210 hebrewParshaMap.put(JewishCalendar.Parsha.BESHALACH, "\u05D1\u05E9\u05DC\u05D7"); 211 hebrewParshaMap.put(JewishCalendar.Parsha.YISRO, "\u05D9\u05EA\u05E8\u05D5"); 212 hebrewParshaMap.put(JewishCalendar.Parsha.MISHPATIM, "\u05DE\u05E9\u05E4\u05D8\u05D9\u05DD"); 213 hebrewParshaMap.put(JewishCalendar.Parsha.TERUMAH, "\u05EA\u05E8\u05D5\u05DE\u05D4"); 214 hebrewParshaMap.put(JewishCalendar.Parsha.TETZAVEH, "\u05EA\u05E6\u05D5\u05D4"); 215 hebrewParshaMap.put(JewishCalendar.Parsha.KI_SISA, "\u05DB\u05D9 \u05EA\u05E9\u05D0"); 216 hebrewParshaMap.put(JewishCalendar.Parsha.VAYAKHEL, "\u05D5\u05D9\u05E7\u05D4\u05DC"); 217 hebrewParshaMap.put(JewishCalendar.Parsha.PEKUDEI, "\u05E4\u05E7\u05D5\u05D3\u05D9"); 218 hebrewParshaMap.put(JewishCalendar.Parsha.VAYIKRA, "\u05D5\u05D9\u05E7\u05E8\u05D0"); 219 hebrewParshaMap.put(JewishCalendar.Parsha.TZAV, "\u05E6\u05D5"); 220 hebrewParshaMap.put(JewishCalendar.Parsha.SHMINI, "\u05E9\u05DE\u05D9\u05E0\u05D9"); 221 hebrewParshaMap.put(JewishCalendar.Parsha.TAZRIA, "\u05EA\u05D6\u05E8\u05D9\u05E2"); 222 hebrewParshaMap.put(JewishCalendar.Parsha.METZORA, "\u05DE\u05E6\u05E8\u05E2"); 223 hebrewParshaMap.put(JewishCalendar.Parsha.ACHREI_MOS, "\u05D0\u05D7\u05E8\u05D9 \u05DE\u05D5\u05EA"); 224 hebrewParshaMap.put(JewishCalendar.Parsha.KEDOSHIM, "\u05E7\u05D3\u05D5\u05E9\u05D9\u05DD"); 225 hebrewParshaMap.put(JewishCalendar.Parsha.EMOR, "\u05D0\u05DE\u05D5\u05E8"); 226 hebrewParshaMap.put(JewishCalendar.Parsha.BEHAR, "\u05D1\u05D4\u05E8"); 227 hebrewParshaMap.put(JewishCalendar.Parsha.BECHUKOSAI, "\u05D1\u05D7\u05E7\u05EA\u05D9"); 228 hebrewParshaMap.put(JewishCalendar.Parsha.BAMIDBAR, "\u05D1\u05DE\u05D3\u05D1\u05E8"); 229 hebrewParshaMap.put(JewishCalendar.Parsha.NASSO, "\u05E0\u05E9\u05D0"); 230 hebrewParshaMap.put(JewishCalendar.Parsha.BEHAALOSCHA, "\u05D1\u05D4\u05E2\u05DC\u05EA\u05DA"); 231 hebrewParshaMap.put(JewishCalendar.Parsha.SHLACH, "\u05E9\u05DC\u05D7 \u05DC\u05DA"); 232 hebrewParshaMap.put(JewishCalendar.Parsha.KORACH, "\u05E7\u05E8\u05D7"); 233 hebrewParshaMap.put(JewishCalendar.Parsha.CHUKAS, "\u05D7\u05D5\u05E7\u05EA"); 234 hebrewParshaMap.put(JewishCalendar.Parsha.BALAK, "\u05D1\u05DC\u05E7"); 235 hebrewParshaMap.put(JewishCalendar.Parsha.PINCHAS, "\u05E4\u05D9\u05E0\u05D7\u05E1"); 236 hebrewParshaMap.put(JewishCalendar.Parsha.MATOS, "\u05DE\u05D8\u05D5\u05EA"); 237 hebrewParshaMap.put(JewishCalendar.Parsha.MASEI, "\u05DE\u05E1\u05E2\u05D9"); 238 hebrewParshaMap.put(JewishCalendar.Parsha.DEVARIM, "\u05D3\u05D1\u05E8\u05D9\u05DD"); 239 hebrewParshaMap.put(JewishCalendar.Parsha.VAESCHANAN, "\u05D5\u05D0\u05EA\u05D7\u05E0\u05DF"); 240 hebrewParshaMap.put(JewishCalendar.Parsha.EIKEV, "\u05E2\u05E7\u05D1"); 241 hebrewParshaMap.put(JewishCalendar.Parsha.REEH, "\u05E8\u05D0\u05D4"); 242 hebrewParshaMap.put(JewishCalendar.Parsha.SHOFTIM, "\u05E9\u05D5\u05E4\u05D8\u05D9\u05DD"); 243 hebrewParshaMap.put(JewishCalendar.Parsha.KI_SEITZEI, "\u05DB\u05D9 \u05EA\u05E6\u05D0"); 244 hebrewParshaMap.put(JewishCalendar.Parsha.KI_SAVO, "\u05DB\u05D9 \u05EA\u05D1\u05D5\u05D0"); 245 hebrewParshaMap.put(JewishCalendar.Parsha.NITZAVIM, "\u05E0\u05E6\u05D1\u05D9\u05DD"); 246 hebrewParshaMap.put(JewishCalendar.Parsha.VAYEILECH, "\u05D5\u05D9\u05DC\u05DA"); 247 hebrewParshaMap.put(JewishCalendar.Parsha.HAAZINU, "\u05D4\u05D0\u05D6\u05D9\u05E0\u05D5"); 248 hebrewParshaMap.put(JewishCalendar.Parsha.VZOS_HABERACHA, "\u05D5\u05D6\u05D0\u05EA \u05D4\u05D1\u05E8\u05DB\u05D4 "); 249 hebrewParshaMap.put(JewishCalendar.Parsha.VAYAKHEL_PEKUDEI, "\u05D5\u05D9\u05E7\u05D4\u05DC \u05E4\u05E7\u05D5\u05D3\u05D9"); 250 hebrewParshaMap.put(JewishCalendar.Parsha.TAZRIA_METZORA, "\u05EA\u05D6\u05E8\u05D9\u05E2 \u05DE\u05E6\u05E8\u05E2"); 251 hebrewParshaMap.put(JewishCalendar.Parsha.ACHREI_MOS_KEDOSHIM, "\u05D0\u05D7\u05E8\u05D9 \u05DE\u05D5\u05EA \u05E7\u05D3\u05D5\u05E9\u05D9\u05DD"); 252 hebrewParshaMap.put(JewishCalendar.Parsha.BEHAR_BECHUKOSAI, "\u05D1\u05D4\u05E8 \u05D1\u05D7\u05E7\u05EA\u05D9"); 253 hebrewParshaMap.put(JewishCalendar.Parsha.CHUKAS_BALAK, "\u05D7\u05D5\u05E7\u05EA \u05D1\u05DC\u05E7"); 254 hebrewParshaMap.put(JewishCalendar.Parsha.MATOS_MASEI, "\u05DE\u05D8\u05D5\u05EA \u05DE\u05E1\u05E2\u05D9"); 255 hebrewParshaMap.put(JewishCalendar.Parsha.NITZAVIM_VAYEILECH, "\u05E0\u05E6\u05D1\u05D9\u05DD \u05D5\u05D9\u05DC\u05DA"); 256 hebrewParshaMap.put(JewishCalendar.Parsha.SHKALIM, "\u05E9\u05E7\u05DC\u05D9\u05DD"); 257 hebrewParshaMap.put(JewishCalendar.Parsha.ZACHOR, "\u05D6\u05DB\u05D5\u05E8"); 258 hebrewParshaMap.put(JewishCalendar.Parsha.PARA, "\u05E4\u05E8\u05D4"); 259 hebrewParshaMap.put(JewishCalendar.Parsha.HACHODESH, "\u05D4\u05D7\u05D3\u05E9"); 260 hebrewParshaMap.put(JewishCalendar.Parsha.SHUVA, "\u05E9\u05D5\u05D1\u05D4"); 261 hebrewParshaMap.put(JewishCalendar.Parsha.SHIRA, "\u05E9\u05D9\u05E8\u05D4"); 262 hebrewParshaMap.put(JewishCalendar.Parsha.HAGADOL, "\u05D4\u05D2\u05D3\u05D5\u05DC"); 263 hebrewParshaMap.put(JewishCalendar.Parsha.CHAZON, "\u05D7\u05D6\u05D5\u05DF"); 264 hebrewParshaMap.put(JewishCalendar.Parsha.NACHAMU, "\u05E0\u05D7\u05DE\u05D5"); 265 } 266 267 /** 268 * Returns if the {@link #formatDayOfWeek(JewishDate)} will use the long format such as ראשון 269 * or short such as א when formatting the day of week in {@link #isHebrewFormat() Hebrew}. 270 * 271 * @return the longWeekFormat 272 * @see #setLongWeekFormat(boolean) 273 * @see #formatDayOfWeek(JewishDate) 274 */ 275 public boolean isLongWeekFormat() { 276 return longWeekFormat; 277 } 278 279 /** 280 * Setting to control if the {@link #formatDayOfWeek(JewishDate)} will use the long format such as 281 * ראשון or short such as א when formatting the day of week in {@link #isHebrewFormat() 282 * Hebrew}. 283 * 284 * @param longWeekFormat 285 * the longWeekFormat to set 286 */ 287 public void setLongWeekFormat(boolean longWeekFormat) { 288 this.longWeekFormat = longWeekFormat; 289 if (longWeekFormat) { 290 weekFormat = DateTimeFormatter.ofPattern("EEEE"); 291 } else { 292 weekFormat = DateTimeFormatter.ofPattern("EEE"); 293 } 294 } 295 296 /** 297 * The <a href="https://en.wikipedia.org/wiki/Geresh#Punctuation_mark">gersh</a> character is the ׳ char 298 * that is similar to a single quote and is used in formatting Hebrew numbers. 299 */ 300 private static final String GERESH = "\u05F3"; 301 302 /** 303 * The <a href="https://en.wikipedia.org/wiki/Gershayim#Punctuation_mark">gershyim</a> character is the ״ char 304 * that is similar to a double quote and is used in formatting Hebrew numbers. 305 */ 306 private static final String GERSHAYIM = "\u05F4"; 307 308 /** 309 * Transliterated month names that default to <code>["Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan", 310 * "Kislev", "Teves", "Shevat", "Adar", "Adar II", "Adar I" ]</code>. 311 * @see #getTransliteratedMonthList() 312 * @see #setTransliteratedMonthList(String[]) 313 */ 314 private String[] transliteratedMonths = { "Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan", 315 "Kislev", "Teves", "Shevat", "Adar", "Adar II", "Adar I" }; 316 317 /** 318 * The Hebrew omer prefix charachter. It defaults to ב producing בעומר, 319 * but can be set to ל to produce לעומר (or any other prefix). 320 * @see #getHebrewOmerPrefix() 321 * @see #setHebrewOmerPrefix(String) 322 */ 323 private String hebrewOmerPrefix = "\u05D1"; 324 325 /** 326 * The default value for formatting "Shabbos" (Saturday) when transliterated. 327 * @see #getTransliteratedShabbosDayOfWeek() 328 * @see #setTransliteratedShabbosDayOfWeek(String) 329 */ 330 private String transliteratedShabbosDayOfWeek = "Shabbos"; 331 332 /** 333 * Returns the day of Shabbos transliterated into Latin chars. The default uses Ashkenazi pronunciation "Shabbos". 334 * This can be overwritten using the {@link #setTransliteratedShabbosDayOfWeek(String)}. It is uesd by {@link 335 * #formatDayOfWeek(JewishDate)}. 336 * 337 * @return the transliteratedShabbos. The default list of months uses Ashkenazi pronunciation "Shabbos". 338 * @see #setTransliteratedShabbosDayOfWeek(String) 339 * @see #formatDayOfWeek(JewishDate) 340 */ 341 public String getTransliteratedShabbosDayOfWeek() { 342 return transliteratedShabbosDayOfWeek; 343 } 344 345 /** 346 * Setter to override the default transliterated name of "Shabbos" to alternate spelling such as "Shabbat" used by 347 * the {@link #formatDayOfWeek(JewishDate)}. 348 * 349 * @param transliteratedShabbos 350 * the transliteratedShabbos to set 351 * 352 * @see #getTransliteratedShabbosDayOfWeek() 353 * @see #formatDayOfWeek(JewishDate) 354 */ 355 public void setTransliteratedShabbosDayOfWeek(String transliteratedShabbos) { 356 this.transliteratedShabbosDayOfWeek = transliteratedShabbos; 357 } 358 359 /** 360 * See {@link #getTransliteratedHolidayList()} and {@link #setTransliteratedHolidayList(String[])}. 361 */ 362 private String[] transliteratedHolidays = {"Erev Pesach", "Pesach", "Chol Hamoed Pesach", "Pesach Sheni", 363 "Erev Shavuos", "Shavuos", "Seventeenth of Tammuz", "Tishah B'Av", "Tu B'Av", "Erev Rosh Hashana", 364 "Rosh Hashana", "Fast of Gedalyah", "Erev Yom Kippur", "Yom Kippur", "Erev Succos", "Succos", 365 "Chol Hamoed Succos", "Hoshana Rabbah", "Shemini Atzeres", "Simchas Torah", "Erev Chanukah", "Chanukah", 366 "Tenth of Teves", "Tu B'Shvat", "Fast of Esther", "Purim", "Shushan Purim", "Purim Katan", "Rosh Chodesh", 367 "Yom HaShoah", "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim", "Lag B'Omer", "Shushan Purim Katan", 368 "Isru Chag"}; 369 370 /** 371 * Returns the array of <em>Yomim Tovim</em> (holidays) transliterated into Latin chars. This is used by the {@link 372 * #formatYomTov(JewishCalendar)} when formatting the <em>Yom Tov</em> String. The default list of months usesnAshkenazi 373 * pronunciation in typical American English spelling. The default list is currently 374 * <code>["Erev Pesach", "Pesach", "Chol Hamoed Pesach", "Pesach Sheni", "Erev Shavuos", "Shavuos", "Seventeenth of Tammuz", 375 * "Tishah B'Av", "Tu B'Av", "Erev Rosh Hashana", "Rosh Hashana", "Fast of Gedalyah", "Erev Yom Kippur", "Yom Kippur", "Erev 376 * Succos", "Succos", "Chol Hamoed Succos", "Hoshana Rabbah", "Shemini Atzeres", "Simchas Torah", "Erev Chanukah", "Chanukah", 377 * "Tenth of Teves", "Tu B'Shvat", "Fast of Esther", "Purim", "Shushan Purim",m"Purim Katan", "Rosh Chodesh", "Yom HaShoah", 378 * "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim", "Lag B'Omer", "Shushan Purim Katan", "Isru Chag"]</code>. 379 * 380 * @return the array of transliterated <em>Yomim Tovim</em> (holidays). 381 * 382 * @see #setTransliteratedMonthList(String[]) 383 * @see #formatYomTov(JewishCalendar) 384 * @see #isHebrewFormat() 385 */ 386 public String[] getTransliteratedHolidayList() { 387 return transliteratedHolidays; 388 } 389 390 /** 391 * Sets the array of <em>Yomim Tovim</em> (holidays) transliterated into Latin chars. This is used by the 392 * {@link #formatYomTov(JewishCalendar)} when formatting the <em>Yom Tov</em> String. The list uses the following order and uses 393 * the spelling as follows. 394 * <code>["Erev Pesach", "Pesach", "Chol Hamoed Pesach", "Pesach Sheni", "Erev Shavuos", "Shavuos", "Seventeenth of Tammuz", 395 * "Tishah B'Av", "Tu B'Av", "Erev Rosh Hashana", "Rosh Hashana", "Fast of Gedalyah", "Erev Yom Kippur", "Yom Kippur", "Erev 396 * Succos", "Succos", "Chol Hamoed Succos", "Hoshana Rabbah", "Shemini Atzeres", "Simchas Torah", "Erev Chanukah", "Chanukah", 397 * "Tenth of Teves", "Tu B'Shvat", "Fast of Esther", "Purim", "Shushan Purim", "Purim Katan", "Rosh Chodesh", "Yom HaShoah", 398 * "Yom Hazikaron", "Yom Ha'atzmaut", "Yom Yerushalayim", "Lag B'Omer", "Shushan Purim Katan", "Isru Chag"]</code>. 399 * 400 * @param transliteratedHolidays 401 * the transliteratedHolidays to set. Ensure that the sequence exactly matches the list returned by the 402 * default 403 */ 404 public void setTransliteratedHolidayList(String[] transliteratedHolidays) { 405 this.transliteratedHolidays = transliteratedHolidays; 406 } 407 408 /** 409 * Hebrew <em>Yomim Tovim</em> (holidays) array in the following format.<br> 410 * <code>‏["ערב פסח", 411 * "פסח", "חול המועד 412 * פסח", "פסח שני", "ערב 413 * שבועות", "שבועות", 414 * "שבעה עשר בתמוז", 415 * "תשעה באב", 416 * "ט״ו באב", 417 * "ערב ראש השנה", 418 * "ראש השנה", 419 * "צום גדליה", 420 * "ערב יום כיפור", 421 * "יום כיפור", 422 * "ערב סוכות", 423 * "סוכות", 424 * "חול המועד סוכות", 425 * "הושענא רבה", 426 * "שמיני עצרת", 427 * "שמחת תורה", 428 * "ערב חנוכה", 429 * "חנוכה", "עשרה בטבת", 430 * "ט״ו בשבט", 431 * "תענית אסתר", 432 * "פורים", 433 * "שושן פורים", 434 * "פורים קטן", 435 * "ראש חודש", 436 * "יום השואה", 437 * "יום הזיכרון", 438 * "יום העצמאות", 439 * "יום ירושלים", 440 * "ל״ג בעומר", 441 * "שושן פורים קטן"]</code> 442 */ 443 private final String[] hebrewHolidays = { "\u05E2\u05E8\u05D1 \u05E4\u05E1\u05D7", "\u05E4\u05E1\u05D7", 444 "\u05D7\u05D5\u05DC \u05D4\u05DE\u05D5\u05E2\u05D3 \u05E4\u05E1\u05D7", 445 "\u05E4\u05E1\u05D7 \u05E9\u05E0\u05D9", "\u05E2\u05E8\u05D1 \u05E9\u05D1\u05D5\u05E2\u05D5\u05EA", 446 "\u05E9\u05D1\u05D5\u05E2\u05D5\u05EA", 447 "\u05E9\u05D1\u05E2\u05D4 \u05E2\u05E9\u05E8 \u05D1\u05EA\u05DE\u05D5\u05D6", 448 "\u05EA\u05E9\u05E2\u05D4 \u05D1\u05D0\u05D1", "\u05D8\u05F4\u05D5 \u05D1\u05D0\u05D1", 449 "\u05E2\u05E8\u05D1 \u05E8\u05D0\u05E9 \u05D4\u05E9\u05E0\u05D4", 450 "\u05E8\u05D0\u05E9 \u05D4\u05E9\u05E0\u05D4", "\u05E6\u05D5\u05DD \u05D2\u05D3\u05DC\u05D9\u05D4", 451 "\u05E2\u05E8\u05D1 \u05D9\u05D5\u05DD \u05DB\u05D9\u05E4\u05D5\u05E8", 452 "\u05D9\u05D5\u05DD \u05DB\u05D9\u05E4\u05D5\u05E8", "\u05E2\u05E8\u05D1 \u05E1\u05D5\u05DB\u05D5\u05EA", 453 "\u05E1\u05D5\u05DB\u05D5\u05EA", 454 "\u05D7\u05D5\u05DC \u05D4\u05DE\u05D5\u05E2\u05D3 \u05E1\u05D5\u05DB\u05D5\u05EA", 455 "\u05D4\u05D5\u05E9\u05E2\u05E0\u05D0 \u05E8\u05D1\u05D4", 456 "\u05E9\u05DE\u05D9\u05E0\u05D9 \u05E2\u05E6\u05E8\u05EA", 457 "\u05E9\u05DE\u05D7\u05EA \u05EA\u05D5\u05E8\u05D4", "\u05E2\u05E8\u05D1 \u05D7\u05E0\u05D5\u05DB\u05D4", 458 "\u05D7\u05E0\u05D5\u05DB\u05D4", "\u05E2\u05E9\u05E8\u05D4 \u05D1\u05D8\u05D1\u05EA", 459 "\u05D8\u05F4\u05D5 \u05D1\u05E9\u05D1\u05D8", "\u05EA\u05E2\u05E0\u05D9\u05EA \u05D0\u05E1\u05EA\u05E8", 460 "\u05E4\u05D5\u05E8\u05D9\u05DD", "\u05E9\u05D5\u05E9\u05DF \u05E4\u05D5\u05E8\u05D9\u05DD", 461 "\u05E4\u05D5\u05E8\u05D9\u05DD \u05E7\u05D8\u05DF", "\u05E8\u05D0\u05E9 \u05D7\u05D5\u05D3\u05E9", 462 "\u05D9\u05D5\u05DD \u05D4\u05E9\u05D5\u05D0\u05D4", 463 "\u05D9\u05D5\u05DD \u05D4\u05D6\u05D9\u05DB\u05E8\u05D5\u05DF", 464 "\u05D9\u05D5\u05DD \u05D4\u05E2\u05E6\u05DE\u05D0\u05D5\u05EA", 465 "\u05D9\u05D5\u05DD \u05D9\u05E8\u05D5\u05E9\u05DC\u05D9\u05DD", 466 "\u05DC\u05F4\u05D2 \u05D1\u05E2\u05D5\u05DE\u05E8", 467 "\u05E9\u05D5\u05E9\u05DF \u05E4\u05D5\u05E8\u05D9\u05DD \u05E7\u05D8\u05DF", 468 "\u05D0\u05E1\u05E8\u05D5 \u05D7\u05D2"}; 469 470 /** 471 * Formats the <em>Yom Tov</em> (holiday) in Hebrew or transliterated Latin characters. 472 * 473 * @param jewishCalendar the JewishCalendar 474 * @return the formatted <em>Yom Tov</em> (holiday) or an empty String if the day is not a <em>Yom Tov</em> (holiday). 475 * @see #isHebrewFormat() 476 */ 477 public String formatYomTov(JewishCalendar jewishCalendar) { 478 int index = jewishCalendar.getYomTovIndex(); 479 if (index == JewishCalendar.CHANUKAH) { 480 int dayOfChanukah = jewishCalendar.getDayOfChanukah(); 481 return hebrewFormat ? (formatHebrewNumber(dayOfChanukah) + " " + hebrewHolidays[index]) 482 : (transliteratedHolidays[index] + " " + dayOfChanukah); 483 } 484 return index == -1 ? "" : hebrewFormat ? hebrewHolidays[index] : transliteratedHolidays[index]; 485 } 486 487 /** 488 * Formats a day as Rosh Chodesh in the format of in the format of ראש 489 * חודש שבט or Rosh Chodesh Shevat. If it 490 * is not Rosh Chodesh, an empty <code>String</code> will be returned. 491 * @param jewishCalendar the JewishCalendar 492 * @return The formatted <code>String</code> in the format of ראש 493 * חודש שבט or Rosh Chodesh Shevat. If it 494 * is not Rosh Chodesh, an empty <code>String</code> will be returned. 495 */ 496 public String formatRoshChodesh(JewishCalendar jewishCalendar) { 497 if (!jewishCalendar.isRoshChodesh()) { 498 return ""; 499 } 500 int month = jewishCalendar.getJewishMonth(); 501 if (jewishCalendar.getJewishDayOfMonth() == 30) { 502 if (month < JewishCalendar.ADAR || (month == JewishCalendar.ADAR && jewishCalendar.isJewishLeapYear())) { 503 month++; 504 } else { // roll to Nissan 505 month = JewishCalendar.NISSAN; 506 } 507 } 508 509 // This method is only about formatting, so we shouldn't make any changes to the params passed in... 510 jewishCalendar = (JewishCalendar) jewishCalendar.clone(); 511 jewishCalendar.setJewishMonth(month); 512 String formattedRoshChodesh = hebrewFormat ? hebrewHolidays[JewishCalendar.ROSH_CHODESH] 513 : transliteratedHolidays[JewishCalendar.ROSH_CHODESH]; 514 formattedRoshChodesh += " " + formatMonth(jewishCalendar); 515 return formattedRoshChodesh; 516 } 517 518 /** 519 * Returns if the formatter is set to use Hebrew formatting in the various formatting methods. 520 * 521 * @return the hebrewFormat 522 * @see #setHebrewFormat(boolean) 523 * @see #format(JewishDate) 524 * @see #formatDayOfWeek(JewishDate) 525 * @see #formatMonth(JewishDate) 526 * @see #formatOmer(JewishCalendar) 527 * @see #formatYomTov(JewishCalendar) 528 */ 529 public boolean isHebrewFormat() { 530 return hebrewFormat; 531 } 532 533 /** 534 * Sets the formatter to format in Hebrew in the various formatting methods. 535 * 536 * @param hebrewFormat 537 * the hebrewFormat to set 538 * @see #isHebrewFormat() 539 * @see #format(JewishDate) 540 * @see #formatDayOfWeek(JewishDate) 541 * @see #formatMonth(JewishDate) 542 * @see #formatOmer(JewishCalendar) 543 * @see #formatYomTov(JewishCalendar) 544 */ 545 public void setHebrewFormat(boolean hebrewFormat) { 546 this.hebrewFormat = hebrewFormat; 547 } 548 549 /** 550 * Returns the Hebrew Omer prefix. By default it is the letter ב producing בעומר, 551 * but it can be set to ל to produce לעומר (or any other prefix) using the 552 * {@link #setHebrewOmerPrefix(String)}. 553 * 554 * @return the hebrewOmerPrefix 555 * @see #hebrewOmerPrefix 556 * @see #setHebrewOmerPrefix(String) 557 * @see #formatOmer(JewishCalendar) 558 */ 559 public String getHebrewOmerPrefix() { 560 return hebrewOmerPrefix; 561 } 562 563 /** 564 * Method to set the Hebrew Omer prefix. By default it is the letter ב producing בעומר, 565 * but it can be set to ל to produce לעומר (or any other prefix). 566 * @param hebrewOmerPrefix 567 * the hebrewOmerPrefix to set. You can use the Unicode \u05DC to set it to ל. 568 * @see #hebrewOmerPrefix 569 * @see #getHebrewOmerPrefix() 570 * @see #formatOmer(JewishCalendar) 571 */ 572 public void setHebrewOmerPrefix(String hebrewOmerPrefix) { 573 this.hebrewOmerPrefix = hebrewOmerPrefix; 574 } 575 576 /** 577 * Returns the Hebrew array of months in the order of <code>‏["\u05E0\u05D9\u05E1\u05DF", "\u05D0\u05D9\u05D9\u05E8", 578 * "\u05E1\u05D9\u05D5\u05DF", "\u05EA\u05DE\u05D5\u05D6", "\u05D0\u05D1", "\u05D0\u05DC\u05D5\u05DC", 579 * "\u05EA\u05E9\u05E8\u05D9", "\u05D7\u05E9\u05D5\u05DF", "\u05DB\u05E1\u05DC\u05D5", "\u05D8\u05D1\u05EA", 580 * "\u05E9\u05D1\u05D8", "\u05D0\u05D3\u05E8", "\u05D0\u05D3\u05E8 \u05D1", "\u05D0\u05D3\u05E8 \u05D0"]</code>. This list has 581 * a length of 14 starting with "ניסן" and ending with 3 variations of Adar - 582 * "אדר", "אדר ב", "אדר א". 583 * @return the array of Hebrew months. 584 * @see #hebrewMonths 585 * @see #setHebrewMonthList(String[]) 586 */ 587 public String[] getHebrewMonthList() { 588 return hebrewMonths; 589 } 590 591 /** 592 * Setter method to allow overriding of the default list of Hebrew month names. This allows changing things such as the default 593 * month name of חשון to מרחשון, etc. This list expects a 594 * length of 14 starting with "ניסן" and ending with 3 variations of Adar - 595 * "אדר", "אדר ב", "אדר". 596 * 597 * @param hebrewMonths the array of Hebrew months beginning in "ניסן" and ending in 598 * "אדר", "אדר ב", "אדר א" 599 * @see #getHebrewMonthList() 600 */ 601 public void setHebrewMonthList(String[] hebrewMonths) { 602 if(hebrewMonths.length !=14) { 603 throw new IllegalArgumentException("The Hebrew month array must have a length of 14."); 604 } 605 this.hebrewMonths = hebrewMonths; 606 } 607 608 /** 609 * Returns the array of months transliterated into Latin chars. The default list of months uses Ashkenazi pronunciation in 610 * typical American English spelling. This list has a length of 14 with 3 variations for Adar - "Adar", "Adar II", "Adar I". 611 * The array of months beginn in Nissan and end in "Adar", "Adar II", "Adar I". The default list is 612 * <code>["Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan", "Kislev", "Teves", "Shevat", "Adar", 613 * "Adar II", "Adar I"]</code>. 614 * 615 * @return the array of 14 month names beginning in Nissan and ending in "Adar", "Adar II", "Adar I". 616 * @see #setTransliteratedMonthList(String[]) 617 */ 618 public String[] getTransliteratedMonthList() { 619 return transliteratedMonths; 620 } 621 622 /** 623 * Setter method to allow overriding of the default list of months transliterated into Latin chars. The default list uses 624 * Ashkenazi American English transliteration. The array of 14 transliterated month names begin in "Nissan" and end in the 625 * 3 Adar variations - "Adar", "Adar II", "Adar I". The default list is 626 * <code>["Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Tishrei", "Cheshvan", "Kislev", "Teves", "Shevat", "Adar", 627 * "Adar II", "Adar I"]</code>. 628 * 629 * @param transliteratedMonths the array of 14 month names beginning in Nissan and ending in "Adar", "Adar II", "Adar I". 630 * @see #getTransliteratedMonthList() 631 */ 632 public void setTransliteratedMonthList(String[] transliteratedMonths) { 633 if(transliteratedHolidays.length !=14) { 634 throw new IllegalArgumentException("The transliterated month array must have a length of 14."); 635 } 636 this.transliteratedMonths = transliteratedMonths; 637 } 638 639 /** 640 * List of Hebrew months. The list has* a length of 14 starting with "ניסן" and ending with the 641 * 3 variations of Adar - "אדר", "אדר ב", "אדר א". 642 * 643 * @see #getHebrewMonthList() 644 * @see #setHebrewMonthList(String[]) 645 * @see #formatMonth(JewishDate) 646 */ 647 private String[] hebrewMonths = { "\u05E0\u05D9\u05E1\u05DF", "\u05D0\u05D9\u05D9\u05E8", 648 "\u05E1\u05D9\u05D5\u05DF", "\u05EA\u05DE\u05D5\u05D6", "\u05D0\u05D1", "\u05D0\u05DC\u05D5\u05DC", 649 "\u05EA\u05E9\u05E8\u05D9", "\u05D7\u05E9\u05D5\u05DF", "\u05DB\u05E1\u05DC\u05D5", 650 "\u05D8\u05D1\u05EA", "\u05E9\u05D1\u05D8", "\u05D0\u05D3\u05E8", "\u05D0\u05D3\u05E8 \u05D1", 651 "\u05D0\u05D3\u05E8 \u05D0" }; 652 653 /** 654 * Unicode list of Hebrew days of week in the format of <code>‏["ראשון", 655 * "שני", "שלישי", "רביעי", 656 * "חמישי", "ששי", "שבת"]</code> 657 */ 658 private static final String[] hebrewDaysOfWeek = { "\u05E8\u05D0\u05E9\u05D5\u05DF", "\u05E9\u05E0\u05D9", 659 "\u05E9\u05DC\u05D9\u05E9\u05D9", "\u05E8\u05D1\u05D9\u05E2\u05D9", "\u05D7\u05DE\u05D9\u05E9\u05D9", 660 "\u05E9\u05E9\u05D9", "\u05E9\u05D1\u05EA" }; 661 662 /** 663 * Formats the day of week. If {@link #isHebrewFormat() Hebrew formatting} is set, it will display in the format 664 * ראשון etc. If Hebrew formatting is not in use it will return it in the format 665 * of Sunday etc. There are various formatting options that will affect the output. 666 * 667 * @param jewishDate the JewishDate Object 668 * @return the formatted day of week 669 * @see #isHebrewFormat() 670 * @see #isLongWeekFormat() 671 */ 672 public String formatDayOfWeek(JewishDate jewishDate) { 673 if (hebrewFormat) { 674 if (isLongWeekFormat()) { 675 return hebrewDaysOfWeek[jewishDate.getDayOfWeek() - 1]; 676 } else { 677 if (jewishDate.getDayOfWeek() == 7) { 678 return formatHebrewNumber(300); 679 } else { 680 return formatHebrewNumber(jewishDate.getDayOfWeek()); 681 } 682 } 683 } else { 684 if (jewishDate.getDayOfWeek() == 7) { 685 if (isLongWeekFormat()) { 686 return getTransliteratedShabbosDayOfWeek(); 687 } else { 688 return getTransliteratedShabbosDayOfWeek().substring(0,3); 689 } 690 } else { 691 return weekFormat.format(jewishDate.getLocalDate()); 692 } 693 } 694 } 695 696 /** 697 * Returns whether the class is set to use the Geresh ׳ and Gershayim ״ in formatting Hebrew dates and 698 * numbers. When true and output would look like כ״א שבט תש״כ 699 * (or כ״א שבט תש״ך). When set to false, this output 700 * would display as כא שבט תשכ. 701 * 702 * @return true if set to use the Geresh ׳ and Gershayim ״ in formatting Hebrew dates and numbers. 703 */ 704 public boolean isUseGershGershayim() { 705 return useGershGershayim; 706 } 707 708 /** 709 * Sets whether to use the Geresh ׳ and Gershayim ״ in formatting Hebrew dates and numbers. The default 710 * value is true and output would look like כ״א שבט תש״כ 711 * (or כ״א שבט תש״ך). When set to false, this output would 712 * display as כא שבט תשכ (or 713 * כא שבט תשך). Single digit days or month or years such as כ׳ 714 * שבט ו׳ אלפים show the use of the Geresh. 715 * 716 * @param useGershGershayim 717 * set this to false to omit the Geresh ׳ and Gershayim ״ in formatting 718 */ 719 public void setUseGershGershayim(boolean useGershGershayim) { 720 this.useGershGershayim = useGershGershayim; 721 } 722 723 /** 724 * Returns whether the class is set to use the מנצפ״ך letters when 725 * formatting years ending in 20, 40, 50, 80 and 90 to produce תש״פ if false or 726 * תש״ף if true. Traditionally non-final form letters are used, so the year 727 * 5780 would be formatted as תש״פ if the default false is used here. If this returns 728 * true, the format תש״ף would be used. 729 * 730 * @return true if set to use final form letters when formatting Hebrew years. The default value is false. 731 */ 732 public boolean isUseFinalFormLetters() { 733 return useFinalFormLetters; 734 } 735 736 /** 737 * When formatting a Hebrew Year, traditionally years ending in 20, 40, 50, 80 and 90 are formatted using non-final 738 * form letters for example תש״פ for the year 5780. Setting this to true (the default 739 * is false) will use the final form letters for מנצפ״ך and will format 740 * the year 5780 as תש״ף. 741 * 742 * @param useFinalFormLetters 743 * Set this to true to use final form letters when formatting Hebrew years. 744 */ 745 public void setUseFinalFormLetters(boolean useFinalFormLetters) { 746 this.useFinalFormLetters = useFinalFormLetters; 747 } 748 749 /** 750 * Returns whether the class is set to use the thousands digit when formatting. When formatting a Hebrew Year, 751 * traditionally the thousands digit is omitted and output for a year such as 5729 (1969 Gregorian) would be 752 * calculated for 729 and format as תשכ״ט. When set to true the long format year such 753 * as ה׳ תשכ״ט for 5729/1969 is returned. 754 * 755 * @return true if set to use the thousands digit when formatting Hebrew dates and numbers. 756 */ 757 public boolean isUseLongHebrewYears() { 758 return useLonghebrewYears; 759 } 760 761 /** 762 * When formatting a Hebrew Year, traditionally the thousands digit is omitted and output for a year such as 5729 763 * (1969 Gregorian) would be calculated for 729 and format as תשכ״ט. This method 764 * allows setting this to true to return the long format year such as ה׳ 765 * תשכ״ט for 5729/1969. 766 * 767 * @param useLongHebrewYears 768 * Set this to true to use the long formatting 769 */ 770 public void setUseLongHebrewYears(boolean useLongHebrewYears) { 771 this.useLonghebrewYears = useLongHebrewYears; 772 } 773 /** 774 * Formats the Jewish date. If the formatter is set to Hebrew, it will format in the form, "day Month year" for 775 * example כ״א שבט תשכ״ט, and the format 776 * "21 Shevat, 5729" if not. 777 * 778 * @param jewishDate 779 * the JewishDate to be formatted 780 * @return the formatted date. If the formatter is set to Hebrew, it will format in the form, "day Month year" for 781 * example כ״א שבט תשכ״ט, and the format 782 * "21 Shevat, 5729" if not. 783 */ 784 public String format(JewishDate jewishDate) { 785 if (isHebrewFormat()) { 786 return formatHebrewNumber(jewishDate.getJewishDayOfMonth()) + " " + formatMonth(jewishDate) + " " 787 + formatHebrewNumber(jewishDate.getJewishYear()); 788 } else { 789 return jewishDate.getJewishDayOfMonth() + " " + formatMonth(jewishDate) + ", " + jewishDate.getJewishYear(); 790 } 791 } 792 793 /** 794 * Returns a string of the current Hebrew month such as "Tishrei". Returns a string of the current Hebrew month such 795 * as "אדר ב׳". 796 * 797 * @param jewishDate 798 * the JewishDate to format 799 * @return the formatted month name 800 * @see #isHebrewFormat() 801 * @see #setHebrewFormat(boolean) 802 * @see #getTransliteratedMonthList() 803 * @see #setTransliteratedMonthList(String[]) 804 */ 805 public String formatMonth(JewishDate jewishDate) { 806 final int month = jewishDate.getJewishMonth(); 807 if (isHebrewFormat()) { 808 if (jewishDate.isJewishLeapYear() && month == JewishDate.ADAR) { 809 return hebrewMonths[13] + (useGershGershayim ? GERESH : ""); // return Adar I, not Adar in a leap year 810 } else if (jewishDate.isJewishLeapYear() && month == JewishDate.ADAR_II) { 811 return hebrewMonths[12] + (useGershGershayim ? GERESH : ""); 812 } else { 813 return hebrewMonths[month - 1]; 814 } 815 } else { 816 if (jewishDate.isJewishLeapYear() && month == JewishDate.ADAR) { 817 return transliteratedMonths[13]; // return Adar I, not Adar in a leap year 818 } else { 819 return transliteratedMonths[month - 1]; 820 } 821 } 822 } 823 824 /** 825 * Returns a String of the Omer day in the form ל״ג בעומר if 826 * Hebrew Format is set, or "Omer X" or "Lag B'Omer" if not. An empty string if there is no Omer this day. 827 * 828 * @param jewishCalendar 829 * the JewishCalendar to be formatted 830 * 831 * @return a String of the Omer day in the form or an empty string if there is no Omer this day. The default 832 * formatting has a ב׳ prefix that would output בעומר, but this 833 * can be set via the {@link #setHebrewOmerPrefix(String)} method to use a ל and output 834 * ל״ג לעומר. 835 * @see #isHebrewFormat() 836 * @see #getHebrewOmerPrefix() 837 * @see #setHebrewOmerPrefix(String) 838 */ 839 public String formatOmer(JewishCalendar jewishCalendar) { 840 int omer = jewishCalendar.getDayOfOmer(); 841 if (omer == -1) { 842 return ""; 843 } 844 if (hebrewFormat) { 845 return formatHebrewNumber(omer) + " " + hebrewOmerPrefix + "\u05E2\u05D5\u05DE\u05E8"; 846 } else { 847 if (omer == 33) { // if Lag B'Omer 848 return transliteratedHolidays[33]; 849 } else { 850 return "Omer " + omer; 851 } 852 } 853 } 854 855 /** 856 * Returns the kviah in the traditional 3 letter Hebrew format where the first letter represents the day of week of 857 * Rosh Hashana, the second letter represents the lengths of Cheshvan and Kislev ({@link JewishDate#SHELAIMIM 858 * Shelaimim} , {@link JewishDate#KESIDRAN Kesidran} or {@link JewishDate#CHASERIM Chaserim}) and the 3rd letter 859 * represents the day of week of Pesach. For example 5729 (1969) would return בשה (Rosh Hashana on 860 * Monday, Shelaimim, and Pesach on Thursday), while 5771 (2011) would return השג (Rosh Hashana on 861 * Thursday, Shelaimim, and Pesach on Tuesday). 862 * 863 * @param jewishYear 864 * the Jewish year 865 * @return the Hebrew String such as בשה for 5729 (1969) and השג for 5771 866 * (2011). 867 */ 868 public String getFormattedKviah(int jewishYear) { 869 JewishDate jewishDate = new JewishDate(jewishYear, JewishDate.TISHREI, 1); // set date to Rosh Hashana 870 int kviah = jewishDate.getCheshvanKislevKviah(); 871 int roshHashanaDayOfWeek = jewishDate.getDayOfWeek(); 872 String returnValue = formatHebrewNumber(roshHashanaDayOfWeek); 873 returnValue += (kviah == JewishDate.CHASERIM ? "\u05D7" : kviah == JewishDate.SHELAIMIM ? "\u05E9" : "\u05DB"); 874 jewishDate.setJewishDate(jewishYear, JewishDate.NISSAN, 15); // set to Pesach of the given year 875 int pesachDayOfWeek = jewishDate.getDayOfWeek(); 876 returnValue += formatHebrewNumber(pesachDayOfWeek); 877 returnValue = returnValue.replaceAll(GERESH, "");// geresh is never used in the kviah format 878 // boolean isLeapYear = JewishDate.isJewishLeapYear(jewishYear); 879 // for efficiency we can avoid the expensive recalculation of the pesach day of week by adding 1 day to Rosh 880 // Hashana for a 353-day year, 2 for a 354-day year, 3 for a 355 or 383-day year, 4 for a 384-day year and 5 for 881 // a 385-day year 882 return returnValue; 883 } 884 885 /** 886 * Formats the <a href="https://en.wikipedia.org/wiki/Daf_Yomi">Daf Yomi</a> Bavli in the format of 887 * "עירובין נ״ב" in {@link #isHebrewFormat() Hebrew}, 888 * or the transliterated format of "Eruvin 52". 889 * @param daf the Daf to be formatted. 890 * @return the formatted daf. 891 */ 892 public String formatDafYomiBavli(Daf daf) { 893 if (hebrewFormat) { 894 return daf.getMasechta() + " " + formatHebrewNumber(daf.getDaf()); 895 } else { 896 return daf.getMasechtaTransliterated() + " " + daf.getDaf(); 897 } 898 } 899 900 /** 901 * Formats the <a href="https://en.wikipedia.org/wiki/Jerusalem_Talmud#Daf_Yomi_Yerushalmi">Daf Yomi Yerushalmi</a> in the format 902 * of "עירובין נ״ב" in {@link #isHebrewFormat() Hebrew}, or 903 * the transliterated format of "Eruvin 52". 904 * 905 * @param daf the Daf to be formatted. 906 * @return the formatted daf. 907 */ 908 public String formatDafYomiYerushalmi(Daf daf) { 909 if (daf == null) { 910 if (hebrewFormat) { 911 return Daf.getYerushalmiMasechtos()[39]; 912 } else { 913 return Daf.getYerushalmiMasechtosTransliterated()[39]; 914 } 915 } 916 if (hebrewFormat) { 917 return daf.getYerushalmiMasechta() + " " + formatHebrewNumber(daf.getDaf()); 918 } else { 919 return daf.getYerushalmiMasechtaTransliterated() + " " + daf.getDaf(); 920 } 921 } 922 923 /** 924 * Returns a Hebrew formatted string of a number. The method can calculate from 0 to 9999. 925 * <ul> 926 * <li>Single digit numbers such as 3, 30 and 100 will be returned with a ׳ (<a 927 * href="http://en.wikipedia.org/wiki/Geresh">Geresh</a>) appended as at the end. For example ג׳, 928 * ל׳ and ק׳</li> 929 * <li>multi digit numbers such as 21 and 769 will be returned with a ״ (<a 930 * href="http://en.wikipedia.org/wiki/Gershayim">Gershayim</a>) between the second to last and last letters. For 931 * example כ״א, תשכ״ט</li> 932 * <li>15 and 16 will be returned as ט״ו and ט״ז</li> 933 * <li>Single digit numbers (years assumed) such as 6000 (%1000=0) will be returned as ו׳ 934 * אלפים</li> 935 * <li>0 will return אפס</li> 936 * </ul> 937 * 938 * @param number 939 * the number to be formatted. It will trow an IllegalArgumentException if the number is < 0 or > 9999. 940 * @return the Hebrew formatted number such as תשכ״ט 941 * @see #isUseFinalFormLetters() 942 * @see #isUseGershGershayim() 943 * @see #isHebrewFormat() 944 * 945 */ 946 public String formatHebrewNumber(int number) { 947 if (number < 0) { 948 throw new IllegalArgumentException("negative numbers can't be formatted"); 949 } else if (number > 9999) { 950 throw new IllegalArgumentException("numbers > 9999 can't be formatted"); 951 } 952 953 String ALAFIM = "\u05D0\u05DC\u05E4\u05D9\u05DD"; 954 String EFES = "\u05D0\u05E4\u05E1"; 955 956 String[] jHundreds = new String[] { "", "\u05E7", "\u05E8", "\u05E9", "\u05EA", "\u05EA\u05E7", "\u05EA\u05E8", 957 "\u05EA\u05E9", "\u05EA\u05EA", "\u05EA\u05EA\u05E7" }; 958 String[] jTens = new String[] { "", "\u05D9", "\u05DB", "\u05DC", "\u05DE", "\u05E0", "\u05E1", "\u05E2", 959 "\u05E4", "\u05E6" }; 960 String[] jTenEnds = new String[] { "", "\u05D9", "\u05DA", "\u05DC", "\u05DD", "\u05DF", "\u05E1", "\u05E2", 961 "\u05E3", "\u05E5" }; 962 String[] tavTaz = new String[] { "\u05D8\u05D5", "\u05D8\u05D6" }; 963 String[] jOnes = new String[] { "", "\u05D0", "\u05D1", "\u05D2", "\u05D3", "\u05D4", "\u05D5", "\u05D6", 964 "\u05D7", "\u05D8" }; 965 966 if (number == 0) { // do we really need this? Should it be applicable to a date? 967 return EFES; 968 } 969 int shortNumber = number % 1000; // discard thousands 970 // next check for all possible single Hebrew digit years 971 boolean singleDigitNumber = (shortNumber < 11 || (shortNumber < 100 && shortNumber % 10 == 0) || (shortNumber <= 400 && shortNumber % 100 == 0)); 972 int thousands = number / 1000; // get # thousands 973 StringBuilder sb = new StringBuilder(); 974 // append thousands to String 975 if (number % 1000 == 0) { // in year is 5000, 4000 etc 976 sb.append(jOnes[thousands]); 977 if (isUseGershGershayim()) { 978 sb.append(GERESH); 979 } 980 sb.append(" "); 981 sb.append(ALAFIM); // add # of thousands plus the word "thousand" (override alafim boolean) 982 return sb.toString(); 983 } else if (useLonghebrewYears && number >= 1000) { // if alafim boolean display thousands 984 sb.append(jOnes[thousands]); 985 if (isUseGershGershayim()) { 986 sb.append(GERESH); // append thousands quote 987 } 988 sb.append(" "); 989 } 990 number = number % 1000; // remove 1000s 991 int hundreds = number / 100; // # of hundreds 992 sb.append(jHundreds[hundreds]); // add hundreds to String 993 number = number % 100; // remove 100s 994 if (number == 15) { // special case 15 995 sb.append(tavTaz[0]); 996 } else if (number == 16) { // special case 16 997 sb.append(tavTaz[1]); 998 } else { 999 int tens = number / 10; 1000 if (number % 10 == 0) { // if evenly divisible by 10 1001 if (!singleDigitNumber) { 1002 if (isUseFinalFormLetters()) { 1003 sb.append(jTenEnds[tens]); // years like 5780 will end with a final form ף 1004 } else { 1005 sb.append(jTens[tens]); // years like 5780 will end with a regular פ 1006 } 1007 } else { 1008 sb.append(jTens[tens]); // standard letters so years like 5050 will end with a regular nun 1009 } 1010 } else { 1011 sb.append(jTens[tens]); 1012 number = number % 10; 1013 sb.append(jOnes[number]); 1014 } 1015 } 1016 if (isUseGershGershayim()) { 1017 if (singleDigitNumber) { 1018 sb.append(GERESH); // append single quote 1019 } else { // append double quote before last digit 1020 sb.insert(sb.length() - 1, GERSHAYIM); 1021 } 1022 } 1023 return sb.toString(); 1024 } 1025 1026 /** 1027 * Returns the map of transliterated parshiyos used by this formatter. This list using the default <em>Ashkenazi</em> 1028 * pronunciation. This list can be overridden (for <em>Sephardi</em> English transliteration for example) by setting the 1029 * {@link #setTransliteratedParshiosList(EnumMap)}. The list includes double and special <em>parshiyos</em> in the following 1030 * order and spelling "<em>Bereshis, Noach, Lech Lecha, Vayera, Chayei Sara, Toldos, Vayetzei, Vayishlach, Vayeshev, Miketz, 1031 * Vayigash, Vayechi, Shemos, Vaera, Bo, Beshalach, Yisro, Mishpatim, Terumah, Tetzaveh, Ki Sisa, Vayakhel, Pekudei, Vayikra, 1032 * Tzav, Shmini, Tazria, Metzora, Achrei Mos, Kedoshim, Emor, Behar, Bechukosai, Bamidbar, Nasso, Beha'aloscha, Sh'lach, 1033 * Korach, Chukas, Balak, Pinchas, Matos, Masei, Devarim, Vaeschanan, Eikev, Re'eh, Shoftim, Ki Seitzei, Ki Savo, Nitzavim, 1034 * Vayeilech, Ha'Azinu, Vezos Habracha, Vayakhel Pekudei, Tazria Metzora, Achrei Mos Kedoshim, Behar Bechukosai, Chukas Balak, 1035 * Matos Masei, Nitzavim Vayeilech, Shekalim, Zachor, Parah, Hachodesh,Shuva, Shira, Hagadol, Chazon, Nachamu</em>". 1036 * 1037 * @return the map of transliterated Parshios 1038 * @see #setTransliteratedParshiosList(EnumMap) 1039 * @see #formatParsha(JewishCalendar) 1040 * @see #formatParsha(JewishCalendar.Parsha) 1041 */ 1042 public EnumMap<JewishCalendar.Parsha, String> getTransliteratedParshiosList() { 1043 return transliteratedParshaMap; 1044 } 1045 1046 /** 1047 * Setter method to allow overriding of the default list of parshiyos transliterated into Latin chars. The 1048 * default uses Ashkenazi American English transliteration. 1049 * 1050 * @param transliteratedParshaMap 1051 * the transliterated Parshios as an EnumMap to set 1052 * @see #getTransliteratedParshiosList() for information on the format. 1053 */ 1054 public void setTransliteratedParshiosList(EnumMap<JewishCalendar.Parsha, String> transliteratedParshaMap) { 1055 this.transliteratedParshaMap = transliteratedParshaMap; 1056 } 1057 1058 /** 1059 * Returns a String with the name of the current parsha(ios). This method gets the current <em>parsha</em> by 1060 * calling {@link JewishCalendar#getParshah()} that does not return a <em>parsha</em> for any non-<em>Shabbos</em> 1061 * or a <em>Shabbos</em> that occurs on a <em>Yom Tov</em>, and will return an empty <code>String</code> in those 1062 * cases. If the class {@link #isHebrewFormat() is set to format in Hebrew} it will return a <code>String</code> 1063 * of the current parsha(ios) in Hebrew for example בראשית or 1064 * נצבים וילך or an empty string if there 1065 * are none. If not set to Hebrew, it returns a string of the parsha(ios) transliterated into Latin chars. The 1066 * default uses Ashkenazi pronunciation in typical American English spelling, for example Bereshis or 1067 * Nitzavim Vayeilech or an empty string if there are none. 1068 * 1069 * @param jewishCalendar the JewishCalendar Object 1070 * @return today's parsha(ios) in Hebrew for example, if the formatter is set to format in Hebrew, returns a string 1071 * of the current parsha(ios) in Hebrew for example בראשית or 1072 * נצבים וילך or an empty string if 1073 * there are none. If not set to Hebrew, it returns a string of the parsha(ios) transliterated into Latin 1074 * chars. The default uses Ashkenazi pronunciation in typical American English spelling, for example 1075 * Bereshis or Nitzavim Vayeilech or an empty string if there are none. 1076 * @see #formatParsha(JewishCalendar) 1077 * @see #isHebrewFormat() 1078 * @see JewishCalendar#getParshah() 1079 */ 1080 public String formatParsha(JewishCalendar jewishCalendar) { 1081 JewishCalendar.Parsha parsha = jewishCalendar.getParshah(); 1082 return formatParsha(parsha); 1083 } 1084 1085 /** 1086 * Returns a String with the name of the current parsha(ios). This method overloads {@link #formatParsha(JewishCalendar)} and 1087 * unlike that method, it will format the <em>parsha</em> passed to this method regardless of the day of week. This is the way 1088 * to format a <em>parsha</em> retrieved from calling 1089 * {@link JewishCalendar#getUpcomingParshah()}. 1090 * 1091 * @param parsha a JewishCalendar.Parsha object 1092 * @return today's parsha(ios) in Hebrew for example, if the formatter is set to format in Hebrew, returns a string 1093 * of the current parsha(ios) in Hebrew for example בראשית or 1094 * נצבים וילך or an empty string if 1095 * there are none. If not set to Hebrew, it returns a string of the parsha(ios) transliterated into Latin 1096 * chars. The default uses Ashkenazi pronunciation in typical American English spelling, for example 1097 * Bereshis or Nitzavim Vayeilech or an empty string if there are none. 1098 * @see #formatParsha(JewishCalendar) 1099 * @see JewishCalendar#getUpcomingParshah() 1100 */ 1101 public String formatParsha(JewishCalendar.Parsha parsha) { 1102 return hebrewFormat ? hebrewParshaMap.get(parsha) : transliteratedParshaMap.get(parsha); 1103 } 1104 1105 /** 1106 * Returns a String with the name of the current special parsha of Shekalim, Zachor, Parah or Hachodesh or an 1107 * empty String for a non-special parsha. If the formatter is set to format in Hebrew, it returns a string of 1108 * the current special parsha in Hebrew, for example שקלים, 1109 * זכור, פרה or החדש. An empty 1110 * string if the date is not a special parsha. If not set to Hebrew, it returns a string of the special parsha 1111 * transliterated into Latin chars. The default uses Ashkenazi pronunciation in typical American English spelling 1112 * Shekalim, Zachor, Parah or Hachodesh. 1113 * 1114 * @param jewishCalendar the JewishCalendar Object 1115 * @return today's special parsha. If the formatter is set to format in Hebrew, returns a string 1116 * of the current special parsha in Hebrew for in the format of שקלים, 1117 * זכור, פרה or החדש or an empty 1118 * string if there are none. If not set to Hebrew, it returns a string of the special parsha transliterated 1119 * into Latin chars. The default uses Ashkenazi pronunciation in typical American English spelling of Shekalim, 1120 * Zachor, Parah or Hachodesh. An empty string if there are none. 1121 */ 1122 public String formatSpecialParsha(JewishCalendar jewishCalendar) { 1123 JewishCalendar.Parsha specialParsha = jewishCalendar.getSpecialShabbos(); 1124 return hebrewFormat ? hebrewParshaMap.get(specialParsha) : transliteratedParshaMap.get(specialParsha); 1125 } 1126}