001/* 002 * Zmanim Java API 003 * Copyright (C) 2011-2020 Eliyahu Hershfeld 004 * 005 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 006 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied 010 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 011 * details. 012 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 013 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA, 014 * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 015 */ 016package com.kosherjava.zmanim.hebrewcalendar; 017 018import java.util.Calendar; 019import java.util.GregorianCalendar; 020 021/** 022 * This class calculates the Daf Yomi Bavli page (daf) for a given date. To calculate Daf Yomi Yerushalmi 023 * use the {@link YerushalmiYomiCalculator}. The library may cover Mishna Yomi etc. at some point in the future. 024 * 025 * @author © Bob Newell (original C code) 026 * @author © Eliyahu Hershfeld 2011 - 2020 027 */ 028public class YomiCalculator { 029 030 /** 031 * The start date of the first Daf Yomi Bavli cycle of September 11, 1923 / Rosh Hashana 5684. 032 */ 033 private static final Calendar dafYomiStartDay = new GregorianCalendar(1923, Calendar.SEPTEMBER, 11); 034 /** The start date of the first Daf Yomi Bavli cycle in the Julian calendar. Used internally for claculations.*/ 035 private static final int dafYomiJulianStartDay = getJulianDay(dafYomiStartDay); 036 /** 037 * The date that the pagination for the Daf Yomi <em>Maseches Shekalim</em> changed to use the commonly used Vilna 038 * Shas pagination from the no longer commonly available Zhitomir / Slavuta Shas used by Rabbi Meir Shapiro. 039 */ 040 private static final Calendar shekalimChangeDay = new GregorianCalendar(1975, Calendar.JUNE, 24); 041 042 /** The Julian date that the cycle for Shekalim changed. 043 * @see #getDafYomiBavli(JewishCalendar) for details. 044 */ 045 private static final int shekalimJulianChangeDay = getJulianDay(shekalimChangeDay); 046 047 /** 048 * Returns the <a href="http://en.wikipedia.org/wiki/Daf_yomi">Daf Yomi</a> <a 049 * href="http://en.wikipedia.org/wiki/Talmud">Bavli</a> {@link Daf} for a given date. The first Daf Yomi cycle 050 * started on Rosh Hashana 5684 (September 11, 1923) and calculations prior to this date will result in an 051 * IllegalArgumentException thrown. For historical calculations (supported by this method), it is important to note 052 * that a change in length of the cycle was instituted starting in the eighth Daf Yomi cycle beginning on June 24, 053 * 1975. The Daf Yomi Bavli cycle has a single masechta of the Talmud Yerushalmi - Shekalim as part of the cycle. 054 * Unlike the Bavli where the number of daf per masechta was standardized since the original <a 055 * href="http://en.wikipedia.org/wiki/Daniel_Bomberg">Bomberg Edition</a> published from 1520 - 1523, there is no 056 * uniform page length in the Yerushalmi. The early cycles had the Yerushalmi Shekalim length of 13 days following the 057 * <a href= 058 * "https://he.wikipedia.org/wiki/%D7%93%D7%A4%D7%95%D7%A1_%D7%A1%D7%9C%D7%90%D7%95%D7%95%D7%99%D7%98%D7%90">Slavuta/Zhytomyr</a> 059 * Shas used by <a href="http://en.wikipedia.org/wiki/Meir_Shapiro">Rabbi Meir Shapiro</a>. With the start of the eighth Daf Yomi 060 * cycle beginning on June 24, 1975 the length of the Yerushalmi Shekalim was changed from 13 to 22 daf to follow 061 * the <a href="https://en.wikipedia.org/wiki/Vilna_Edition_Shas">Vilna Shas</a> that is in common use today. 062 * 063 * @param jewishCalendar 064 * The JewishCalendar date for calculation. TODO: this can be changed to use a regular GregorianCalendar since 065 * there is nothing specific to the JewishCalendar in this class. 066 * @return the {@link Daf}. 067 * 068 * @throws IllegalArgumentException 069 * if the date is prior to the September 11, 1923 start date of the first Daf Yomi cycle 070 */ 071 public static Daf getDafYomiBavli(JewishCalendar jewishCalendar) { 072 /* 073 * The number of daf per masechta. Since the number of blatt in Shekalim changed on the 8th Daf Yomi cycle 074 * beginning on June 24, 1975 from 13 to 22, the actual calculation for blattPerMasechta[4] will later be 075 * adjusted based on the cycle. 076 */ 077 int[] blattPerMasechta = { 64, 157, 105, 121, 22, 88, 56, 40, 35, 31, 32, 29, 27, 122, 112, 91, 66, 49, 90, 82, 078 119, 119, 176, 113, 24, 49, 76, 14, 120, 110, 142, 61, 34, 34, 28, 22, 4, 9, 5, 73 }; 079 Calendar calendar = jewishCalendar.getGregorianCalendar(); 080 081 Daf dafYomi = null; 082 int julianDay = getJulianDay(calendar); 083 int cycleNo = 0; 084 int dafNo = 0; 085 if (calendar.before(dafYomiStartDay)) { 086 // TODO: should we return a null or throw an IllegalArgumentException? 087 throw new IllegalArgumentException(calendar + " is prior to organized Daf Yomi Bavli cycles that started on " 088 + dafYomiStartDay); 089 } 090 if (calendar.equals(shekalimChangeDay) || calendar.after(shekalimChangeDay)) { 091 cycleNo = 8 + ((julianDay - shekalimJulianChangeDay) / 2711); 092 dafNo = ((julianDay - shekalimJulianChangeDay) % 2711); 093 } else { 094 cycleNo = 1 + ((julianDay - dafYomiJulianStartDay) / 2702); 095 dafNo = ((julianDay - dafYomiJulianStartDay) % 2702); 096 } 097 098 int total = 0; 099 int masechta = -1; 100 int blatt = 0; 101 102 // Fix Shekalim for old cycles. 103 if (cycleNo <= 7) { 104 blattPerMasechta[4] = 13; 105 } else { 106 blattPerMasechta[4] = 22; // correct any change that may have been changed from a prior calculation 107 } 108 // Finally find the daf. 109 for (int j = 0; j < blattPerMasechta.length; j++) { 110 masechta++; 111 total = total + blattPerMasechta[j] - 1; 112 if (dafNo < total) { 113 blatt = 1 + blattPerMasechta[j] - (total - dafNo); 114 // Fiddle with the weird ones near the end. 115 if (masechta == 36) { 116 blatt += 21; 117 } else if (masechta == 37) { 118 blatt += 24; 119 } else if (masechta == 38) { 120 blatt += 32; 121 } 122 dafYomi = new Daf(masechta, blatt); 123 break; 124 } 125 } 126 127 return dafYomi; 128 } 129 130 /** 131 * Return the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> from a Java Calendar. 132 * 133 * @param calendar 134 * The Java Calendar of the date to be calculated 135 * @return the Julian day number corresponding to the date 136 */ 137 private static int getJulianDay(Calendar calendar) { 138 int year = calendar.get(Calendar.YEAR); 139 int month = calendar.get(Calendar.MONTH) + 1; 140 int day = calendar.get(Calendar.DAY_OF_MONTH); 141 if (month <= 2) { 142 year -= 1; 143 month += 12; 144 } 145 int a = year / 100; 146 int b = 2 - a + a / 4; 147 return (int) (Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + b - 1524.5); 148 } 149}