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