diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java
index 4e1a7bdb..22016429 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/HebrewDateFormatter.java
@@ -824,6 +824,303 @@ public String formatDafYomiYerushalmi(Daf daf) {
}
}
+ /**
+ * Formats the Mishna Yomi reading.
+ * @param mishnaYomi the Mishna Yomi to be formatted.
+ * @return the formatted Mishna Yomi.
+ */
+ public String formatMishnaYomi(MishnaYomi mishnaYomi) {
+ String start = (hebrewFormat ? mishnaYomi.getMasechta() + " " + formatHebrewNumber(mishnaYomi.getStartChapter())
+ + ": " + formatMishnaNumber(mishnaYomi.getStartMishna()) : mishnaYomi.getMasechtaTransliterated() + " "
+ + mishnaYomi.getStartChapter() + ":" + mishnaYomi.getStartMishna());
+ if (mishnaYomi.getStartMasechtaNumber() == mishnaYomi.getEndMasechtaNumber()
+ && mishnaYomi.getStartChapter() == mishnaYomi.getEndChapter()) {
+ return start + "-" + (hebrewFormat ? formatMishnaNumber(mishnaYomi.getEndMishna()) : mishnaYomi.getEndMishna());
+ }
+ return start + "-" + (hebrewFormat ? mishnaYomi.getEndMasechta() + " " + formatHebrewNumber(mishnaYomi.getEndChapter())
+ + ": " + formatMishnaNumber(mishnaYomi.getEndMishna()) : mishnaYomi.getEndMasechtaTransliterated() + " "
+ + mishnaYomi.getEndChapter() + ":" + mishnaYomi.getEndMishna());
+ }
+
+ /**
+ * Formats the daily Rambam reading.
+ * @param rambamYomi the Rambam Yomi to be formatted.
+ * @return the formatted Rambam Yomi.
+ */
+ public String formatRambamYomi(RambamYomi rambamYomi) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < rambamYomi.getReadingCount(); i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ String start = rambamYomi.getStartChapter(i);
+ String end = rambamYomi.getEndChapter(i);
+ if (hebrewFormat) {
+ sb.append(formatRambamHebrewName(rambamYomi.getBookNumber(i)));
+ sb.append(start.equals(end) ? " פרק " : " פרקים ");
+ sb.append(formatRambamChapter(start));
+ if (!start.equals(end)) {
+ sb.append("-").append(formatRambamChapter(end));
+ }
+ } else {
+ sb.append(rambamYomi.getName(i)).append(" ").append(start);
+ if (!start.equals(end)) {
+ sb.append("-").append(end);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Formats the daily Tehillim reading.
+ * @param tehillimYomi the daily Tehillim to be formatted.
+ * @return the formatted daily Tehillim.
+ */
+ public String formatDailyTehillim(TehillimYomi tehillimYomi) {
+ if (hebrewFormat) {
+ return "תהילים " + formatHebrewNumber(tehillimYomi.getStartChapter())
+ + (tehillimYomi.getStartChapter() == tehillimYomi.getEndChapter() ? "" : "-" + formatHebrewNumber(tehillimYomi.getEndChapter()));
+ }
+ return "Psalms " + tehillimYomi.getStartChapter()
+ + (tehillimYomi.getStartChapter() == tehillimYomi.getEndChapter() ? "" : "-" + tehillimYomi.getEndChapter());
+ }
+
+ /**
+ * Formats the Tanach Yomi reading.
+ * @param tanachYomi the Tanach Yomi to be formatted.
+ * @return the formatted Tanach Yomi.
+ */
+ public String formatTanachYomi(TanachYomi tanachYomi) {
+ if (tanachYomi == null) {
+ return "";
+ }
+ if (hebrewFormat) {
+ String[] parts = tanachYomi.getSeder().split("\\.");
+ String seder = " ס׳ " + formatHebrewNumber(Integer.parseInt(parts[0]));
+ if (parts.length > 1) {
+ seder += " " + formatHebrewNumber(Integer.parseInt(parts[1]));
+ }
+ return tanachYomi.getHebrewBook() + seder;
+ }
+ return tanachYomi.getBook() + " Seder " + tanachYomi.getSeder();
+ }
+
+ /**
+ * Formats the Kitzur Shulchan Aruch Yomi reading.
+ * @param kitzurYomi the Kitzur Shulchan Aruch Yomi to be formatted.
+ * @return the formatted Kitzur Shulchan Aruch Yomi.
+ */
+ public String formatKitzurShulchanAruchYomi(KitzurShulchanAruchYomi kitzurYomi) {
+ if (kitzurYomi == null) {
+ return "";
+ }
+ if (kitzurYomi.getStart().equals(kitzurYomi.getEnd())) {
+ return formatKitzurRef(kitzurYomi.getStart());
+ }
+ String[] start = kitzurYomi.getStart().split(":");
+ String[] end = kitzurYomi.getEnd().split(":");
+ if (start.length > 1 && end.length > 1 && start[0].equals(end[0])) {
+ return formatKitzurRef(kitzurYomi.getStart()) + "-" + (hebrewFormat ? formatPlainHebrewToken(end[1]) : end[1]);
+ }
+ return formatKitzurRef(kitzurYomi.getStart()) + (hebrewFormat ? " - " : "-") + formatKitzurRef(kitzurYomi.getEnd());
+ }
+
+ /**
+ * Formats the Shemiras HaLashon Yomi reading.
+ * @param shemirasYomi the Shemiras HaLashon Yomi to be formatted.
+ * @return the formatted Shemiras HaLashon Yomi.
+ */
+ public String formatShemirasHaLashonYomi(ShemirasHaLashonYomi shemirasYomi) {
+ if (shemirasYomi == null) {
+ return "";
+ }
+ if (hebrewFormat) {
+ String section = formatShemirasSection(shemirasYomi.getSection());
+ return "שמירת הלשון, חלק " + formatHebrewNumber(shemirasYomi.getBook())
+ + (section.length() == 0 ? ", " : ", " + section + ", ")
+ + formatShemirasSectionRef(shemirasYomi.getStart())
+ + (shemirasYomi.getStart().equals(shemirasYomi.getEnd()) ? ""
+ : formatShemirasSectionRangeEnd(shemirasYomi.getStart(), shemirasYomi.getEnd()));
+ }
+ String section = formatShemirasEnglishSection(shemirasYomi.getSection());
+ return "Shemirat HaLashon, Part " + shemirasYomi.getBook()
+ + (section.length() == 0 ? ", " : ", " + section + ", ")
+ + formatShemirasEnglishSectionRef(shemirasYomi.getStart())
+ + (shemirasYomi.getStart().equals(shemirasYomi.getEnd()) ? ""
+ : formatShemirasEnglishSectionRangeEnd(shemirasYomi.getStart(), shemirasYomi.getEnd()));
+ }
+
+ private String formatKitzurRef(String ref) {
+ String[] parts = ref.split(":");
+ if (hebrewFormat) {
+ return formatHebrewToken(parts[0]) + (parts.length > 1 ? ": " + formatPlainHebrewToken(parts[1]) : "");
+ }
+ return ref;
+ }
+
+ private String formatRambamHebrewName(int bookNumber) {
+ String name = LimudYomiData.RAMBAM_NAMES_HEBREW[bookNumber];
+ if (bookNumber < 4 || "סדר התפילה".equals(name)) {
+ return name;
+ }
+ return "הלכות " + name;
+ }
+
+ private String formatRambamChapter(String chapter) {
+ String[] range = chapter.split("-");
+ if (range.length == 2) {
+ return formatRambamChapterPart(range[0]) + "-" + formatRambamChapterPart(range[1]);
+ }
+ return formatRambamChapterPart(chapter);
+ }
+
+ private String formatRambamChapterPart(String chapter) {
+ String[] parts = chapter.split(":");
+ if (parts.length == 2) {
+ return formatPlainHebrewNumber(Integer.parseInt(parts[0])) + ":" + formatPlainHebrewNumber(Integer.parseInt(parts[1]));
+ }
+ return formatPlainHebrewNumber(Integer.parseInt(chapter));
+ }
+
+ private String formatShemirasKlalRef(String ref) {
+ String[] parts = ref.split("\\.");
+ return "פרק " + formatHebrewNumber(Integer.parseInt(parts[0])) + (parts.length > 1 ? " הלכה " + formatPlainHebrewToken(parts[1]) : "");
+ }
+
+ private String formatShemirasEnglishKlalRef(String ref) {
+ String[] parts = ref.split("\\.");
+ return "Perek " + parts[0] + (parts.length > 1 ? " Halacha " + parts[1] : "");
+ }
+
+ private String formatShemirasEnglishSection(String section) {
+ if ("Hakdamah".equals(section)) {
+ return "Hakdamah";
+ }
+ if ("Shar Hazechira".equals(section)) {
+ return "Shaar HaZechirah";
+ }
+ if ("Shar Hatvuna".equals(section)) {
+ return "Shaar HaTevunah";
+ }
+ if ("Shar Hatorah".equals(section)) {
+ return "Shaar HaTorah";
+ }
+ if ("Chasimas Hasefer".equals(section)) {
+ return "Chasima";
+ }
+ if ("x".equals(section)) {
+ return "";
+ }
+ return section;
+ }
+
+ private String formatShemirasSection(String section) {
+ if ("Hakdamah".equals(section)) {
+ return "הקדמה";
+ }
+ if ("Shar Hazechira".equals(section)) {
+ return "שער הזכירה";
+ }
+ if ("Shar Hatvuna".equals(section)) {
+ return "שער התבונה";
+ }
+ if ("Shar Hatorah".equals(section)) {
+ return "שער התורה";
+ }
+ if ("Chasimas Hasefer".equals(section)) {
+ return "חתימה";
+ }
+ if ("x".equals(section)) {
+ return "";
+ }
+ return section;
+ }
+
+ private String formatShemirasSectionRef(String ref) {
+ if (ref.indexOf('.') >= 0) {
+ return formatShemirasKlalRef(ref);
+ }
+ return formatPlainHebrewToken(ref);
+ }
+
+ private String formatShemirasEnglishSectionRef(String ref) {
+ if (ref.indexOf('.') >= 0) {
+ return formatShemirasEnglishKlalRef(ref);
+ }
+ return ref;
+ }
+
+ private String formatShemirasSectionRangeEnd(String start, String end) {
+ if (start.indexOf('.') >= 0 && end.indexOf('.') >= 0) {
+ return sameShemirasKlal(start, end) ? "-" + shemirasHalacha(end) : " - " + formatShemirasKlalRef(end);
+ }
+ return "-" + formatPlainHebrewToken(end);
+ }
+
+ private String formatShemirasEnglishSectionRangeEnd(String start, String end) {
+ if (start.indexOf('.') >= 0 && end.indexOf('.') >= 0) {
+ return sameShemirasKlal(start, end) ? "-" + shemirasHalachaEnglish(end) : " - " + formatShemirasEnglishKlalRef(end);
+ }
+ return "-" + end;
+ }
+
+ private boolean sameShemirasKlal(String start, String end) {
+ return start.split("\\.")[0].equals(end.split("\\.")[0]);
+ }
+
+ private String shemirasHalacha(String ref) {
+ String[] parts = ref.split("\\.");
+ return parts.length > 1 ? formatPlainHebrewToken(parts[1]) : "";
+ }
+
+ private String shemirasHalachaEnglish(String ref) {
+ String[] parts = ref.split("\\.");
+ return parts.length > 1 ? parts[1] : "";
+ }
+
+ private String formatHebrewToken(String token) {
+ if ("E".equals(token)) {
+ return "סוף";
+ }
+ if ("Shmita".equals(token)) {
+ return "שמיטה";
+ }
+ if ("Klalim".equals(token)) {
+ return "כללים";
+ }
+ try {
+ return formatHebrewNumber(Integer.parseInt(token));
+ } catch (NumberFormatException e) {
+ return token;
+ }
+ }
+
+ private String formatPlainHebrewToken(String token) {
+ if ("E".equals(token)) {
+ return "סוף";
+ }
+ if ("Shmita".equals(token)) {
+ return "שמיטה";
+ }
+ if ("Klalim".equals(token)) {
+ return "כללים";
+ }
+ try {
+ return formatPlainHebrewNumber(Integer.parseInt(token));
+ } catch (NumberFormatException e) {
+ return token;
+ }
+ }
+
+ private String formatPlainHebrewNumber(int number) {
+ return formatHebrewNumber(number).replace(GERESH, "").replace(GERSHAYIM, "");
+ }
+
+ private String formatMishnaNumber(int number) {
+ return formatHebrewNumber(number).replace(GERESH, "");
+ }
+
/**
* Returns a Hebrew formatted string of a number. The method can calculate from 0 to 9999.
*
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java
index ecf8d02c..0afd416d 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishCalendar.java
@@ -1347,6 +1347,62 @@ public Daf getDafYomiBavli() {
public Daf getDafYomiYerushalmi() {
return YerushalmiYomiCalculator.getDafYomiYerushalmi(this);
}
+
+ /**
+ * Returns the Mishna Yomi for the date that the calendar is set to.
+ * @return the Mishna Yomi as a {@link MishnaYomi}
+ */
+ public MishnaYomi getMishnaYomi() {
+ return MishnaYomiCalculator.getMishnaYomi(this);
+ }
+
+ /**
+ * Returns the one chapter Rambam Yomi for the date that the calendar is set to.
+ * @return the Rambam Yomi as a {@link RambamYomi}
+ */
+ public RambamYomi getRambamYomi() {
+ return RambamYomiCalculator.getRambamYomi(this);
+ }
+
+ /**
+ * Returns the three chapter Rambam Yomi for the date that the calendar is set to.
+ * @return the Rambam Yomi as a {@link RambamYomi}
+ */
+ public RambamYomi getRambamYomi3Chapters() {
+ return RambamYomiCalculator.getRambamYomi3Chapters(this);
+ }
+
+ /**
+ * Returns the daily Tehillim for the date that the calendar is set to.
+ * @return the daily Tehillim as a {@link TehillimYomi}
+ */
+ public TehillimYomi getDailyTehillim() {
+ return TehillimYomiCalculator.getDailyTehillim(this);
+ }
+
+ /**
+ * Returns the Tanach Yomi for the date that the calendar is set to.
+ * @return the Tanach Yomi as a {@link TanachYomi}, or null on days without a reading
+ */
+ public TanachYomi getTanachYomi() {
+ return TanachYomiCalculator.getTanachYomi(this);
+ }
+
+ /**
+ * Returns the Kitzur Shulchan Aruch Yomi for the date that the calendar is set to.
+ * @return the Kitzur Shulchan Aruch Yomi as a {@link KitzurShulchanAruchYomi}, or null on days without a reading
+ */
+ public KitzurShulchanAruchYomi getKitzurShulchanAruchYomi() {
+ return KitzurShulchanAruchYomiCalculator.getKitzurShulchanAruchYomi(this);
+ }
+
+ /**
+ * Returns the Shemiras HaLashon Yomi for the date that the calendar is set to.
+ * @return the Shemiras HaLashon Yomi as a {@link ShemirasHaLashonYomi}
+ */
+ public ShemirasHaLashonYomi getShemirasHaLashonYomi() {
+ return ShemirasHaLashonYomiCalculator.getShemirasHaLashonYomi(this);
+ }
/**
* Returns the elapsed days since Tekufas Tishrei. This uses Tekufas Shmuel (identical to the monthSchedule.length) {
+ return null;
+ }
+ String reading = monthSchedule[day - 1];
+ if (reading == null || reading.length() == 0) {
+ return null;
+ }
+ String[] parts = reading.split("-");
+ return new KitzurShulchanAruchYomi(parts[0], parts.length > 1 ? parts[1] : parts[0]);
+ }
+
+ private static String[] getMonthSchedule(JewishCalendar calendar, int month) {
+ switch (month) {
+ case JewishCalendar.NISSAN:
+ return LimudYomiData.KITZUR_NISAN;
+ case JewishCalendar.IYAR:
+ return LimudYomiData.KITZUR_IYYAR;
+ case JewishCalendar.SIVAN:
+ return LimudYomiData.KITZUR_SIVAN;
+ case JewishCalendar.TAMMUZ:
+ return LimudYomiData.KITZUR_TAMUZ;
+ case JewishCalendar.AV:
+ return LimudYomiData.KITZUR_AV;
+ case JewishCalendar.ELUL:
+ return LimudYomiData.KITZUR_ELUL;
+ case JewishCalendar.TISHREI:
+ return LimudYomiData.KITZUR_TISHREI;
+ case JewishCalendar.CHESHVAN:
+ return LimudYomiData.KITZUR_CHESHVAN;
+ case JewishCalendar.KISLEV:
+ return LimudYomiData.KITZUR_KISLEV;
+ case JewishCalendar.TEVES:
+ return LimudYomiData.KITZUR_TEVET;
+ case JewishCalendar.SHEVAT:
+ return LimudYomiData.KITZUR_SH_VAT;
+ case JewishCalendar.ADAR:
+ return LimudYomiData.KITZUR_ADAR;
+ case JewishCalendar.ADAR_II:
+ return calendar.isJewishLeapYear() ? LimudYomiData.KITZUR_LEAP_OPTION_A : null;
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/LimudYomiData.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/LimudYomiData.java
new file mode 100644
index 00000000..387d13eb
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/LimudYomiData.java
@@ -0,0 +1,109 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+/** Package-private offline data tables for daily limud calculators. */
+class LimudYomiData {
+ static final String[] MISHNA_NAMES = { "Berakhot", "Peah", "Demai", "Kilayim", "Sheviit", "Terumot", "Maasrot", "Maaser Sheni", "Challah", "Orlah", "Bikkurim", "Shabbat", "Eruvin", "Pesachim", "Shekalim", "Yoma", "Sukkah", "Beitzah", "Rosh Hashanah", "Taanit", "Megillah", "Moed Katan", "Chagigah", "Yevamot", "Ketubot", "Nedarim", "Nazir", "Sotah", "Gittin", "Kiddushin", "Bava Kamma", "Bava Metzia", "Bava Batra", "Sanhedrin", "Makkot", "Shevuot", "Eduyot", "Avodah Zarah", "Avot", "Horayot", "Zevachim", "Menachot", "Chullin", "Bekhorot", "Arakhin", "Temurah", "Keritot", "Meilah", "Tamid", "Middot", "Kinnim", "Kelim", "Oholot", "Negaim", "Parah", "Tahorot", "Mikvaot", "Niddah", "Makhshirin", "Zavim", "Tevul Yom", "Yadayim", "Oktzin" };
+ static final String[] MISHNA_NAMES_HEBREW = { "ברכות", "פאה", "דמאי", "כלאים", "שביעית", "תרומות", "מעשרות", "מעשר שני", "חלה", "ערלה", "ביכורים", "שבת", "עירובין", "פסחים", "שקלים", "יומא", "סוכה", "ביצה", "ראש השנה", "תענית", "מגילה", "מועד קטן", "חגיגה", "יבמות", "כתובות", "נדרים", "נזיר", "סוטה", "גיטין", "קידושין", "בבא קמא", "בבא מציעא", "בבא בתרא", "סנהדרין", "מכות", "שבועות", "עדיות", "עבודה זרה", "אבות", "הוריות", "זבחים", "מנחות", "חולין", "בכורות", "ערכין", "תמורה", "כריתות", "מעילה", "תמיד", "מדות", "קינים", "כלים", "אהלות", "נגעים", "פרה", "טהרות", "מקוואות", "נדה", "מכשירין", "זבים", "טבול יום", "ידים", "עוקצים" };
+ static final int[][] MISHNA_CHAPTERS = {
+ { 5, 8, 6, 7, 5, 8, 5, 8, 5 },
+ { 6, 8, 8, 11, 8, 11, 8, 9 },
+ { 4, 5, 6, 7, 11, 12, 8 },
+ { 9, 11, 7, 9, 8, 9, 8, 6, 10 },
+ { 8, 10, 10, 10, 9, 6, 7, 11, 9, 9 },
+ { 10, 6, 9, 13, 9, 6, 7, 12, 7, 12, 10 },
+ { 8, 8, 10, 6, 8 },
+ { 7, 10, 13, 12, 15 },
+ { 9, 8, 10, 11 },
+ { 9, 17, 9 },
+ { 11, 11, 12, 5 },
+ { 11, 7, 6, 2, 4, 10, 4, 7, 7, 6, 6, 6, 7, 4, 3, 8, 8, 3, 6, 5, 3, 6, 5, 5 },
+ { 10, 6, 9, 11, 9, 10, 11, 11, 4, 15 },
+ { 7, 8, 8, 9, 10, 6, 13, 8, 11, 9 },
+ { 7, 5, 4, 9, 6, 6, 7, 8 },
+ { 8, 7, 11, 6, 7, 8, 5, 9 },
+ { 11, 9, 15, 10, 8 },
+ { 10, 10, 8, 7, 7 },
+ { 9, 9, 8, 9 },
+ { 7, 10, 9, 8 },
+ { 11, 6, 6, 10 },
+ { 10, 5, 9 },
+ { 8, 7, 8 },
+ { 4, 10, 10, 13, 6, 6, 6, 6, 6, 9, 7, 6, 13, 9, 10, 7 },
+ { 10, 10, 9, 12, 9, 7, 10, 8, 9, 6, 6, 4, 11 },
+ { 4, 5, 11, 8, 6, 10, 9, 7, 10, 8, 12 },
+ { 7, 10, 7, 7, 7, 11, 4, 2, 5 },
+ { 9, 6, 8, 5, 5, 4, 8, 7, 15 },
+ { 6, 7, 8, 9, 9, 7, 9, 10, 10 },
+ { 10, 10, 13, 14 },
+ { 4, 6, 11, 9, 7, 6, 7, 7, 12, 10 },
+ { 8, 11, 12, 12, 11, 8, 11, 9, 13, 6 },
+ { 6, 14, 8, 9, 11, 8, 4, 8, 10, 8 },
+ { 6, 5, 8, 5, 5, 6, 11, 7, 6, 6, 6 },
+ { 10, 8, 16 },
+ { 7, 5, 11, 13, 5, 7, 8, 6 },
+ { 14, 10, 12, 12, 7, 3, 9, 7 },
+ { 9, 7, 10, 12, 12 },
+ { 18, 16, 18, 22, 23, 11 },
+ { 5, 7, 8 },
+ { 4, 5, 6, 6, 8, 7, 6, 12, 7, 8, 8, 6, 8, 10 },
+ { 4, 5, 7, 5, 9, 7, 6, 7, 9, 9, 9, 5, 11 },
+ { 7, 10, 7, 7, 5, 7, 6, 6, 8, 4, 2, 5 },
+ { 7, 9, 4, 10, 6, 12, 7, 10, 8 },
+ { 4, 6, 5, 4, 6, 5, 5, 7, 8 },
+ { 6, 3, 5, 4, 6, 5, 6 },
+ { 7, 6, 10, 3, 8, 9 },
+ { 4, 9, 8, 6, 5, 6 },
+ { 4, 5, 9, 3, 6, 3, 4 },
+ { 9, 6, 8, 7, 4 },
+ { 4, 5, 6 },
+ { 9, 8, 8, 4, 11, 4, 6, 11, 8, 8, 9, 8, 8, 8, 6, 8, 17, 9, 10, 7, 3, 10, 5, 17, 9, 9, 12, 10, 8, 4 },
+ { 8, 7, 7, 3, 7, 7, 6, 6, 16, 7, 9, 8, 6, 7, 10, 5, 5, 10 },
+ { 6, 5, 8, 11, 5, 8, 5, 10, 3, 10, 12, 7, 12, 13 },
+ { 4, 5, 11, 4, 9, 5, 12, 11, 9, 6, 9, 11 },
+ { 9, 8, 8, 13, 9, 10, 9, 9, 9, 8 },
+ { 8, 10, 4, 5, 6, 11, 7, 5, 7, 8 },
+ { 7, 7, 7, 7, 9, 14, 5, 4, 11, 8 },
+ { 6, 11, 8, 10, 11, 8 },
+ { 6, 4, 3, 7, 12 },
+ { 5, 8, 6, 7 },
+ { 5, 4, 5, 8 },
+ { 6, 10, 12 },
+ };
+
+ static final String[] RAMBAM_NAMES = { "Transmission of the Oral Law", "Positive Mitzvot", "Negative Mitzvot", "Overview of Mishneh Torah Contents", "Foundations of the Torah", "Human Dispositions", "Torah Study", "Foreign Worship and Customs of the Nations", "Repentance", "Reading the Shema", "Prayer and the Priestly Blessing", "Tefillin, Mezuzah and the Torah Scroll", "Fringes", "Blessings", "Circumcision", "The Order of Prayer", "Sabbath", "Eruvin", "Rest on the Tenth of Tishrei", "Rest on a Holiday", "Leavened and Unleavened Bread", "Shofar, Sukkah and Lulav", "Sheqel Dues", "Sanctification of the New Month", "Fasts", "Scroll of Esther and Hanukkah", "Marriage", "Divorce", "Levirate Marriage and Release", "Virgin Maiden", "Woman Suspected of Infidelity", "Forbidden Intercourse", "Forbidden Foods", "Ritual Slaughter", "Oaths", "Vows", "Nazariteship", "Appraisals and Devoted Property", "Diverse Species", "Gifts to the Poor", "Heave Offerings", "Tithes", "Second Tithes and Fourth Year's Fruit", "First Fruits and other Gifts to Priests Outside the Sanctuary", "Sabbatical Year and the Jubilee", "The Chosen Temple", "Vessels of the Sanctuary and Those who Serve Therein", "Admission into the Sanctuary", "Things Forbidden on the Altar", "Sacrificial Procedure", "Daily Offerings and Additional Offerings", "Sacrifices Rendered Unfit", "Service on the Day of Atonement", "Trespass", "Paschal Offering", "Festival Offering", "Firstlings", "Offerings for Unintentional Transgressions", "Offerings for Those with Incomplete Atonement", "Substitution", "Defilement by a Corpse", "Red Heifer", "Defilement by Leprosy", "Those Who Defile Bed or Seat", "Other Sources of Defilement", "Defilement of Foods", "Vessels", "Immersion Pools", "Damages to Property", "Theft", "Robbery and Lost Property", "One Who Injures a Person or Property", "Murderer and the Preservation of Life", "Sales", "Ownerless Property and Gifts", "Neighbors", "Agents and Partners", "Slaves", "Hiring", "Borrowing and Deposit", "Creditor and Debtor", "Plaintiff and Defendant", "Inheritances", "The Sanhedrin and the Penalties within their Jurisdiction", "Testimony", "Rebels", "Mourning", "Kings and Wars" };
+ static final String[] RAMBAM_NAMES_HEBREW = { "מסירת תורה שבעל פה", "מצוות עשה", "מצוות לא תעשה", "תוכן החיבור", "יסודי התורה", "דעות", "תלמוד תורה", "עבודה זרה וחוקות הגויים", "תשובה", "קריאת שמע", "תפילה וברכת כהנים", "תפילין ומזוזה וספר תורה", "ציצית", "ברכות", "מילה", "סדר התפילה", "שבת", "עירובין", "שביתת עשור", "שביתת יום טוב", "חמץ ומצה", "שופר וסוכה ולולב", "שקלים", "קידוש החודש", "תעניות", "מגילה וחנוכה", "אישות", "גירושין", "יבום וחליצה", "נערה בתולה", "סוטה", "איסורי ביאה", "מאכלות אסורות", "שחיטה", "שבועות", "נדרים", "נזירות", "ערכים וחרמין", "כלאים", "מתנות עניים", "תרומות", "מעשרות", "מעשר שני ונטע רבעי", "ביכורים ושאר מתנות כהונה שבגבולין", "שמיטה ויובל", "בית הבחירה", "כלי המקדש והעובדין בו", "ביאת מקדש", "איסורי המזבח", "מעשה הקרבנות", "תמידים ומוספין", "פסולי המוקדשין", "עבודת יום הכפורים", "מעילה", "קרבן פסח", "חגיגה", "בכורות", "שגגות", "מחוסרי כפרה", "תמורה", "טומאת מת", "פרה אדומה", "טומאת צרעת", "מטמאי משכב ומושב", "שאר אבות הטומאות", "טומאת אוכלים", "כלים", "מקואות", "נזקי ממון", "גניבה", "גזילה ואבידה", "חובל ומזיק", "רוצח ושמירת נפש", "מכירה", "זכייה ומתנה", "שכנים", "שלוחין ושותפין", "עבדים", "שכירות", "שאלה ופיקדון", "מלווה ולווה", "טוען ונטען", "נחלות", "סנהדרין והעונשין המסורין להם", "עדות", "ממרים", "אבל", "מלכים ומלחמות" };
+ static final int[] RAMBAM_CHAPTERS = { 3, 3, 3, 3, 10, 7, 7, 12, 10, 4, 15, 10, 3, 11, 3, 4, 30, 8, 3, 8, 9, 8, 4, 19, 5, 4, 25, 13, 8, 3, 4, 22, 17, 14, 12, 13, 10, 8, 10, 10, 15, 14, 11, 12, 13, 8, 10, 9, 7, 19, 10, 19, 5, 8, 10, 3, 8, 15, 5, 4, 25, 15, 16, 13, 20, 16, 28, 11, 14, 9, 18, 8, 13, 30, 12, 14, 10, 9, 13, 8, 27, 16, 11, 26, 22, 7, 14, 12 };
+
+ static final String[] KITZUR_TISHREI = { "133:17-133:21", "133:22-133:26", "133:27-4:1", "134:2-134:6", "134:7-134:12", "134:13-135:2", "135:3-135:6", "135:7-135:12", "135:13-135:E", "136:1-136:2", "136:3-136:E", "137:1-137:7", "137:8-138:1", "138:2-138:E", "98:1-98:7", "98:8-98:13", "98:14-98:22", "98:33-98:32", "98:33-99:2", "99:3-100:3", "100:5-100:10", "100:11-100:16", "100:17-100:E", "1:1-1:4", "1:5-2:4", "2:5-3:1", "3:2-3:E", "4:1-5:1", "5:2-5:8", "5:9-6:16" };
+ static final String[] KITZUR_CHESHVAN = { "6:17-6:3", "6:4-6:9", "6:10-7:E", "8:1-8:5", "8:6-9:3", "9:4-9:9", "9:10-9:13", "9:14-9:E", "10:1-10:3", "10:4-10:12", "10:13-10:19", "10:20-10:E", "11:1-11:11", "11:12-11:20", "11:21-12:4", "12:5-12:10", "12:11-13:1", "13:2-14:3", "14:4-14:E", "15:1-15:6", "15:7-15:E", "16:1-16:E", "17:1-17:7", "17:8-18:2", "18:3-18:9", "18:10-18:14", "18:15-18:E", "19:1-19:7", "19:8-19:13" };
+ static final String[] KITZUR_KISLEV = { "19:14-20:7", "20:8-21:2", "21:3-21:8", "21:9-22:E", "23:1-23:9", "23:10-23:15", "23:16-23:22", "23:23-23:E", "24:1-24:6", "24:7-24:E", "25:1-26:2", "26:3-26:12", "26:13-26:21", "26:22-27:E", "28:1-28:10", "28:10-29:3", "29:4-29:10", "29:11-29:17", "29:18-30:3", "30:4-31:1", "31:2-32:1", "32:2-32:7", "32:8-32:18", "32:16-32:22", "139:1-139:4", "139:5-139:11", "139:12-139:19", "139:20-139:E", "32:23-32:E", "33:1-33:6" };
+ static final String[] KITZUR_TEVET = { "33:7-33:E", "34:1-34:4", "34:5-34:13", "34:14-35:7", "35:8-36:10", "36:11-36:26", "36:27-37:9", "37:10-38:8", "38:9-39:1", "121:1-121:5", "39:2-40:4", "40:5-40:13", "40:14-40:E", "41:1-41:7", "41:8-42:5", "42:6-42:19", "42:20-43:3", "43:4-44:4", "44:5-44:13", "44:14-45:2", "45:3-45:8", "45:9-45:16", "45:17-46:3", "46:4-46:16", "46:17-46:29", "46:30-46:40", "46:41-47:7", "47:8-47:21", "47:22-48:5" };
+ static final String[] KITZUR_SH_VAT = { "48:6-48:E", "49:1-49:6", "49:7-50:2", "50:3-50:10", "50:11-51:1", "51:2-51:7", "51:8-51:E", "52:1-52:7", "52:8-52:15", "52:16-53:2", "53:3-54:3", "54:4-55:1", "55:2-56:5", "56:6-57:5", "57:6-58:7", "58:8-59:1", "59:2-59:8", "59:9-59:19", "59:20-60:5", "60:6-60:13", "60:14-61:5", "61:6-62:3", "62:4-62:14", "62:15-63:1", "63:2-64:E", "65:1-65:8", "65:9-65:15", "65:16-65:22", "65:23-65:E", "66:1-66:6" };
+ static final String[] KITZUR_ADAR = { "66:7-66:10", "66:11-67:5", "67:6-67:E", "68:1-68:7", "68:8-69:1", "69:2-69:7", "69:8-70:E", "71:1-71:4", "71:5-72:4", "72:5-72:10", "140:1-141:3", "141:4-141:13", "141:14-141:21", "141:22-142:5", "142:6-142:E", "72:11-72:19", "72:20-73:4", "73:5-73:E", "74:1-75:3", "75:4-75:9", "75:10-76:4", "76:5-76:13", "107:1-108:3", "108:4-109:6", "109:7-110:5", "110:6-110:12", "110:13-111:6", "111:7-111:13", "111:14-112:4" };
+ static final String[] KITZUR_NISAN = { "112:5-113:7", "113:8-114:4", "114:5-114:12", "114:13-115:3", "115:4-116:4", "116:5-116:14", "116:15-117:4", "117:5-117:11", "117:12-118:4", "118:5-118:8", "118:9-119:2", "119:3-119:5", "119:6-119:8", "119:9-119:E", "120:1-120:E", "101:1-102:1", "102:2-103:2", "103:3-103:11", "103:12-104:6", "104:7-104:E", "104:1-105:E", "76:14-76:22", "76:23-77:8", "77:9-77:15", "77:16-77:E", "78:1-78:7", "78:8-79:1", "79:2-79:E", "80:1-80:8", "80:9-80:17" };
+ static final String[] KITZUR_IYYAR = { "80:17-80:26", "80:267-80:35", "80:36-80:45", "80:46-80:60", "80:61-80:67", "80:68-80:76", "80:77-80:86", "80:87-81:2", "81:3-82:2", "82:3-82:8", "82:9-83:2", "83:3-84:4", "84:5-84:15", "84:16-85:3", "85:4-86:5", "86:6-87:6", "87:7-87:17", "87:18-88:1", "88:2-88:6", "88:7-88:14", "88:15-89:3", "89:4-90:4", "90:5-90:14", "90:15-91:1", "91:2-91:13", "91:14-92:2", "92:3-92:E", "93:1-94:2", "94:3-94:8" };
+ static final String[] KITZUR_SIVAN = { "94:9-94:19", "94:20-95:1", "95:2-95:11", "95:12-95:E", "96:1-96:5", "96:6-96:14", "96:15-97:9", "97:10-97:E", "143:1-143:9", "143:10-143:18", "143:19-144:6", "144:7-145:6", "145:7-145:20", "145:21-146:E", "147:1-148:E", "149:1-149:11", "149:12-150:5", "150:6-150:13", "150:14-151:5", "151:6-152:7", "152:8-152:E", "153:1-153:9", "153:10-154:1", "154:2-154:E", "155:1-155:6", "155:7-155:E", "156:1-157:3", "157:4-158:E", "159:1-159:6", "159:7-160:5" };
+ static final String[] KITZUR_TAMUZ = { "160:6-161:8", "161:9-161:17", "161:18-162:5", "162:6-162:11", "162:12-163:4", "163:5-164:4", "164:5-165:3", "165:4-165:11", "165:12-166:3", "166:4-167:9", "167:10-168:5", "168:6-171:1", "171:2-173:1", "173:2-175:3", "175:4-176:7", "176:8-177:8", "121:6-121:E", "177:9-178:3", "178:4-179:8", "179:9-180:8", "180:9-181:4", "181:5-181:13", "181:14-182:1", "182:2-182:11", "182:12-183:3", "183:4-184:5", "184:6-185:4", "185:5-187:E", "188:1-189:5" };
+ static final String[] KITZUR_AV = { "189:6-191:E", "122:1-122:6", "122:7-122:11", "122:12-123:2", "123:3-1234:3", "124:4-124:11", "124:12-124:20", "124:21-125:E", "126:1-126:E", "127:1-127:10", "127:11-127:E", "192:1-192:7", "192:8-193:5", "193:6-193:E", "194:1-194:11", "194:12-195:7", "195:8-196:1", "196:2-196:8", "196:9-196:19", "196:20-197:5", "197:6-198:3", "198:4-198:14", "198:15-199:9", "199:10-200:2", "200:3-200:9", "200:10-202:1", "202:2-202:8", "202:9-203:2", "203:3-204:5", "204:6-205:3" };
+ static final String[] KITZUR_ELUL = { "205:4-206:6", "206:7-207:5", "207:6-208:9", "208:10-209:6", "209:7-210:E", "211:1-211:11", "211:12-212:E", "213:1-214:E", "215:1-216:E", "217:1-219:1", "219:2-219:7", "219:8-220:4", "220:5-221:2", "221:3-221:E", "Klalim", "128:1-128:4", "128:5-128:11", "128:12-128:E", "129:1-129:7", "129:8-129:13", "129:14-129:19", "129:20-129:E", "130:1-130:E", "131:1-131:4", "131:5-131:9", "131:10-131:16", "131:17-132:E", "133:1-133:8", "133:9-133:15" };
+ static final String[] KITZUR_ADAR_I = { };
+ static final String[] KITZUR_ADAR_II = { };
+ static final String[] KITZUR_LEAP_OPTION_A = { "1-4", "5-9", "10-14", "15-18", "19-23", "24-28", "29-31", "32-34", "35-E", "Shmita:1-4", "5-7", "8-12", "13-17", "18-21", "22-24", "25-27", "28-32", "33-34:1", "34:2-34:5", "34:6-38", "39-42", "43-46", "47-50", "51-53", "54-46", "57-61", "62-66", "67-70", "71-75" };
+ static final String[] KITZUR_LEAP_OPTION_B = { "6:1-6:4", "6:5-6:7", "6:8-7:E", "14:1-14:8", "15:1-15:6", "15:7-15:E", "16:1-16:E", "11:1-17:7", "17-8:18-2", "18:3-18:9", "18:10-18:14", "18:15-18:E", "19:1-19:7", "19:8-19:E", "43:1-43:E", "44:1-44:11", "44:12-44:E", "50:1-10", "50:11-51:1", "51:2-51:7", "51:8-51:E", "52:1-52:7", "52:8-52:15", "52:16-53:2", "53:3-54:3", "54:4-55:1", "55:2-56-4", "56:5-57:1", "57:2-57:E" };
+
+ private LimudYomiData() { }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/MishnaYomi.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/MishnaYomi.java
new file mode 100644
index 00000000..4eaa8a82
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/MishnaYomi.java
@@ -0,0 +1,88 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+/** An object representing the two mishnayos learned in the Mishna Yomi cycle. */
+public class MishnaYomi {
+ private final int startMasechtaNumber;
+ private final int startChapter;
+ private final int startMishna;
+ private final int endMasechtaNumber;
+ private final int endChapter;
+ private final int endMishna;
+
+ public MishnaYomi(
+ int startMasechtaNumber,
+ int startChapter,
+ int startMishna,
+ int endMasechtaNumber,
+ int endChapter,
+ int endMishna) {
+ this.startMasechtaNumber = startMasechtaNumber;
+ this.startChapter = startChapter;
+ this.startMishna = startMishna;
+ this.endMasechtaNumber = endMasechtaNumber;
+ this.endChapter = endChapter;
+ this.endMishna = endMishna;
+ }
+
+ public int getMasechtaNumber() {
+ return startMasechtaNumber;
+ }
+
+ public int getStartMasechtaNumber() {
+ return startMasechtaNumber;
+ }
+
+ public int getStartChapter() {
+ return startChapter;
+ }
+
+ public int getChapter() {
+ return startChapter;
+ }
+
+ public int getStartMishna() {
+ return startMishna;
+ }
+
+ public int getEndMasechtaNumber() {
+ return endMasechtaNumber;
+ }
+
+ public int getEndChapter() {
+ return endChapter;
+ }
+
+ public int getEndMishna() {
+ return endMishna;
+ }
+
+ public String getMasechtaTransliterated() {
+ return LimudYomiData.MISHNA_NAMES[startMasechtaNumber];
+ }
+
+ public String getMasechta() {
+ return LimudYomiData.MISHNA_NAMES_HEBREW[startMasechtaNumber];
+ }
+
+ public String getEndMasechtaTransliterated() {
+ return LimudYomiData.MISHNA_NAMES[endMasechtaNumber];
+ }
+
+ public String getEndMasechta() {
+ return LimudYomiData.MISHNA_NAMES_HEBREW[endMasechtaNumber];
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/MishnaYomiCalculator.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/MishnaYomiCalculator.java
new file mode 100644
index 00000000..7edfff70
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/MishnaYomiCalculator.java
@@ -0,0 +1,74 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
+
+/**
+ * Calculates Mishna Yomi, the cycle of learning two mishnayos a day. The cycle began on
+ * May 20, 1947 / 1 Sivan 5707 and repeats every 2,096 days. The schedule is calculated offline from
+ * the number of mishnayos in each chapter of Shisha Sidrei Mishna.
+ */
+public class MishnaYomiCalculator {
+ private static final LocalDate START = LocalDate.of(1947, 5, 20);
+ private static final MishnaYomi[] CYCLE = buildCycle();
+
+ public MishnaYomiCalculator() {}
+
+ /**
+ * Returns the Mishna Yomi for the date that the calendar is set to.
+ *
+ * @param calendar the calendar set to the date to calculate
+ * @return the Mishna Yomi reading
+ * @throws IllegalArgumentException if the date is before May 20, 1947, the start of the cycle
+ */
+ public static MishnaYomi getMishnaYomi(JewishCalendar calendar) {
+ LocalDate date = calendar.getLocalDate();
+ if (date.isBefore(START)) {
+ throw new IllegalArgumentException(
+ date + " is prior to the Mishna Yomi cycle that started on " + START);
+ }
+ int day = (int) (ChronoUnit.DAYS.between(START, date) % CYCLE.length);
+ return CYCLE[day];
+ }
+
+ private static MishnaYomi[] buildCycle() {
+ MishnaYomi[] cycle = new MishnaYomi[2096];
+ int day = 0;
+ int firstMasechta = 0;
+ int firstChapter = 1;
+ int firstMishna = 1;
+ boolean haveFirst = false;
+ for (int m = 0; m < LimudYomiData.MISHNA_CHAPTERS.length; m++) {
+ int[] chapters = LimudYomiData.MISHNA_CHAPTERS[m];
+ for (int c = 0; c < chapters.length; c++) {
+ for (int mishnah = 1; mishnah <= chapters[c]; mishnah++) {
+ if (!haveFirst) {
+ firstMasechta = m;
+ firstChapter = c + 1;
+ firstMishna = mishnah;
+ haveFirst = true;
+ } else {
+ cycle[day++] =
+ new MishnaYomi(firstMasechta, firstChapter, firstMishna, m, c + 1, mishnah);
+ haveFirst = false;
+ }
+ }
+ }
+ }
+ return cycle;
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/RambamYomi.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/RambamYomi.java
new file mode 100644
index 00000000..72f575b9
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/RambamYomi.java
@@ -0,0 +1,122 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+/**
+ * An object representing a daily Rambam Mishneh Torah reading. The one chapter cycle generally
+ * contains one reading, while the three chapter cycle may contain multiple collapsed readings when
+ * the daily chapters cross from one section of the Mishneh Torah to another.
+ */
+public class RambamYomi {
+ private final int[] bookNumbers;
+ private final String[] startChapters;
+ private final String[] endChapters;
+
+ public RambamYomi(int bookNumber, int startChapter, int endChapter) {
+ this(bookNumber, String.valueOf(startChapter), String.valueOf(endChapter));
+ }
+
+ public RambamYomi(int bookNumber, String startChapter, String endChapter) {
+ this(new int[] {bookNumber}, new String[] {startChapter}, new String[] {endChapter});
+ }
+
+ public RambamYomi(int[] bookNumbers, String[] startChapters, String[] endChapters) {
+ if (bookNumbers.length == 0
+ || bookNumbers.length != startChapters.length
+ || bookNumbers.length != endChapters.length) {
+ throw new IllegalArgumentException("Rambam readings must have matching non-empty arrays");
+ }
+ this.bookNumbers = bookNumbers.clone();
+ this.startChapters = startChapters.clone();
+ this.endChapters = endChapters.clone();
+ }
+
+ public int getReadingCount() {
+ return bookNumbers.length;
+ }
+
+ public int getBookNumber(int index) {
+ return bookNumbers[index];
+ }
+
+ public String getStartChapter(int index) {
+ return startChapters[index];
+ }
+
+ public String getEndChapter(int index) {
+ return endChapters[index];
+ }
+
+ public int getBookNumber() {
+ return getBookNumber(0);
+ }
+
+ public int getEndBookNumber() {
+ return getBookNumber(bookNumbers.length - 1);
+ }
+
+ public int getStartChapter() {
+ return parseChapter(getStartChapter(0));
+ }
+
+ public int getEndChapter() {
+ return parseChapter(getEndChapter(endChapters.length - 1));
+ }
+
+ public String getStartChapterString() {
+ return getStartChapter(0);
+ }
+
+ public String getEndChapterString() {
+ return getEndChapter(endChapters.length - 1);
+ }
+
+ public String getName() {
+ return getName(0);
+ }
+
+ public String getHebrewName() {
+ return getHebrewName(0);
+ }
+
+ public String getEndName() {
+ return getName(bookNumbers.length - 1);
+ }
+
+ public String getEndHebrewName() {
+ return getHebrewName(bookNumbers.length - 1);
+ }
+
+ public String getName(int index) {
+ return LimudYomiData.RAMBAM_NAMES[bookNumbers[index]];
+ }
+
+ public String getHebrewName(int index) {
+ return LimudYomiData.RAMBAM_NAMES_HEBREW[bookNumbers[index]];
+ }
+
+ private int parseChapter(String chapter) {
+ int dash = chapter.indexOf('-');
+ int colon = chapter.indexOf(':');
+ int end = chapter.length();
+ if (dash >= 0) {
+ end = dash;
+ }
+ if (colon >= 0 && colon < end) {
+ end = colon;
+ }
+ return Integer.parseInt(chapter.substring(0, end));
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/RambamYomiCalculator.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/RambamYomiCalculator.java
new file mode 100644
index 00000000..76e0993c
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/RambamYomiCalculator.java
@@ -0,0 +1,146 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
+
+/**
+ * Calculates the one and three chapter daily Rambam Mishneh Torah cycles that began on April 29,
+ * 1984 / 27 Nisan 5744. The one chapter cycle repeats every 1,017 days and the three chapter cycle
+ * repeats every 339 days. The opening introduction sections and the published special groupings in
+ * Seder Tefilos and Hilchos Chametz U'Matzah are handled offline.
+ */
+public class RambamYomiCalculator {
+ private static final LocalDate START = LocalDate.of(1984, 4, 29);
+ private static final int ONE_CHAPTER_CYCLE = 1017;
+ private static final String[][] FIRST_FOUR_SECTIONS = {
+ {"1-21", "22-33", "34-45"},
+ {"1-83", "84-166", "167-248"},
+ {"1-122", "123-245", "246-365"},
+ {"1:1-4:8", "5:1-9:9", "10:1-14:10"}
+ };
+
+ public RambamYomiCalculator() {}
+
+ /**
+ * Returns the one chapter daily Rambam reading for the date that the calendar is set to.
+ *
+ * @param calendar the calendar set to the date to calculate
+ * @return the one chapter Rambam Yomi reading
+ * @throws IllegalArgumentException if the date is before April 29, 1984, the start of the cycle
+ */
+ public static RambamYomi getRambamYomi(JewishCalendar calendar) {
+ return getRambamYomi1Chapter(calendar);
+ }
+
+ /**
+ * Returns the one chapter daily Rambam reading for the date that the calendar is set to.
+ *
+ * @param calendar the calendar set to the date to calculate
+ * @return the one chapter Rambam Yomi reading
+ * @throws IllegalArgumentException if the date is before April 29, 1984, the start of the cycle
+ */
+ public static RambamYomi getRambamYomi1Chapter(JewishCalendar calendar) {
+ int d = day(calendar, ONE_CHAPTER_CYCLE);
+ RambamYomi reading = chapterAt(d, LimudYomiData.RAMBAM_CHAPTERS);
+ if ("The Order of Prayer".equals(reading.getName())
+ && "4".equals(reading.getStartChapterString())) {
+ return new RambamYomi(reading.getBookNumber(), "4", "5");
+ }
+ return reading;
+ }
+
+ /**
+ * Returns the three chapter daily Rambam reading for the date that the calendar is set to.
+ *
+ * @param calendar the calendar set to the date to calculate
+ * @return the three chapter Rambam Yomi reading, collapsed by adjacent Mishneh Torah section
+ * @throws IllegalArgumentException if the date is before April 29, 1984, the start of the cycle
+ */
+ public static RambamYomi getRambamYomi3Chapters(JewishCalendar calendar) {
+ int d = day(calendar, ONE_CHAPTER_CYCLE / 3) * 3;
+ int[] chapters = LimudYomiData.RAMBAM_CHAPTERS.clone();
+ chapters[15] = 5; // The Order of Prayer has an extra day in the 3-chapter cycle.
+ chapters[20] = 8; // The Haggadah text is combined with chapter 8 of Chametz U'Matzah.
+ RambamYomi[] readings =
+ new RambamYomi[] {
+ chapterAt(d, chapters), chapterAt(d + 1, chapters), chapterAt(d + 2, chapters)
+ };
+ if ("Leavened and Unleavened Bread".equals(readings[0].getName())
+ && "8".equals(readings[0].getStartChapterString())) {
+ readings[0] = new RambamYomi(readings[0].getBookNumber(), "8", "9");
+ }
+ return collapseAdjacent(readings);
+ }
+
+ private static int day(JewishCalendar calendar, int cycle) {
+ LocalDate date = calendar.getLocalDate();
+ if (date.isBefore(START)) {
+ throw new IllegalArgumentException(
+ date + " is prior to the Daily Rambam cycle that started on " + START);
+ }
+ return (int) (ChronoUnit.DAYS.between(START, date) % cycle);
+ }
+
+ private static RambamYomi chapterAt(int index, int[] chapters) {
+ int total = index;
+ for (int i = 0; i < chapters.length; i++) {
+ if (total < chapters[i]) {
+ String chapter =
+ i < FIRST_FOUR_SECTIONS.length
+ ? FIRST_FOUR_SECTIONS[i][total]
+ : String.valueOf(total + 1);
+ return new RambamYomi(i, chapter, chapter);
+ }
+ total -= chapters[i];
+ }
+ throw new IllegalStateException("Unable to calculate Rambam Yomi");
+ }
+
+ private static RambamYomi collapseAdjacent(RambamYomi[] readings) {
+ int count = 0;
+ int[] books = new int[3];
+ String[] starts = new String[3];
+ String[] ends = new String[3];
+ for (RambamYomi reading : readings) {
+ if (count > 0 && books[count - 1] == reading.getBookNumber()) {
+ ends[count - 1] = lastChapterInRange(reading.getEndChapterString());
+ } else {
+ books[count] = reading.getBookNumber();
+ starts[count] = firstChapterInRange(reading.getStartChapterString());
+ ends[count] = lastChapterInRange(reading.getEndChapterString());
+ count++;
+ }
+ }
+ int[] collapsedBooks = new int[count];
+ String[] collapsedStarts = new String[count];
+ String[] collapsedEnds = new String[count];
+ System.arraycopy(books, 0, collapsedBooks, 0, count);
+ System.arraycopy(starts, 0, collapsedStarts, 0, count);
+ System.arraycopy(ends, 0, collapsedEnds, 0, count);
+ return new RambamYomi(collapsedBooks, collapsedStarts, collapsedEnds);
+ }
+
+ private static String firstChapterInRange(String chapter) {
+ int dash = chapter.indexOf('-');
+ return dash < 0 ? chapter : chapter.substring(0, dash);
+ }
+
+ private static String lastChapterInRange(String chapter) {
+ int dash = chapter.lastIndexOf('-');
+ return dash < 0 ? chapter : chapter.substring(dash + 1);
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/ShemirasHaLashonYomi.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/ShemirasHaLashonYomi.java
new file mode 100644
index 00000000..475162af
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/ShemirasHaLashonYomi.java
@@ -0,0 +1,46 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+/** An object representing a Shemiras HaLashon Yomi reading. */
+public class ShemirasHaLashonYomi {
+ private final int book;
+ private final String section;
+ private final String start;
+ private final String end;
+
+ public ShemirasHaLashonYomi(int book, String section, String start, String end) {
+ this.book = book;
+ this.section = section;
+ this.start = start;
+ this.end = end;
+ }
+
+ public int getBook() {
+ return book;
+ }
+
+ public String getSection() {
+ return section;
+ }
+
+ public String getStart() {
+ return start;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/ShemirasHaLashonYomiCalculator.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/ShemirasHaLashonYomiCalculator.java
new file mode 100644
index 00000000..92ba637e
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/ShemirasHaLashonYomiCalculator.java
@@ -0,0 +1,467 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+import java.time.LocalDate;
+
+/**
+ * Calculates the annual Hebrew-date Shemiras HaLashon Yomi schedule. The cycle follows the
+ * published calendar-date schedule for Sefer Shemiras HaLashon and has separate common-year and
+ * leap-year date columns. Short Cheshvan and Kislev years combine the missing 30th day with the
+ * 29th day.
+ */
+public class ShemirasHaLashonYomiCalculator {
+ private static final LocalDate START = LocalDate.of(1876, 2, 16);
+ private static final String[][] SCHEDULE = {
+ {"1", "7", "1", "7", "1", "Hakdamah", "1", "2"},
+ {"2", "7", "2", "7", "1", "Hakdamah", "3", "4"},
+ {"3", "7", "3", "7", "1", "Hakdamah", "5", "6"},
+ {"4", "7", "4", "7", "1", "Hakdamah", "7", "13"},
+ {"5", "7", "5", "7", "1", "Hakdamah", "14", "15"},
+ {"6", "7", "6", "7", "1", "Hakdamah", "16", "16"},
+ {"7", "7", "7", "7", "1", "Hakdamah", "17", "17"},
+ {"8", "7", "8", "7", "1", "Hakdamah", "18", "20"},
+ {"9", "7", "9", "7", "1", "Hakdamah", "21", "22"},
+ {"10", "7", "10", "7", "1", "Hakdamah", "23", "24"},
+ {"11", "7", "11", "7", "1", "Shar Hazechira", "1.1", "1.4"},
+ {"12", "7", "12", "7", "1", "Shar Hazechira", "1.5", "1.6"},
+ {"13", "7", "13", "7", "1", "Shar Hazechira", "1.7", "1.7"},
+ {"14", "7", "14", "7", "1", "Shar Hazechira", "2.1", "2.5"},
+ {"15", "7", "15", "7", "1", "Shar Hazechira", "2.6", "2.8"},
+ {"15", "7", "16", "7", "1", "Shar Hazechira", "2.9", "2.9"},
+ {"16", "7", "17", "7", "1", "Shar Hazechira", "2.10", "2.11"},
+ {"16", "7", "18", "7", "1", "Shar Hazechira", "2.12", "2.12"},
+ {"17", "7", "19", "7", "1", "Shar Hazechira", "2.13", "2.14"},
+ {"18", "7", "20", "7", "1", "Shar Hazechira", "3.1", "3.5"},
+ {"18", "7", "21", "7", "1", "Shar Hazechira", "3.6", "3.6"},
+ {"19", "7", "22", "7", "1", "Shar Hazechira", "3.7", "3.8"},
+ {"20", "7", "23", "7", "1", "Shar Hazechira", "4.1", "4.2"},
+ {"20", "7", "24", "7", "1", "Shar Hazechira", "4.3", "4.4"},
+ {"21", "7", "25", "7", "1", "Shar Hazechira", "4.5", "4.6"},
+ {"22", "7", "26", "7", "1", "Shar Hazechira", "4.7", "4.9"},
+ {"23", "7", "27", "7", "1", "Shar Hazechira", "4.10", "4.16"},
+ {"24", "7", "28", "7", "1", "Shar Hazechira", "4.17", "4.19"},
+ {"25", "7", "29", "7", "1", "Shar Hazechira", "5.1", "5.4"},
+ {"26", "7", "30", "7", "1", "Shar Hazechira", "5.5", "5.6"},
+ {"27", "7", "1", "8", "1", "Shar Hazechira", "5.7", "5.7"},
+ {"27", "7", "2", "8", "1", "Shar Hazechira", "5.8", "5.10"},
+ {"28", "7", "3", "8", "1", "Shar Hazechira", "6.1", "6.4"},
+ {"29", "7", "4", "8", "1", "Shar Hazechira", "6.5", "6.6"},
+ {"29", "7", "5", "8", "1", "Shar Hazechira", "6.7", "6.9"},
+ {"30", "7", "6", "8", "1", "Shar Hazechira", "6.10", "6.10"},
+ {"1", "8", "7", "8", "1", "Shar Hazechira", "7.1", "7.7"},
+ {"2", "8", "8", "8", "1", "Shar Hazechira", "7.8", "7.11"},
+ {"3", "8", "9", "8", "1", "Shar Hazechira", "7.12", "7.15"},
+ {"4", "8", "10", "8", "1", "Shar Hazechira", "7.16", "7.17"},
+ {"5", "8", "11", "8", "1", "Shar Hazechira", "7.18", "7.19"},
+ {"6", "8", "12", "8", "1", "Shar Hazechira", "8.1", "8.4"},
+ {"7", "8", "13", "8", "1", "Shar Hazechira", "8.5", "8.5"},
+ {"7", "8", "14", "8", "1", "Shar Hazechira", "8.6", "8.6"},
+ {"8", "8", "15", "8", "1", "Shar Hazechira", "8.7", "8.9"},
+ {"9", "8", "16", "8", "1", "Shar Hazechira", "8.10", "8.13"},
+ {"10", "8", "17", "8", "1", "Shar Hazechira", "9.1", "9.4"},
+ {"11", "8", "18", "8", "1", "Shar Hazechira", "9.5", "9.5"},
+ {"12", "8", "19", "8", "1", "Shar Hazechira", "9.6", "9.7"},
+ {"13", "8", "20", "8", "1", "Shar Hazechira", "10.1", "10.2"},
+ {"14", "8", "21", "8", "1", "Shar Hazechira", "10.3", "10.3"},
+ {"15", "8", "22", "8", "1", "Shar Hazechira", "10.4", "10.6"},
+ {"16", "8", "23", "8", "1", "Shar Hazechira", "11.1", "11.2"},
+ {"16", "8", "24", "8", "1", "Shar Hazechira", "11.3", "11.6"},
+ {"17", "8", "25", "8", "1", "Shar Hazechira", "11.7", "11.9"},
+ {"18", "8", "26", "8", "1", "Shar Hazechira", "11.10", "11.10"},
+ {"19", "8", "27", "8", "1", "Shar Hazechira", "11.11", "11.11"},
+ {"20", "8", "28", "8", "1", "Shar Hazechira", "11.12", "11.15"},
+ {"21", "8", "29", "8", "1", "Shar Hazechira", "12.1", "12.3"},
+ {"22", "8", "30", "8", "1", "Shar Hazechira", "12.4", "12.4"},
+ {"23", "8", "1", "9", "1", "Shar Hazechira", "12.5", "12.6"},
+ {"24", "8", "2", "9", "1", "Shar Hazechira", "13.1", "13.3"},
+ {"25", "8", "3", "9", "1", "Shar Hazechira", "13.4", "13.4"},
+ {"26", "8", "4", "9", "1", "Shar Hazechira", "13.5", "13.5"},
+ {"27", "8", "5", "9", "1", "Shar Hazechira", "13.6", "13.7"},
+ {"28", "8", "6", "9", "1", "Shar Hazechira", "14.1", "14.2"},
+ {"29", "8", "7", "9", "1", "Shar Hazechira", "14.3", "14.4"},
+ {"30", "8", "8", "9", "1", "Shar Hazechira", "14.5", "14.5"},
+ {"1", "9", "9", "9", "1", "Shar Hazechira", "15.1", "15.3"},
+ {"2", "9", "10", "9", "1", "Shar Hazechira", "15.4", "15.7"},
+ {"3", "9", "11", "9", "1", "Shar Hazechira", "15.8", "15.10"},
+ {"3", "9", "12", "9", "1", "Shar Hazechira", "15.11", "15.11"},
+ {"4", "9", "13", "9", "1", "Shar Hazechira", "15.12", "15.15"},
+ {"5", "9", "14", "9", "1", "Shar Hazechira", "16.1", "16.2"},
+ {"6", "9", "15", "9", "1", "Shar Hazechira", "16.3", "16.4"},
+ {"7", "9", "16", "9", "1", "Shar Hazechira", "16.5", "16.5"},
+ {"8", "9", "17", "9", "1", "Shar Hazechira", "16.6", "16.6"},
+ {"9", "9", "18", "9", "1", "Shar Hazechira", "16.7", "16.7"},
+ {"10", "9", "19", "9", "1", "Shar Hazechira", "17.1", "17.2"},
+ {"10", "9", "20", "9", "1", "Shar Hazechira", "17.3", "17.3"},
+ {"11", "9", "21", "9", "1", "Shar Hazechira", "17.4", "17.6"},
+ {"12", "9", "22", "9", "1", "Shar Hazechira", "17.7", "17.7"},
+ {"13", "9", "23", "9", "1", "Shar Hatvuna", "1.1", "1.2"},
+ {"14", "9", "24", "9", "1", "Shar Hatvuna", "1.3", "1.3"},
+ {"15", "9", "25", "9", "1", "Shar Hatvuna", "1.4", "1.4"},
+ {"16", "9", "26", "9", "1", "Shar Hatvuna", "2.1", "2.2"},
+ {"17", "9", "27", "9", "1", "Shar Hatvuna", "2.3", "2.3"},
+ {"18", "9", "28", "9", "1", "Shar Hatvuna", "2.4", "2.4"},
+ {"19", "9", "29", "9", "1", "Shar Hatvuna", "2.5", "2.5"},
+ {"20", "9", "30", "9", "1", "Shar Hatvuna", "2.6", "2.10"},
+ {"21", "9", "1", "10", "1", "Shar Hatvuna", "3.1", "3.2"},
+ {"22", "9", "2", "10", "1", "Shar Hatvuna", "3.3", "3.3"},
+ {"23", "9", "3", "10", "1", "Shar Hatvuna", "3.4", "3.5"},
+ {"24", "9", "4", "10", "1", "Shar Hatvuna", "3.6", "3.6"},
+ {"25", "9", "5", "10", "1", "Shar Hatvuna", "3.7", "3.8"},
+ {"26", "9", "6", "10", "1", "Shar Hatvuna", "4.1", "4.3"},
+ {"27", "9", "7", "10", "1", "Shar Hatvuna", "4.4", "4.4"},
+ {"28", "9", "8", "10", "1", "Shar Hatvuna", "4.5", "4.6"},
+ {"29", "9", "9", "10", "1", "Shar Hatvuna", "5.1", "5.2"},
+ {"30", "9", "10", "10", "1", "Shar Hatvuna", "5.3", "5.4"},
+ {"1", "10", "11", "10", "1", "Shar Hatvuna", "5.5", "5.6"},
+ {"2", "10", "12", "10", "1", "Shar Hatvuna", "6.1", "6.5"},
+ {"3", "10", "13", "10", "1", "Shar Hatvuna", "6.6", "6.6"},
+ {"4", "10", "14", "10", "1", "Shar Hatvuna", "6.7", "6.8"},
+ {"5", "10", "15", "10", "1", "Shar Hatvuna", "6.9", "6.13"},
+ {"6", "10", "16", "10", "1", "Shar Hatvuna", "7.1", "7.2"},
+ {"7", "10", "17", "10", "1", "Shar Hatvuna", "7.3", "7.5"},
+ {"8", "10", "18", "10", "1", "Shar Hatvuna", "7.6", "7.9"},
+ {"9", "10", "19", "10", "1", "Shar Hatvuna", "7.10", "7.11"},
+ {"10", "10", "20", "10", "1", "Shar Hatvuna", "7.12", "7.12"},
+ {"11", "10", "21", "10", "1", "Shar Hatvuna", "8.1", "8.3"},
+ {"12", "10", "22", "10", "1", "Shar Hatvuna", "8.4", "8.5"},
+ {"13", "10", "23", "10", "1", "Shar Hatvuna", "8.6", "8.7"},
+ {"14", "10", "24", "10", "1", "Shar Hatvuna", "8.8", "8.9"},
+ {"15", "10", "25", "10", "1", "Shar Hatvuna", "8.10", "8.12"},
+ {"16", "10", "26", "10", "1", "Shar Hatvuna", "8.13", "8.13"},
+ {"17", "10", "27", "10", "1", "Shar Hatvuna", "9.1", "9.2"},
+ {"18", "10", "28", "10", "1", "Shar Hatvuna", "9.3", "9.3"},
+ {"19", "10", "29", "10", "1", "Shar Hatvuna", "9.4", "9.4"},
+ {"20", "10", "1", "11", "1", "Shar Hatvuna", "9.5", "9.6"},
+ {"21", "10", "2", "11", "1", "Shar Hatvuna", "10.1", "10.3"},
+ {"22", "10", "3", "11", "1", "Shar Hatvuna", "10.4", "10.4"},
+ {"23", "10", "4", "11", "1", "Shar Hatvuna", "10.5", "10.5"},
+ {"24", "10", "5", "11", "1", "Shar Hatvuna", "10.6", "10.6"},
+ {"25", "10", "6", "11", "1", "Shar Hatvuna", "11.1", "11.2"},
+ {"26", "10", "7", "11", "1", "Shar Hatvuna", "11.3", "11.4"},
+ {"27", "10", "8", "11", "1", "Shar Hatvuna", "11.5", "11.7"},
+ {"28", "10", "9", "11", "1", "Shar Hatvuna", "12.1", "12.2"},
+ {"29", "10", "10", "11", "1", "Shar Hatvuna", "12.3", "12.3"},
+ {"1", "11", "11", "11", "1", "Shar Hatvuna", "12.4", "12.4"},
+ {"2", "11", "12", "11", "1", "Shar Hatvuna", "12.5", "12.6"},
+ {"3", "11", "13", "11", "1", "Shar Hatvuna", "13.1", "13.2"},
+ {"4", "11", "14", "11", "1", "Shar Hatvuna", "13.3", "13.4"},
+ {"5", "11", "15", "11", "1", "Shar Hatvuna", "13.5", "13.5"},
+ {"5", "11", "16", "11", "1", "Shar Hatvuna", "13.6", "13.6"},
+ {"6", "11", "17", "11", "1", "Shar Hatvuna", "13.7", "13.8"},
+ {"7", "11", "18", "11", "1", "Shar Hatvuna", "13.9", "13.9"},
+ {"8", "11", "19", "11", "1", "Shar Hatvuna", "13.10", "13.10"},
+ {"9", "11", "20", "11", "1", "Shar Hatvuna", "13.11", "13.13"},
+ {"10", "11", "21", "11", "1", "Shar Hatvuna", "14.1", "14.3"},
+ {"11", "11", "22", "11", "1", "Shar Hatvuna", "14.4", "14.4"},
+ {"12", "11", "23", "11", "1", "Shar Hatvuna", "14.5", "14.6"},
+ {"13", "11", "24", "11", "1", "Shar Hatvuna", "14.7", "14.8"},
+ {"14", "11", "25", "11", "1", "Shar Hatvuna", "15.1", "15.3"},
+ {"15", "11", "26", "11", "1", "Shar Hatvuna", "15.4", "15.5"},
+ {"16", "11", "27", "11", "1", "Shar Hatvuna", "15.6", "15.6"},
+ {"17", "11", "28", "11", "1", "Shar Hatvuna", "16.1", "16.3"},
+ {"18", "11", "29", "11", "1", "Shar Hatvuna", "16.4", "16.8"},
+ {"19", "11", "30", "11", "1", "Shar Hatvuna", "16.9", "16.11"},
+ {"20", "11", "1", "12", "1", "Shar Hatvuna", "16.12", "16.12"},
+ {"21", "11", "2", "12", "1", "Shar Hatvuna", "16.13", "16.13"},
+ {"22", "11", "3", "12", "1", "Shar Hatvuna", "16.14", "16.15"},
+ {"23", "11", "4", "12", "1", "Shar Hatvuna", "17.1", "17.4"},
+ {"23", "11", "5", "12", "1", "Shar Hatvuna", "17.5", "17.6"},
+ {"24", "11", "6", "12", "1", "Shar Hatvuna", "17.7", "17.9"},
+ {"25", "11", "7", "12", "1", "Shar Hatvuna", "17.10", "17.10"},
+ {"26", "11", "8", "12", "1", "Shar Hatvuna", "17.11", "17.12"},
+ {"27", "11", "9", "12", "1", "Shar Hatorah", "1.1", "1.3"},
+ {"28", "11", "10", "12", "1", "Shar Hatorah", "1.4", "1.4"},
+ {"29", "11", "11", "12", "1", "Shar Hatorah", "1.5", "1.7"},
+ {"30", "11", "12", "12", "1", "Shar Hatorah", "1.8", "1.9"},
+ {"1", "12", "13", "12", "1", "Shar Hatorah", "1.10", "1.10"},
+ {"2", "12", "14", "12", "1", "Shar Hatorah", "1.11", "1.12"},
+ {"3", "12", "15", "12", "1", "Shar Hatorah", "1.13", "1.13"},
+ {"4", "12", "16", "12", "1", "Shar Hatorah", "1.14", "1.16"},
+ {"5", "12", "17", "12", "1", "Shar Hatorah", "2.1", "2.3"},
+ {"6", "12", "18", "12", "1", "Shar Hatorah", "2.4", "2.9"},
+ {"7", "12", "19", "12", "1", "Shar Hatorah", "2.10", "2.10"},
+ {"8", "12", "20", "12", "1", "Shar Hatorah", "2.11", "2.11"},
+ {"9", "12", "21", "12", "1", "Shar Hatorah", "2.12", "2.16"},
+ {"10", "12", "22", "12", "1", "Shar Hatorah", "2.17", "2.19"},
+ {"10", "12", "23", "12", "1", "Shar Hatorah", "2.20", "2.23"},
+ {"11", "12", "24", "12", "1", "Shar Hatorah", "2.24", "2.25"},
+ {"11", "12", "25", "12", "1", "Shar Hatorah", "2.26", "2.27"},
+ {"12", "12", "26", "12", "1", "Shar Hatorah", "3.1", "3.3"},
+ {"13", "12", "27", "12", "1", "Shar Hatorah", "3.4", "3.6"},
+ {"13", "12", "28", "12", "1", "Shar Hatorah", "3.7", "3.7"},
+ {"14", "12", "29", "12", "1", "Shar Hatorah", "3.8", "3.8"},
+ {"15", "12", "30", "12", "1", "Shar Hatorah", "3.9", "3.12"},
+ {"16", "12", "1", "13", "1", "Shar Hatorah", "3.13", "3.14"},
+ {"17", "12", "2", "13", "1", "Shar Hatorah", "3.15", "3.15"},
+ {"18", "12", "3", "13", "1", "Shar Hatorah", "3.16", "3.19"},
+ {"19", "12", "4", "13", "1", "Shar Hatorah", "4.1", "4.3"},
+ {"20", "12", "5", "13", "1", "Shar Hatorah", "4.4", "4.5"},
+ {"21", "12", "6", "13", "1", "Shar Hatorah", "4.6", "4.7"},
+ {"22", "12", "7", "13", "1", "Shar Hatorah", "4.8", "4.11"},
+ {"23", "12", "8", "13", "1", "Shar Hatorah", "4.12", "4.16"},
+ {"24", "12", "9", "13", "1", "Shar Hatorah", "4.17", "4.19"},
+ {"25", "12", "10", "13", "1", "Shar Hatorah", "4.20", "4.25"},
+ {"26", "12", "11", "13", "1", "Shar Hatorah", "4.26", "4.26"},
+ {"27", "12", "12", "13", "1", "Shar Hatorah", "4.27", "4.29"},
+ {"28", "12", "13", "13", "1", "Shar Hatorah", "5.1", "5.2"},
+ {"29", "12", "14", "13", "1", "Shar Hatorah", "5.3", "5.4"},
+ {"1", "1", "15", "13", "1", "Shar Hatorah", "5.5", "5.5"},
+ {"2", "1", "16", "13", "1", "Shar Hatorah", "5.6", "5.8"},
+ {"3", "1", "17", "13", "1", "Shar Hatorah", "5.9", "5.11"},
+ {"4", "1", "18", "13", "1", "Shar Hatorah", "5.12", "5.13"},
+ {"5", "1", "19", "13", "1", "Shar Hatorah", "5.14", "5.15"},
+ {"6", "1", "20", "13", "1", "Shar Hatorah", "5.16", "5.17"},
+ {"7", "1", "21", "13", "1", "Shar Hatorah", "6.1", "6.3"},
+ {"8", "1", "22", "13", "1", "Shar Hatorah", "6.4", "6.5"},
+ {"9", "1", "23", "13", "1", "Shar Hatorah", "6.6", "6.9"},
+ {"10", "1", "24", "13", "1", "Shar Hatorah", "6.10", "6.14"},
+ {"11", "1", "25", "13", "1", "Shar Hatorah", "6.15", "6.16"},
+ {"12", "1", "26", "13", "1", "Shar Hatorah", "7.1", "7.2"},
+ {"13", "1", "27", "13", "1", "Shar Hatorah", "7.3", "7.4"},
+ {"14", "1", "28", "13", "1", "Shar Hatorah", "7.5", "7.6"},
+ {"15", "1", "29", "13", "1", "Shar Hatorah", "7.7", "7.8"},
+ {"16", "1", "1", "1", "1", "Shar Hatorah", "7.9", "7.9"},
+ {"17", "1", "2", "1", "1", "Shar Hatorah", "7.10", "7.11"},
+ {"18", "1", "3", "1", "1", "Shar Hatorah", "7.12", "7.14"},
+ {"19", "1", "4", "1", "1", "Shar Hatorah", "7.15", "7.17"},
+ {"20", "1", "5", "1", "1", "Shar Hatorah", "7.18", "7.18"},
+ {"21", "1", "6", "1", "1", "Shar Hatorah", "7.19", "7.19"},
+ {"22", "1", "7", "1", "1", "Shar Hatorah", "8.1", "8.3"},
+ {"23", "1", "8", "1", "1", "Shar Hatorah", "8.4", "8.4"},
+ {"24", "1", "9", "1", "1", "Shar Hatorah", "8.5", "8.6"},
+ {"25", "1", "10", "1", "1", "Shar Hatorah", "8.7", "8.7"},
+ {"26", "1", "11", "1", "1", "Shar Hatorah", "8.8", "8.8"},
+ {"27", "1", "12", "1", "1", "Shar Hatorah", "8.9", "8.10"},
+ {"28", "1", "13", "1", "1", "Shar Hatorah", "9.1", "9.5"},
+ {"29", "1", "14", "1", "1", "Shar Hatorah", "9.6", "9.7"},
+ {"30", "1", "15", "1", "1", "Shar Hatorah", "9.8", "9.11"},
+ {"1", "2", "16", "1", "1", "Shar Hatorah", "9.12", "9.12"},
+ {"2", "2", "17", "1", "1", "Shar Hatorah", "9.13", "9.14"},
+ {"3", "2", "18", "1", "1", "Shar Hatorah", "9.15", "9.17"},
+ {"4", "2", "19", "1", "1", "Shar Hatorah", "10.1", "10.4"},
+ {"5", "2", "20", "1", "1", "Shar Hatorah", "10.5", "10.7"},
+ {"6", "2", "21", "1", "1", "Shar Hatorah", "10.8", "10.9"},
+ {"7", "2", "22", "1", "1", "Shar Hatorah", "10.10", "10.11"},
+ {"8", "2", "23", "1", "1", "Chasimas Hasefer", "1.1", "1.4"},
+ {"9", "2", "24", "1", "1", "Chasimas Hasefer", "1.5", "1.5"},
+ {"10", "2", "25", "1", "1", "Chasimas Hasefer", "2.1", "2.4"},
+ {"11", "2", "26", "1", "1", "Chasimas Hasefer", "2.5", "2.5"},
+ {"12", "2", "27", "1", "1", "Chasimas Hasefer", "3.1", "3.2"},
+ {"13", "2", "28", "1", "1", "Chasimas Hasefer", "3.3", "3.4"},
+ {"14", "2", "29", "1", "1", "Chasimas Hasefer", "3.5", "3.5"},
+ {"15", "2", "30", "1", "1", "Chasimas Hasefer", "3.6", "3.6"},
+ {"16", "2", "1", "2", "1", "Chasimas Hasefer", "4.1", "4.3"},
+ {"17", "2", "2", "2", "1", "Chasimas Hasefer", "4.4", "4.5"},
+ {"18", "2", "3", "2", "1", "Chasimas Hasefer", "4.6", "4.8"},
+ {"19", "2", "4", "2", "1", "Chasimas Hasefer", "5.1", "5.3"},
+ {"20", "2", "5", "2", "1", "Chasimas Hasefer", "6.1", "6.2"},
+ {"21", "2", "6", "2", "1", "Chasimas Hasefer", "6.3", "6.4"},
+ {"22", "2", "7", "2", "1", "Chasimas Hasefer", "6.5", "6.6"},
+ {"23", "2", "8", "2", "1", "Chasimas Hasefer", "6.7", "6.9"},
+ {"24", "2", "9", "2", "1", "Chasimas Hasefer", "6.10", "6.11"},
+ {"25", "2", "10", "2", "1", "Chasimas Hasefer", "7.1", "7.5"},
+ {"26", "2", "11", "2", "1", "Chasimas Hasefer", "7.6", "7.6"},
+ {"27", "2", "12", "2", "1", "Chasimas Hasefer", "7.7", "7.8"},
+ {"28", "2", "13", "2", "1", "Chasimas Hasefer", "7.9", "7.9"},
+ {"29", "2", "14", "2", "1", "Chasimas Hasefer", "7.10", "7.10"},
+ {"1", "3", "15", "2", "1", "Chasimas Hasefer", "7.11", "7.11"},
+ {"2", "3", "16", "2", "1", "Chasimas Hasefer", "7.12", "7.13"},
+ {"3", "3", "17", "2", "2", "x", "1.1", "1.2"},
+ {"4", "3", "18", "2", "2", "x", "1.3", "1.5"},
+ {"5", "3", "19", "2", "2", "x", "1.6", "1.7"},
+ {"6", "3", "20", "2", "2", "x", "1.8", "1.8"},
+ {"7", "3", "21", "2", "2", "x", "2.1", "2.4"},
+ {"8", "3", "22", "2", "2", "x", "2.5", "2.6"},
+ {"9", "3", "23", "2", "2", "x", "2.7", "2.7"},
+ {"10", "3", "24", "2", "2", "x", "2.8", "2.8"},
+ {"10", "3", "25", "2", "2", "x", "2.9", "2.9"},
+ {"11", "3", "26", "2", "2", "x", "2.10", "2.10"},
+ {"12", "3", "27", "2", "2", "x", "2.11", "2.11"},
+ {"13", "3", "28", "2", "2", "x", "3.1", "3.2"},
+ {"14", "3", "29", "2", "2", "x", "3.3", "3.4"},
+ {"15", "3", "1", "3", "2", "x", "3.5", "3.6"},
+ {"16", "3", "2", "3", "2", "x", "3.7", "3.7"},
+ {"17", "3", "3", "3", "2", "x", "4.1", "4.5"},
+ {"18", "3", "4", "3", "2", "x", "4.6", "4.7"},
+ {"19", "3", "5", "3", "2", "x", "5.1", "5.3"},
+ {"20", "3", "6", "3", "2", "x", "5.4", "5.5"},
+ {"21", "3", "7", "3", "2", "x", "5.6", "5.7"},
+ {"22", "3", "8", "3", "2", "x", "6.1", "6.3"},
+ {"23", "3", "9", "3", "2", "x", "6.4", "6.5"},
+ {"24", "3", "10", "3", "2", "x", "7.1", "7.3"},
+ {"25", "3", "11", "3", "2", "x", "7.4", "7.4"},
+ {"25", "3", "12", "3", "2", "x", "7.5", "7.6"},
+ {"26", "3", "13", "3", "2", "x", "7.7", "7.9"},
+ {"27", "3", "14", "3", "2", "x", "8.1", "8.3"},
+ {"28", "3", "15", "3", "2", "x", "8.4", "8.5"},
+ {"29", "3", "16", "3", "2", "x", "8.6", "8.7"},
+ {"30", "3", "17", "3", "2", "x", "8.8", "8.8"},
+ {"1", "4", "18", "3", "2", "x", "9.1", "9.5"},
+ {"2", "4", "19", "3", "2", "x", "9.6", "9.7"},
+ {"3", "4", "20", "3", "2", "x", "9.8", "9.10"},
+ {"4", "4", "21", "3", "2", "x", "10.1", "10.4"},
+ {"5", "4", "22", "3", "2", "x", "11.1", "11.3"},
+ {"5", "4", "23", "3", "2", "x", "11.4", "11.6"},
+ {"6", "4", "24", "3", "2", "x", "11.7", "11.8"},
+ {"7", "4", "25", "3", "2", "x", "11.9", "11.10"},
+ {"8", "4", "26", "3", "2", "x", "11.11", "11.12"},
+ {"9", "4", "27", "3", "2", "x", "11.13", "11.13"},
+ {"10", "4", "28", "3", "2", "x", "11.14", "11.17"},
+ {"11", "4", "29", "3", "2", "x", "11.18", "11.19"},
+ {"12", "4", "30", "3", "2", "x", "11.20", "11.21"},
+ {"13", "4", "1", "4", "2", "x", "11.22", "11.25"},
+ {"14", "4", "2", "4", "2", "x", "12.1", "12.3"},
+ {"15", "4", "3", "4", "2", "x", "12.4", "12.4"},
+ {"16", "4", "4", "4", "2", "x", "12.5", "12.5"},
+ {"17", "4", "5", "4", "2", "x", "12.6", "12.6"},
+ {"18", "4", "6", "4", "2", "x", "12.7", "12.7"},
+ {"18", "4", "7", "4", "2", "x", "12.8", "12.8"},
+ {"19", "4", "8", "4", "2", "x", "12.9", "12.10"},
+ {"19", "4", "9", "4", "2", "x", "12.11", "12.11"},
+ {"20", "4", "10", "4", "2", "x", "13.1", "13.4"},
+ {"21", "4", "11", "4", "2", "x", "13.5", "13.7"},
+ {"22", "4", "12", "4", "2", "x", "13.8", "13.13"},
+ {"23", "4", "13", "4", "2", "x", "14.1", "14.4"},
+ {"24", "4", "14", "4", "2", "x", "14.5", "14.7"},
+ {"25", "4", "15", "4", "2", "x", "15.1", "15.3"},
+ {"26", "4", "16", "4", "2", "x", "15.4", "15.6"},
+ {"27", "4", "17", "4", "2", "x", "15.7", "15.8"},
+ {"28", "4", "18", "4", "2", "x", "16.1", "16.4"},
+ {"29", "4", "19", "4", "2", "x", "16.5", "16.5"},
+ {"29", "4", "20", "4", "2", "x", "16.6", "16.10"},
+ {"1", "5", "21", "4", "2", "x", "16.11", "16.12"},
+ {"2", "5", "22", "4", "2", "x", "16.13", "16.13"},
+ {"3", "5", "23", "4", "2", "x", "16.14", "16.14"},
+ {"3", "5", "24", "4", "2", "x", "16.15", "16.15"},
+ {"4", "5", "25", "4", "2", "x", "17.1", "17.2"},
+ {"5", "5", "26", "4", "2", "x", "17.3", "17.3"},
+ {"6", "5", "27", "4", "2", "x", "17.4", "17.4"},
+ {"6", "5", "28", "4", "2", "x", "17.5", "17.5"},
+ {"7", "5", "29", "4", "2", "x", "18.1", "18.7"},
+ {"8", "5", "1", "5", "2", "x", "19.1", "19.2"},
+ {"9", "5", "2", "5", "2", "x", "19.3", "19.4"},
+ {"10", "5", "3", "5", "2", "x", "19.5", "19.6"},
+ {"11", "5", "4", "5", "2", "x", "19.7", "19.8"},
+ {"12", "5", "5", "5", "2", "x", "19.9", "19.10"},
+ {"13", "5", "6", "5", "2", "x", "19.11", "19.12"},
+ {"14", "5", "7", "5", "2", "x", "19.Footnote_in_11", "19.Footnote_in_11"},
+ {"15", "5", "8", "5", "2", "x", "19.12", "19.14"},
+ {"15", "5", "9", "5", "2", "x", "19.15", "19.15"},
+ {"16", "5", "10", "5", "2", "x", "20.1", "20.4"},
+ {"17", "5", "11", "5", "2", "x", "20.5", "20.6"},
+ {"18", "5", "12", "5", "2", "x", "21.1", "21.4"},
+ {"19", "5", "13", "5", "2", "x", "21.5", "21.10"},
+ {"20", "5", "14", "5", "2", "x", "21.11", "21.13"},
+ {"21", "5", "15", "5", "2", "x", "21.14", "21.14"},
+ {"22", "5", "16", "5", "2", "x", "21.15", "21.15"},
+ {"23", "5", "17", "5", "2", "x", "22.1", "22.3"},
+ {"24", "5", "18", "5", "2", "x", "22.4", "22.4"},
+ {"25", "5", "19", "5", "2", "x", "22.5", "22.6"},
+ {"26", "5", "20", "5", "2", "x", "23.1", "23.2"},
+ {"27", "5", "21", "5", "2", "x", "23.3", "23.3"},
+ {"27", "5", "22", "5", "2", "x", "23.4", "23.5"},
+ {"28", "5", "23", "5", "2", "x", "24.1", "24.3"},
+ {"29", "5", "24", "5", "2", "x", "25.1", "25.3"},
+ {"30", "5", "25", "5", "2", "x", "26.1", "26.4"},
+ {"1", "6", "26", "5", "2", "x", "26.5", "26.5"},
+ {"2", "6", "27", "5", "2", "x", "26.6", "26.11"},
+ {"3", "6", "28", "5", "2", "x", "27.1", "27.2"},
+ {"4", "6", "29", "5", "2", "x", "27.3", "27.3"},
+ {"4", "6", "30", "5", "2", "x", "27.4", "27.4"},
+ {"5", "6", "1", "6", "2", "x", "27.5", "27.5"},
+ {"6", "6", "2", "6", "2", "x", "27.6", "27.7"},
+ {"7", "6", "3", "6", "2", "x", "28.1", "28.2"},
+ {"8", "6", "4", "6", "2", "x", "28.3", "28.3"},
+ {"9", "6", "5", "6", "2", "x", "29.1", "29.8"},
+ {"10", "6", "6", "6", "2", "x", "29.9", "29.13"},
+ {"11", "6", "7", "6", "2", "x", "29.14", "29.16"},
+ {"12", "6", "8", "6", "2", "x", "29.17", "29.17"},
+ {"13", "6", "9", "6", "2", "x", "29.18", "29.20"},
+ {"14", "6", "10", "6", "2", "x", "30.1", "30.5"},
+ {"15", "6", "11", "6", "2", "x", "30.6", "30.9"},
+ {"16", "6", "12", "6", "2", "x", "30.10", "30.12"},
+ {"17", "6", "13", "6", "2", "x", "30.13", "30.14"},
+ {"18", "6", "14", "6", "2", "x", "30.15", "30.16"},
+ {"19", "6", "15", "6", "2", "x", "30.17", "30.17"},
+ {"19", "6", "16", "6", "2", "x", "30.18", "30.20"},
+ {"20", "6", "17", "6", "2", "Chasimas Hasefer", "1.1", "1.2"},
+ {"21", "6", "18", "6", "2", "Chasimas Hasefer", "1.3", "1.3"},
+ {"22", "6", "19", "6", "2", "Chasimas Hasefer", "1.4", "1.6"},
+ {"23", "6", "20", "6", "2", "Chasimas Hasefer", "1.7", "1.7"},
+ {"23", "6", "21", "6", "2", "Chasimas Hasefer", "1.8", "1.8"},
+ {"24", "6", "22", "6", "2", "Chasimas Hasefer", "1.9", "1.12"},
+ {"25", "6", "23", "6", "2", "Chasimas Hasefer", "1.13", "1.16"},
+ {"26", "6", "24", "6", "2", "Chasimas Hasefer", "1.17", "1.17"},
+ {"26", "6", "25", "6", "2", "Chasimas Hasefer", "1.18", "1.18"},
+ {"26", "6", "26", "6", "2", "Chasimas Hasefer", "1.19", "1.19"},
+ {"27", "6", "27", "6", "2", "Chasimas Hasefer", "2.1", "2.2"},
+ {"28", "6", "28", "6", "2", "Chasimas Hasefer", "3.1", "3.4"},
+ {"29", "6", "29", "6", "2", "Chasimas Hasefer", "4.1", "4.2"},
+ };
+
+ public ShemirasHaLashonYomiCalculator() {}
+
+ /**
+ * Returns the Shemiras HaLashon Yomi reading for the date that the calendar is set to.
+ *
+ * @param calendar the calendar set to the date to calculate
+ * @return the Shemiras HaLashon Yomi reading
+ * @throws IllegalArgumentException if the date is before February 16, 1876, the start of the
+ * cycle
+ */
+ public static ShemirasHaLashonYomi getShemirasHaLashonYomi(JewishCalendar calendar) {
+ if (calendar.getLocalDate().isBefore(START)) {
+ throw new IllegalArgumentException(
+ calendar.getLocalDate()
+ + " is prior to the Shemiras HaLashon cycle that started on "
+ + START);
+ }
+ ShemirasHaLashonYomi result =
+ lookup(
+ calendar.getJewishDayOfMonth(), calendar.getJewishMonth(), calendar.isJewishLeapYear());
+ if (calendar.getJewishDayOfMonth() == 29
+ && ((calendar.getJewishMonth() == JewishCalendar.KISLEV
+ || calendar.getJewishMonth() == JewishCalendar.CHESHVAN)
+ && calendar.getDaysInJewishMonth() == 29)) {
+ ShemirasHaLashonYomi extra =
+ lookup(30, calendar.getJewishMonth(), calendar.isJewishLeapYear());
+ if (extra != null && result != null) {
+ result =
+ new ShemirasHaLashonYomi(
+ result.getBook(), result.getSection(), result.getStart(), extra.getEnd());
+ }
+ }
+ return result;
+ }
+
+ private static ShemirasHaLashonYomi lookup(int day, int month, boolean leapYear) {
+ ShemirasHaLashonYomi result = null;
+ for (String[] r : SCHEDULE) {
+ int d = Integer.parseInt(r[leapYear ? 2 : 0]);
+ int m = Integer.parseInt(r[leapYear ? 3 : 1]);
+ if (d == day && m == month) {
+ if (result == null) {
+ result = new ShemirasHaLashonYomi(Integer.parseInt(r[4]), r[5], r[6], r[7]);
+ } else {
+ result =
+ new ShemirasHaLashonYomi(
+ result.getBook(), result.getSection(), result.getStart(), r[7]);
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TanachYomi.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TanachYomi.java
new file mode 100644
index 00000000..dd0fa7f0
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TanachYomi.java
@@ -0,0 +1,40 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+/** An object representing a Tanach Yomi seder. */
+public class TanachYomi {
+ private final String book;
+ private final String hebrewBook;
+ private final String seder;
+
+ public TanachYomi(String book, String hebrewBook, String seder) {
+ this.book = book;
+ this.hebrewBook = hebrewBook;
+ this.seder = seder;
+ }
+
+ public String getBook() {
+ return book;
+ }
+
+ public String getHebrewBook() {
+ return hebrewBook;
+ }
+
+ public String getSeder() {
+ return seder;
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TanachYomiCalculator.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TanachYomiCalculator.java
new file mode 100644
index 00000000..83eadf9b
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TanachYomiCalculator.java
@@ -0,0 +1,213 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+import java.time.LocalDate;
+
+/**
+ * Calculates Tanach Yomi according to the annual Masoretic seder cycle that began on October 26,
+ * 1948 / 23 Tishrei 5709. The cycle starts each year on 23 Tishrei and skips Shabbos and selected
+ * Jewish holidays. It returns {@code null} on skipped days.
+ */
+public class TanachYomiCalculator {
+ private static final LocalDate START = LocalDate.of(1948, 10, 26);
+ private static final String JOSHUA = "Joshua";
+ private static final String JEREMIAH = "Jeremiah";
+ private static final String RUTH = "Ruth";
+ private static final String SHIR_HASHIRIM = "Song of Songs";
+ private static final String[] BOOKS = {
+ JOSHUA,
+ "Judges",
+ "Samuel",
+ "Kings",
+ "Isaiah",
+ JEREMIAH,
+ "Ezekiel",
+ "Minor Prophets",
+ "Psalms",
+ "Proverbs",
+ "Job",
+ SHIR_HASHIRIM,
+ RUTH,
+ "Lamentations",
+ "Ecclesiastes",
+ "Esther",
+ "Daniel",
+ "Ezra and Nehemiah",
+ "Chronicles",
+ "Chronicles"
+ };
+ private static final String[] HEBREW_BOOKS = {
+ "יהושע",
+ "שופטים",
+ "שמואל",
+ "מלכים",
+ "ישעיהו",
+ "ירמיהו",
+ "יחזקאל",
+ "תרי עשר",
+ "תהלים",
+ "משלי",
+ "איוב",
+ "שיר השירים",
+ "רות",
+ "איכה",
+ "קהלת",
+ "אסתר",
+ "דניאל",
+ "עזרא ונחמיה",
+ "דברי הימים",
+ "דברי הימים"
+ };
+ private static final int[] BLATT = {
+ 14, 14, 34, 35, 26, 31, 29, 21, 19, 8, 8, 1, 1, 1, 4, 5, 7, 10, 25, 25
+ };
+
+ public TanachYomiCalculator() {}
+
+ /**
+ * Returns the Tanach Yomi seder for the date that the calendar is set to.
+ *
+ * @param calendar the calendar set to the date to calculate
+ * @return the Tanach Yomi reading, or {@code null} on days without a reading
+ * @throws IllegalArgumentException if the date is before October 26, 1948, the start of the cycle
+ */
+ public static TanachYomi getTanachYomi(JewishCalendar calendar) {
+ if (calendar.getLocalDate().isBefore(START)) {
+ throw new IllegalArgumentException(
+ calendar.getLocalDate() + " is prior to the Tanach Yomi cycle that started on " + START);
+ }
+ if (skipDay(calendar)) {
+ return null;
+ }
+ int year = calendar.getJewishYear();
+ JewishCalendar start = new JewishCalendar(year, JewishCalendar.TISHREI, 23);
+ int total = 0;
+ if (calendar.getLocalDate().isBefore(start.getLocalDate())) {
+ JewishCalendar rh = new JewishCalendar(year, JewishCalendar.TISHREI, 1);
+ int rhDow = rh.getDayOfWeek();
+ int blatt = rhDow == 5 ? 11 : rhDow == 7 ? 10 : 12;
+ JewishCalendar loop = new JewishCalendar(year, JewishCalendar.TISHREI, 3);
+ while (loop.getLocalDate().isBefore(calendar.getLocalDate())) {
+ if (!skipDay(loop)) {
+ blatt++;
+ }
+ loop.plusDays(1);
+ }
+ return new TanachYomi("Chronicles", "דברי הימים", String.valueOf(blatt));
+ }
+ JewishCalendar loop = new JewishCalendar(year, JewishCalendar.TISHREI, 23);
+ while (loop.getLocalDate().isBefore(calendar.getLocalDate())) {
+ if (!skipDay(loop)) {
+ total++;
+ }
+ loop.plusDays(1);
+ }
+ ReadingTable readingTable = makeReadingTable(year);
+ int remaining = total;
+ for (int i = 0; i < readingTable.blatt.length; i++) {
+ if (remaining < readingTable.blatt[i]) {
+ int blatt = remaining + 1;
+ String seder = String.valueOf(blatt);
+ if ((readingTable.longShirHaShirim && BOOKS[i].equals(SHIR_HASHIRIM))
+ || (readingTable.longRuth && BOOKS[i].equals(RUTH))) {
+ seder = "1." + blatt;
+ } else if (readingTable.longJoshua && BOOKS[i].equals(JOSHUA) && blatt >= 4) {
+ seder = blatt == 4 ? "4.1" : blatt == 5 ? "4.2" : String.valueOf(blatt - 1);
+ } else if (readingTable.longJeremiah && BOOKS[i].equals(JEREMIAH) && blatt >= 9) {
+ seder = blatt == 9 ? "9.1" : blatt == 10 ? "9.2" : String.valueOf(blatt - 1);
+ }
+ return new TanachYomi(BOOKS[i], HEBREW_BOOKS[i], seder);
+ }
+ remaining -= readingTable.blatt[i];
+ }
+ throw new IllegalStateException("Unable to calculate Tanach Yomi");
+ }
+
+ private static boolean skipDay(JewishCalendar calendar) {
+ if (calendar.getDayOfWeek() == 7) {
+ return true;
+ }
+ JewishCalendar c = new JewishCalendar(calendar.getLocalDate());
+ c.setInIsrael(true);
+ c.setUseModernHolidays(true);
+ int yomTov = c.getYomTovIndex();
+ if (yomTov == JewishCalendar.PURIM
+ || yomTov == JewishCalendar.YOM_HAATZMAUT
+ || yomTov == JewishCalendar.TISHA_BEAV
+ || yomTov == JewishCalendar.YOM_KIPPUR
+ || yomTov == JewishCalendar.SHAVUOS
+ || yomTov == JewishCalendar.ROSH_HASHANA
+ || yomTov == JewishCalendar.SHEMINI_ATZERES) {
+ return true;
+ }
+ return (yomTov == JewishCalendar.PESACH
+ && (c.getJewishDayOfMonth() == 15 || c.getJewishDayOfMonth() == 21))
+ || (yomTov == JewishCalendar.SUCCOS && c.getJewishDayOfMonth() == 15);
+ }
+
+ private static int calculateNumDaysToRead(int year) {
+ JewishCalendar loop = new JewishCalendar(year, JewishCalendar.TISHREI, 23);
+ JewishCalendar end = new JewishCalendar(year + 1, JewishCalendar.TISHREI, 22);
+ int count = 0;
+ while (!loop.getLocalDate().isAfter(end.getLocalDate())) {
+ if (!skipDay(loop)) {
+ count++;
+ }
+ loop.plusDays(1);
+ }
+ return count;
+ }
+
+ private static ReadingTable makeReadingTable(int year) {
+ int numDays = calculateNumDaysToRead(year);
+ int count = JewishDate.isJewishLeapYear(year) ? numDays - 25 : numDays;
+ int extra = count - 293;
+ int[] table = BLATT.clone();
+ ReadingTable result = new ReadingTable(table);
+ switch (extra) {
+ case 0:
+ return result;
+ case 4:
+ table[0] = 15;
+ result.longJoshua = true;
+ case 3:
+ table[5] = 32;
+ result.longJeremiah = true;
+ case 2:
+ table[11] = 2;
+ result.longShirHaShirim = true;
+ case 1:
+ table[12] = 2;
+ result.longRuth = true;
+ return result;
+ default:
+ throw new IllegalStateException(
+ "Unexpected Tanach Yomi year length " + year + " => " + extra);
+ }
+ }
+
+ private static class ReadingTable {
+ private final int[] blatt;
+ private boolean longRuth;
+ private boolean longShirHaShirim;
+ private boolean longJeremiah;
+ private boolean longJoshua;
+
+ private ReadingTable(int[] blatt) {
+ this.blatt = blatt;
+ }
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TehillimYomi.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TehillimYomi.java
new file mode 100644
index 00000000..0d1672cd
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TehillimYomi.java
@@ -0,0 +1,34 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+/** An object representing the daily Tehillim portion. */
+public class TehillimYomi {
+ private final int startChapter;
+ private final int endChapter;
+
+ public TehillimYomi(int startChapter, int endChapter) {
+ this.startChapter = startChapter;
+ this.endChapter = endChapter;
+ }
+
+ public int getStartChapter() {
+ return startChapter;
+ }
+
+ public int getEndChapter() {
+ return endChapter;
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TehillimYomiCalculator.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TehillimYomiCalculator.java
new file mode 100644
index 00000000..b8eaf21d
--- /dev/null
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/TehillimYomiCalculator.java
@@ -0,0 +1,72 @@
+/*
+ * Zmanim Java API
+ * Copyright © 2026 Eliyahu Hershfeld
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA,
+ * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ */
+package com.kosherjava.zmanim.hebrewcalendar;
+
+/**
+ * Calculates the daily Tehillim cycle divided by the Hebrew day of month. In a 29-day Hebrew month,
+ * the 30th day's portion is combined with the 29th day so that Sefer Tehillim is completed every
+ * month.
+ */
+public class TehillimYomiCalculator {
+ private static final int[][] SCHEDULE = {
+ {0, 0},
+ {1, 9},
+ {10, 17},
+ {18, 22},
+ {23, 28},
+ {29, 34},
+ {35, 38},
+ {39, 43},
+ {44, 48},
+ {49, 54},
+ {55, 59},
+ {60, 65},
+ {66, 68},
+ {69, 71},
+ {72, 76},
+ {77, 78},
+ {79, 82},
+ {83, 87},
+ {88, 89},
+ {90, 96},
+ {97, 103},
+ {104, 105},
+ {106, 107},
+ {108, 112},
+ {113, 118},
+ {119, 119},
+ {119, 119},
+ {120, 134},
+ {135, 139},
+ {140, 144},
+ {145, 150}
+ };
+
+ public TehillimYomiCalculator() {}
+
+ /**
+ * Returns the daily Tehillim for the date that the calendar is set to.
+ *
+ * @param calendar the calendar set to the date to calculate
+ * @return the daily Tehillim reading
+ */
+ public static TehillimYomi getDailyTehillim(JewishCalendar calendar) {
+ int day = calendar.getJewishDayOfMonth();
+ if (day == 29 && calendar.getDaysInJewishMonth() == 29) {
+ return new TehillimYomi(140, 150);
+ }
+ return new TehillimYomi(SCHEDULE[day][0], SCHEDULE[day][1]);
+ }
+}
diff --git a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/package-info.java b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/package-info.java
index 3afef8cc..e0c9d918 100644
--- a/src/main/java/com/kosherjava/zmanim/hebrewcalendar/package-info.java
+++ b/src/main/java/com/kosherjava/zmanim/hebrewcalendar/package-info.java
@@ -12,7 +12,9 @@
* - {@link TefilaRules} is a utility class for various calendar based tefila rules.
* - {@link HebrewDateFormatter} defines the basics for taking a JewishCalendar and formatting the dates.
* - {@link YomiCalculator} calculates the {@link Daf} Yomi Bavli for a given JewishCalendar and {@link YerushalmiYomiCalculator} does the same
- * for Yerushalmi Yomi.
+ * for Yerushalmi Yomi. Other daily limud calculators include {@link MishnaYomiCalculator}, {@link RambamYomiCalculator},
+ * {@link TehillimYomiCalculator}, {@link TanachYomiCalculator}, {@link KitzurShulchanAruchYomiCalculator} and
+ * {@link ShemirasHaLashonYomiCalculator}.
*
* @author © Eliyahu Hershfeld 2011 - 2026
*/
diff --git a/src/test/java/com/kosherjava/zmanim/hebrewcalendar/LimudYomiCalculatorTest.java b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/LimudYomiCalculatorTest.java
new file mode 100644
index 00000000..7c51ee51
--- /dev/null
+++ b/src/test/java/com/kosherjava/zmanim/hebrewcalendar/LimudYomiCalculatorTest.java
@@ -0,0 +1,142 @@
+package com.kosherjava.zmanim.hebrewcalendar;
+
+import java.time.LocalDate;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LimudYomiCalculatorTest {
+ private final HebrewDateFormatter formatter = new HebrewDateFormatter();
+ private final HebrewDateFormatter hebrewFormatter = new HebrewDateFormatter();
+
+ public LimudYomiCalculatorTest() {
+ hebrewFormatter.setHebrewFormat(true);
+ }
+
+ @Test
+ public void testMishnaYomi() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2020, 9, 21));
+ Assert.assertEquals("Kelim 11:7-8", formatter.formatMishnaYomi(calendar.getMishnaYomi()));
+ Assert.assertEquals(
+ "כלים י״א: ז-ח", hebrewFormatter.formatMishnaYomi(calendar.getMishnaYomi()));
+ }
+
+ @Test
+ public void testMishnaYomiHebrewFifteen() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2020, 10, 18));
+ Assert.assertEquals("Kelim 17:14-15", formatter.formatMishnaYomi(calendar.getMishnaYomi()));
+ Assert.assertEquals(
+ "כלים י״ז: י״ד-ט״ו", hebrewFormatter.formatMishnaYomi(calendar.getMishnaYomi()));
+ }
+
+ @Test
+ public void testRambamYomiOneChapter() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2020, 11, 11));
+ Assert.assertEquals("Sabbath 17", formatter.formatRambamYomi(calendar.getRambamYomi()));
+ Assert.assertEquals(
+ "הלכות שבת פרק יז", hebrewFormatter.formatRambamYomi(calendar.getRambamYomi()));
+ }
+
+ @Test
+ public void testRambamYomiIntroAndSpecialChapters() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(1984, 4, 29));
+ Assert.assertEquals(
+ "Transmission of the Oral Law 1-21", formatter.formatRambamYomi(calendar.getRambamYomi()));
+ Assert.assertEquals(
+ "מסירת תורה שבעל פה פרק א-כא", hebrewFormatter.formatRambamYomi(calendar.getRambamYomi()));
+
+ calendar = new JewishCalendar(LocalDate.of(2023, 8, 8));
+ Assert.assertEquals(
+ "The Order of Prayer 4-5", formatter.formatRambamYomi(calendar.getRambamYomi()));
+ Assert.assertEquals(
+ "סדר התפילה פרקים ד-ה", hebrewFormatter.formatRambamYomi(calendar.getRambamYomi()));
+ }
+
+ @Test
+ public void testRambamYomiThreeChapters() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2024, 7, 29));
+ Assert.assertEquals(
+ "Gifts to the Poor 8-10", formatter.formatRambamYomi(calendar.getRambamYomi3Chapters()));
+ Assert.assertEquals(
+ "הלכות מתנות עניים פרקים ח-י",
+ hebrewFormatter.formatRambamYomi(calendar.getRambamYomi3Chapters()));
+ }
+
+ @Test
+ public void testRambamYomiThreeChapterSpecialCases() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(1984, 4, 29));
+ Assert.assertEquals(
+ "Transmission of the Oral Law 1-45",
+ formatter.formatRambamYomi(calendar.getRambamYomi3Chapters()));
+ Assert.assertEquals(
+ "מסירת תורה שבעל פה פרקים א-מה",
+ hebrewFormatter.formatRambamYomi(calendar.getRambamYomi3Chapters()));
+
+ calendar = new JewishCalendar(LocalDate.of(2020, 9, 3));
+ Assert.assertEquals(
+ "Leavened and Unleavened Bread 8-9, Shofar, Sukkah and Lulav 1-2",
+ formatter.formatRambamYomi(calendar.getRambamYomi3Chapters()));
+ Assert.assertEquals(
+ "הלכות חמץ ומצה פרקים ח-ט, הלכות שופר וסוכה ולולב פרקים א-ב",
+ hebrewFormatter.formatRambamYomi(calendar.getRambamYomi3Chapters()));
+ }
+
+ @Test
+ public void testDailyTehillim() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2024, 1, 3));
+ Assert.assertEquals(
+ "Psalms 106-107", formatter.formatDailyTehillim(calendar.getDailyTehillim()));
+ Assert.assertEquals(
+ "תהילים ק״ו-ק״ז", hebrewFormatter.formatDailyTehillim(calendar.getDailyTehillim()));
+ }
+
+ @Test
+ public void testTanachYomi() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2024, 6, 9));
+ Assert.assertEquals("Psalms Seder 3", formatter.formatTanachYomi(calendar.getTanachYomi()));
+ Assert.assertEquals("תהלים ס׳ ג׳", hebrewFormatter.formatTanachYomi(calendar.getTanachYomi()));
+ }
+
+ @Test
+ public void testKitzurShulchanAruchYomi() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2024, 7, 9));
+ Assert.assertEquals(
+ "161:18-162:5",
+ formatter.formatKitzurShulchanAruchYomi(calendar.getKitzurShulchanAruchYomi()));
+ Assert.assertEquals(
+ "קס״א: יח - קס״ב: ה",
+ hebrewFormatter.formatKitzurShulchanAruchYomi(calendar.getKitzurShulchanAruchYomi()));
+ }
+
+ @Test
+ public void testShemirasHaLashonYomi() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2024, 6, 26));
+ Assert.assertEquals(
+ "Shemirat HaLashon, Part 2, Perek 9 Halacha 8-10",
+ formatter.formatShemirasHaLashonYomi(calendar.getShemirasHaLashonYomi()));
+ Assert.assertEquals(
+ "שמירת הלשון, חלק ב׳, פרק ט׳ הלכה ח-י",
+ hebrewFormatter.formatShemirasHaLashonYomi(calendar.getShemirasHaLashonYomi()));
+ }
+
+ @Test
+ public void testShemirasHaLashonSectionYomi() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2024, 10, 3));
+ Assert.assertEquals(
+ "Shemirat HaLashon, Part 1, Hakdamah, 1-2",
+ formatter.formatShemirasHaLashonYomi(calendar.getShemirasHaLashonYomi()));
+ Assert.assertEquals(
+ "שמירת הלשון, חלק א׳, הקדמה, א-ב",
+ hebrewFormatter.formatShemirasHaLashonYomi(calendar.getShemirasHaLashonYomi()));
+ }
+
+ @Test
+ public void testShemirasHaLashonShaarYomi() {
+ JewishCalendar calendar = new JewishCalendar(LocalDate.of(2024, 10, 13));
+ Assert.assertEquals(
+ "Shemirat HaLashon, Part 1, Shaar HaZechirah, Perek 1 Halacha 1-4",
+ formatter.formatShemirasHaLashonYomi(calendar.getShemirasHaLashonYomi()));
+ Assert.assertEquals(
+ "שמירת הלשון, חלק א׳, שער הזכירה, פרק א׳ הלכה א-ד",
+ hebrewFormatter.formatShemirasHaLashonYomi(calendar.getShemirasHaLashonYomi()));
+ }
+}