001/* 002 * Zmanim Java API 003 * Copyright (C) 2017 - 2023 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/** 023 * This class calculates the <a href="https://en.wikipedia.org/wiki/Jerusalem_Talmud">Talmud Yerusalmi</a> <a href= 024 * "https://en.wikipedia.org/wiki/Daf_Yomi">Daf Yomi</a> page ({@link Daf}) for the a given date. 025 * 026 * @author © elihaidv 027 * @author © Eliyahu Hershfeld 2017 - 2023 028 */ 029public class YerushalmiYomiCalculator { 030 031 /** 032 * The start date of the first Daf Yomi Yerushalmi cycle of February 2, 1980 / 15 Shevat, 5740. 033 */ 034 private final static Calendar DAF_YOMI_START_DAY = new GregorianCalendar(1980, Calendar.FEBRUARY, 2); 035 /** The number of milliseconds in a day. */ 036 private final static int DAY_MILIS = 1000 * 60 * 60 * 24; 037 /** The number of pages in the Talmud Yerushalmi.*/ 038 private final static int WHOLE_SHAS_DAFS = 1554; 039 /** The number of pages per <em>masechta</em> (tractate).*/ 040 private final static int[] BLATT_PER_MASECHTA = { 041 68, 37, 34, 44, 31, 59, 26, 33, 28, 20, 13, 92, 65, 71, 22, 22, 42, 26, 26, 33, 34, 22, 042 19, 85, 72, 47, 40, 47, 54, 48, 44, 37, 34, 44, 9, 57, 37, 19, 13}; 043 044 /** 045 * Returns the <a href="https://en.wikipedia.org/wiki/Daf_Yomi">Daf Yomi</a> 046 * <a href="https://en.wikipedia.org/wiki/Jerusalem_Talmud">Yerusalmi</a> page ({@link Daf}) for a given date. 047 * The first Daf Yomi cycle started on 15 Shevat (Tu Bishvat), 5740 (February, 2, 1980) and calculations 048 * prior to this date will result in an IllegalArgumentException thrown. A null will be returned on Tisha B'Av or 049 * Yom Kippur. 050 * 051 * @param calendar 052 * the calendar date for calculation 053 * @return the {@link Daf} or null if the date is on Tisha B'Av or Yom Kippur. 054 * 055 * @throws IllegalArgumentException 056 * if the date is prior to the February 2, 1980, the start of the first Daf Yomi Yerushalmi cycle 057 */ 058 public static Daf getDafYomiYerushalmi(JewishCalendar calendar) { 059 060 Calendar nextCycle = new GregorianCalendar(); 061 Calendar prevCycle = new GregorianCalendar(); 062 Calendar requested = calendar.getGregorianCalendar(); 063 int masechta = 0; 064 Daf dafYomi = null; 065 066 // There isn't Daf Yomi on Yom Kippur or Tisha B'Av. 067 if ( calendar.getYomTovIndex() == JewishCalendar.YOM_KIPPUR || 068 calendar.getYomTovIndex() == JewishCalendar.TISHA_BEAV ) { 069 return null; 070 } 071 072 073 if (requested.before(DAF_YOMI_START_DAY)) { 074 throw new IllegalArgumentException(requested + " is prior to organized Daf Yomi Yerushalmi cycles that started on " 075 + DAF_YOMI_START_DAY); 076 } 077 078 // Start to calculate current cycle. init the start day 079 nextCycle.setTime(DAF_YOMI_START_DAY.getTime()); 080 081 // Go cycle by cycle, until we get the next cycle 082 while (requested.after(nextCycle)) { 083 prevCycle.setTime(nextCycle.getTime()); 084 085 // Adds the number of whole shas dafs. and the number of days that not have daf. 086 nextCycle.add(Calendar.DAY_OF_MONTH, WHOLE_SHAS_DAFS); 087 nextCycle.add(Calendar.DAY_OF_MONTH, getNumOfSpecialDays(prevCycle, nextCycle)); 088 } 089 090 // Get the number of days from cycle start until request. 091 int dafNo = (int)(getDiffBetweenDays(prevCycle, requested)); 092 093 // Get the number of special day to subtract 094 int specialDays = getNumOfSpecialDays(prevCycle, requested); 095 int total = dafNo - specialDays; 096 097 // Finally find the daf. 098 for (int j = 0; j < BLATT_PER_MASECHTA.length; j++) { 099 100 if (total < BLATT_PER_MASECHTA[j]) { 101 dafYomi = new Daf(masechta, total + 1); 102 break; 103 } 104 total -= BLATT_PER_MASECHTA[j]; 105 masechta++; 106 } 107 108 return dafYomi; 109 } 110 111 /** 112 * Return the number of special days (Yom Kippur and Tisha Beav) That there is no Daf in this days. 113 * From the last given number of days until given date 114 * 115 * @param start start date to calculate 116 * @param end end date to calculate 117 * @return the number of special days 118 */ 119 private static int getNumOfSpecialDays(Calendar start, Calendar end) { 120 121 // Find the start and end Jewish years 122 int startYear = new JewishCalendar(start).getJewishYear(); 123 int endYear = new JewishCalendar(end).getJewishYear(); 124 125 // Value to return 126 int specialDays = 0; 127 128 //Instant of special Dates 129 JewishCalendar yom_kippur = new JewishCalendar(5770, 7, 10); 130 JewishCalendar tisha_beav = new JewishCalendar(5770, 5, 9); 131 132 // Go over the years and find special dates 133 for (int i = startYear; i <= endYear; i++) { 134 yom_kippur.setJewishYear(i); 135 tisha_beav.setJewishYear(i); 136 137 if (isBetween(start, yom_kippur.getGregorianCalendar(), end)) { 138 specialDays++; 139 } 140 if (isBetween(start, tisha_beav.getGregorianCalendar(), end)) { 141 specialDays++; 142 } 143 } 144 145 return specialDays; 146 } 147 148 /** 149 * Return if the date is between two dates 150 * 151 * @param start the start date 152 * @param date the date being compared 153 * @param end the end date 154 * @return if the date is between the start and end dates 155 */ 156 private static boolean isBetween( Calendar start, Calendar date, Calendar end ) { 157 return start.before(date) && end.after(date); 158 } 159 160 /** 161 * Return the number of days between the dates passed in 162 * @param start the start date 163 * @param end the end date 164 * @return the number of days between the start and end dates 165 */ 166 private static long getDiffBetweenDays(Calendar start, Calendar end) { 167 return ( end.getTimeInMillis() - start.getTimeInMillis()) / DAY_MILIS; 168 } 169}