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