1 /*
2 This file is part of KOrganizer.
3
4 SPDX-FileCopyrightText: 2003 Jonathan Singer <jsinger@leeta.net>
5 SPDX-FileCopyrightText: 2007 Loïc Corbasson <loic.corbasson@gmail.com>
6
7 Calendar routines from Hebrew Calendar by Frank Yellin.
8 Based on some GNU Emacs code (lisp/calendar/cal-hebrew.el),
9 SPDX-FileCopyrightText: 1995, 1997 Free Software Foundation, Inc.
10 SPDX-FileContributor: Nachum Dershowitz <nachum@cs.uiuc.edu>
11 SPDX-FileContributor: Edward M. Reingold <reingold@cs.uiuc.edu>
12
13 SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16 #include "parsha.h"
17 #include "korganizer_hebrew_debug.h"
18 #include <KLocalizedString>
19
findParshaName(int dayNumber,int kvia,bool isLeapYear,bool useIsraelSettings)20 QString Parsha::findParshaName(int dayNumber, int kvia, bool isLeapYear, bool useIsraelSettings)
21 {
22 // The names of the Parshiot.
23 static QStringList parshiotNames = QStringList();
24 parshiotNames << i18nc(
25 "These are weekly readings and do not have translations. "
26 "They may have different spellings in your language; "
27 "otherwise, just translate the sound to your characters",
28 "Bereshit")
29 << i18n("Noach") << i18n("Lech L'cha") << i18n("Vayera") << i18n("Chaye Sarah") << i18n("Toldot") << i18n("Vayetze") << i18n("Vayishlach")
30 << i18n("Vayeshev") << i18n("Miketz") << i18n("Vayigash") << i18n("Vayechi") << i18n("Shemot") << i18n("Vaera") << i18n("Bo")
31 << i18n("Beshalach") << i18n("Yitro") << i18n("Mishpatim") << i18n("Terumah") << i18n("Tetzaveh") << i18n("Ki Tisa") << i18n("Vayakhel")
32 << i18n("Pekudei") << i18n("Vayikra") << i18n("Tzav") << i18n("Shemini") << i18n("Tazria") << i18n("Metzora") << i18n("Acharei Mot")
33 << i18n("Kedoshim") << i18n("Emor") << i18n("Behar") << i18n("Bechukotai") << i18n("Bemidbar") << i18n("Naso") << i18n("Behaalotcha")
34 << i18n("Shelach") << i18n("Korach") << i18n("Chukat") << i18n("Balak") << i18n("Pinchas") << i18n("Matot") << i18n("Masei")
35 << i18n("Devarim") << i18n("Vaetchanan") << i18n("Ekev") << i18n("Reeh") << i18n("Shoftim") << i18n("Ki Tetze") << i18n("Ki Tavo")
36 << i18n("Nitzavim") << i18n("Vayelech") << i18n("Haazinu");
37
38 /*
39 Tables for each of the year types. XX indicates that it is a Holiday, and a
40 special parsha is read that week. For some year types among the 14, Israel
41 is different from the diaspora.
42
43 The names indicate the day of the week on which Rosh Hashanah fell, whether
44 it is a short/normal/long year (kvia=0,1,2), and whether it is a leap year.
45 As said earlier, some year types also have an _Israel version.
46
47 The numbers are indices in the list above for a given week.
48 Numbers > 100 indicate a double parsha, e.g. 150 means read both table
49 entries 150 - 100 = 50 and 150 - 99 = 51.
50
51 These tables were stolen (with some massaging) from the Gnu code.
52 */
53
54 static const quint8 XX = 255;
55
56 /* Non-leap years */
57 static const quint8 SatShort[] = {
58 XX, 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 121,
59 23, 24, XX, 25, 126, 128, 30, 131, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 50,
60 };
61 static const quint8 SatLong[] = {
62 XX, 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 121,
63 23, 24, XX, 25, 126, 128, 30, 131, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 150,
64 };
65
66 static const quint8 MonShort[] = {
67 51, 52, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 121,
68 23, 24, XX, 25, 126, 128, 30, 131, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 150,
69 };
70 static const quint8 MonLong[] = /* split */
71 {
72 51, 52, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 121,
73 23, 24, XX, 25, 126, 128, 30, 131, 33, XX, 34, 35, 36, 37, 138, 40, 141, 43, 44, 45, 46, 47, 48, 49, 150,
74 };
75 #define MonLong_Israel MonShort
76
77 #define TueNormal MonLong
78 #define TueNormal_Israel MonShort
79
80 static const quint8 ThuNormal[] = {
81 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 121, 23,
82 24, XX, XX, 25, 126, 128, 30, 131, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 50,
83 };
84 static const quint8 ThuNormal_Israel[] = {
85 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 121, 23,
86 24, XX, 25, 126, 128, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 50,
87 };
88 static const quint8 ThuLong[] = {
89 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
90 23, 24, XX, 25, 126, 128, 30, 131, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 50,
91 };
92
93 /* Leap years */
94 static const quint8 SatShortLeap[] = {
95 XX, 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
96 24, 25, 26, 27, XX, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 150,
97 };
98 static const quint8 SatLongLeap[] = {
99 XX, 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
100 24, 25, 26, 27, XX, 28, 29, 30, 31, 32, 33, XX, 34, 35, 36, 37, 138, 40, 141, 43, 44, 45, 46, 47, 48, 49, 150,
101 };
102 #define SatLongLeap_Israel SatShortLeap
103
104 static const quint8 MonShortLeap[] = {
105 51, 52, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
106 24, 25, 26, 27, XX, 28, 29, 30, 31, 32, 33, XX, 34, 35, 36, 37, 138, 40, 141, 43, 44, 45, 46, 47, 48, 49, 150,
107 };
108 static const quint8 MonShortLeap_Israel[] = {
109 51, 52, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
110 24, 25, 26, 27, XX, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 150,
111 };
112 static const quint8 MonLongLeap[] = {
113 51, 52, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
114 25, 26, 27, XX, XX, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 141, 43, 44, 45, 46, 47, 48, 49, 50,
115 };
116 static const quint8 MonLongLeap_Israel[] = {
117 51, 52, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
118 25, 26, 27, XX, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
119 };
120
121 #define TueNormalLeap MonLongLeap
122 #define TueNormalLeap_Israel MonLongLeap_Israel
123
124 static const quint8 ThuShortLeap[] = {
125 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
126 25, 26, 27, 28, XX, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
127 };
128 static const quint8 ThuLongLeap[] = {
129 52, XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
130 25, 26, 27, 28, XX, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 150,
131 };
132
133 /* Make the calculations */
134 int week = dayNumber / 7; // week of the year
135 const quint8 *array = nullptr;
136 int index;
137
138 /* Get the appropriate array by exhaustive search into the 14 year types.
139 Since we know it's a Shabbat, we can find out what day Rosh Hashanah was on
140 by looking at dayNumber % 7. */
141 if (!isLeapYear) {
142 switch (dayNumber % 7) {
143 case 1: /* Rosh Hashanah was on a Saturday */
144 if (kvia == 0) {
145 array = SatShort;
146 } else if (kvia == 2) {
147 array = SatLong;
148 }
149 break;
150 case 6: /* Rosh Hashanah was on a Monday */
151 if (kvia == 0) {
152 array = MonShort;
153 } else if (kvia == 2) {
154 array = useIsraelSettings ? MonLong_Israel : MonLong;
155 }
156 break;
157 case 5: /* Rosh Hashanah was on a Tuesday */
158 if (kvia == 1) {
159 array = useIsraelSettings ? TueNormal_Israel : TueNormal;
160 }
161 break;
162 case 3: /* Rosh Hashanah was on a Thursday */
163 if (kvia == 1) {
164 array = useIsraelSettings ? ThuNormal_Israel : ThuNormal;
165 } else if (kvia == 2) {
166 array = ThuLong;
167 }
168 break;
169 }
170 } else { /* leap year */
171 switch (dayNumber % 7) {
172 case 1: /* Rosh Hashanah was on a Sat */
173 if (kvia == 0) {
174 array = SatShortLeap;
175 } else if (kvia == 2) {
176 array = useIsraelSettings ? SatLongLeap_Israel : SatLongLeap;
177 }
178 break;
179 case 6: /* Rosh Hashanah was on a Monday */
180 if (kvia == 0) {
181 array = useIsraelSettings ? MonShortLeap_Israel : MonShortLeap;
182 } else if (kvia == 2) {
183 array = useIsraelSettings ? MonLongLeap_Israel : MonLongLeap;
184 }
185 break;
186 case 5: /* Rosh Hashanah was on a Tuesday */
187 if (kvia == 1) {
188 array = useIsraelSettings ? TueNormalLeap_Israel : TueNormalLeap;
189 }
190 break;
191 case 3: /* Rosh Hashanah was on a Thursday */
192 if (kvia == 0) {
193 array = ThuShortLeap;
194 } else if (kvia == 2) {
195 array = ThuLongLeap;
196 }
197 break;
198 }
199 }
200 QString buffer;
201
202 if (!array) { /* Something is terribly wrong! */
203 buffer = QStringLiteral("??Parsha??");
204 qCWarning(KORGANIZER_HEBREWPLUGIN_LOG) << "Hebrew Plugin: Was not able to determine the Parsha."
205 << "Please report this as a bug.";
206 return buffer;
207 }
208
209 index = array[week];
210 if (index == XX) { // no Parsha this week.
211 buffer.clear();
212 return buffer;
213 } else if (index < 100) {
214 buffer = parshiotNames[index];
215 return buffer;
216 } else { // Create a double parsha
217 buffer = parshiotNames[index - 100] + QLatin1Char('-') + parshiotNames[index - 99];
218 return buffer;
219 }
220 }
221