-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathYomiCalculator.java
More file actions
164 lines (152 loc) · 6.94 KB
/
YomiCalculator.java
File metadata and controls
164 lines (152 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
* Zmanim Java API
* Copyright (C) 2011-2025 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; either version 2.1 of the License, or (at your option)
* any later version.
*
* 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.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
/**
* This class calculates the Daf Yomi Bavli page (daf) for a given date. To calculate Daf Yomi Yerushalmi
* use the {@link YerushalmiYomiCalculator}. The library may cover Mishna Yomi etc. at some point in the future.
*
* @author © Bob Newell (original C code)
* @author © Eliyahu Hershfeld 2011 - 2025
*/
public class YomiCalculator {
/**
* The start date of the first Daf Yomi Bavli cycle of September 11, 1923 / Rosh Hashana 5684.
*/
private static final Calendar DAF_YOMI_START_DAY;
static {
DAF_YOMI_START_DAY = new GregorianCalendar(1923, Calendar.SEPTEMBER, 11,0,0,0);
DAF_YOMI_START_DAY.setTimeZone(TimeZone.getTimeZone("UTC"));
}
/** The start date of the first Daf Yomi Bavli cycle in the Julian calendar. Used internally for calculations.*/
private static final int DAF_YOMI_JULIAN_START_DAY = getJulianDay(DAF_YOMI_START_DAY);
/**
* The date that the pagination for the Daf Yomi <em>Maseches Shekalim</em> changed to use the commonly used Vilna
* Shas pagination from the no longer commonly available Zhitomir / Slavuta Shas used by Rabbi Meir Shapiro.
*/
private static final Calendar SHEKALIM_CHANGE_DAY;
static {
SHEKALIM_CHANGE_DAY = new GregorianCalendar(1975, Calendar.JUNE, 24,0,0,0);
SHEKALIM_CHANGE_DAY.setTimeZone(TimeZone.getTimeZone("UTC"));
}
/** The Julian date that the cycle for Shekalim changed.
* @see #getDafYomiBavli(JewishCalendar) for details.
*/
private static final int SHEKALIM_JULIAN_CHANGE_DAY = getJulianDay(SHEKALIM_CHANGE_DAY);
/**
* Default constructor.
*/
public YomiCalculator() {
// nothing here
}
/**
* Returns the <a href="http://en.wikipedia.org/wiki/Daf_yomi">Daf Yomi</a> <a
* href="http://en.wikipedia.org/wiki/Talmud">Bavli</a> {@link Daf} for a given date. The first Daf Yomi cycle
* started on Rosh Hashana 5684 (September 11, 1923) and calculations prior to this date will result in an
* IllegalArgumentException thrown. For historical calculations (supported by this method), it is important to note
* that a change in length of the cycle was instituted starting in the eighth Daf Yomi cycle beginning on June 24,
* 1975. The Daf Yomi Bavli cycle has a single masechta of the Talmud Yerushalmi - Shekalim as part of the cycle.
* Unlike the Bavli where the number of daf per masechta was standardized since the original <a
* href="http://en.wikipedia.org/wiki/Daniel_Bomberg">Bomberg Edition</a> published from 1520 - 1523, there is no
* uniform page length in the Yerushalmi. The early cycles had the Yerushalmi Shekalim length of 13 days following the
* <a href=
* "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>
* Shas used by <a href="http://en.wikipedia.org/wiki/Meir_Shapiro">Rabbi Meir Shapiro</a>. With the start of the eighth Daf Yomi
* cycle beginning on June 24, 1975, the length of the Yerushalmi Shekalim was changed from 13 to 22 daf to follow
* the <a href="https://en.wikipedia.org/wiki/Vilna_Edition_Shas">Vilna Shas</a> that is in common use today.
*
* @param jewishCalendar
* The JewishCalendar date for calculation. TODO: this can be changed to use a regular GregorianCalendar since
* there is nothing specific to the JewishCalendar in this class.
* @return the {@link Daf}.
*
* @throws IllegalArgumentException
* if the date is prior to the September 11, 1923, the start date of the first Daf Yomi cycle.
*/
public static Daf getDafYomiBavli(JewishCalendar jewishCalendar) {
/*
* The number of daf per masechta. Since the number of blatt in Shekalim changed on the 8th Daf Yomi cycle
* beginning on June 24, 1975, from 13 to 22, the actual calculation for blattPerMasechta[4] will later be
* adjusted based on the cycle.
*/
int[] blattPerMasechta = { 64, 157, 105, 121, 22, 88, 56, 40, 35, 31, 32, 29, 27, 122, 112, 91, 66, 49, 90, 82,
119, 119, 176, 113, 24, 49, 76, 14, 120, 110, 142, 61, 34, 34, 28, 22, 4, 9, 5, 73 };
Calendar calendar = jewishCalendar.getGregorianCalendar();
Daf dafYomi = null;
int julianDay = getJulianDay(calendar);
int cycleNo;
int dafNo;
if (calendar.before(DAF_YOMI_START_DAY)) {
// TODO: should we return a null or throw an IllegalArgumentException?
throw new IllegalArgumentException(calendar + " is prior to organized Daf Yomi Bavli cycles that started on "
+ DAF_YOMI_START_DAY);
}
if (calendar.equals(SHEKALIM_CHANGE_DAY) || calendar.after(SHEKALIM_CHANGE_DAY)) {
cycleNo = 8 + ((julianDay - SHEKALIM_JULIAN_CHANGE_DAY) / 2711);
dafNo = ((julianDay - SHEKALIM_JULIAN_CHANGE_DAY) % 2711);
} else {
cycleNo = 1 + ((julianDay - DAF_YOMI_JULIAN_START_DAY) / 2702);
dafNo = ((julianDay - DAF_YOMI_JULIAN_START_DAY) % 2702);
}
int total = 0;
int masechta = -1;
int blatt;
// Fix Shekalim for old cycles.
if (cycleNo <= 7) {
blattPerMasechta[4] = 13;
}
// Finally find the daf.
for (int i : blattPerMasechta) {
masechta++;
total = total + i - 1;
if (dafNo < total) {
blatt = 1 + i - (total - dafNo);
// Fiddle with the weird ones near the end.
if (masechta == 36) {
blatt += 21;
} else if (masechta == 37) {
blatt += 24;
} else if (masechta == 38) {
blatt += 32;
}
dafYomi = new Daf(masechta, blatt);
break;
}
}
return dafYomi;
}
/**
* Return the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> from a Java Calendar.
*
* @param calendar
* The Java Calendar of the date to be calculated
* @return the Julian day number corresponding to the date
*/
private static int getJulianDay(Calendar calendar) {
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
if (month <= 2) {
year -= 1;
month += 12;
}
int a = year / 100;
int b = 2 - a + a / 4;
return (int) (Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + b - 1524.5);
}
}