holiday.cpp
1 /***************************************************************************
2  * Copyright (C) 2003 by Jonathan Singer *
3  * jsinger@leeta.net *
4  * Calendar routines from Hebrew Calendar by Frank Yellin *
5  * *
6  * This program is free software; you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation; either version 2 of the License, or *
9  * (at your option) any later version. *
10  ***************************************************************************/
11 #include "holiday.h"
12 #include <tdelocale.h>
13 
14 bool Holiday::CholP;
15 bool Holiday::OmerP;
16 bool Holiday::ParshaP;
17 
18 TQStringList Holiday::holidays;
19 int Holiday::HolidayFlags;
20 
21 Holiday::Holiday()
22 {
23 
24 }
25 
26 Holiday::~Holiday()
27 {
28 }
29 
30 /* Given a day of the Hebrew month, figuring out all the interesting holidays that
31 * correspond to that date. ParshaP, OmerP, and CholP determine whether we should
32 * given info about the Parsha of the week, the Sfira, or Chol Hamoed.
33 *
34 * We are also influenced by the IsraelP flag
35 */
36 
37 TQStringList
38  Holiday::FindHoliday(int month, int day, int weekday, int kvia,
39  bool leap_year_p, bool israel_p,
40  int day_number, int year)
41 {
42 
43  enum
44  { Sunday = 1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
45  };
46 
47  holidays.clear();
48  bool shabbat_p = (weekday == Saturday); // Is it a Saturday?
49 
50  // Treat Adar in a non-leap year as if it were Adar II.
51  if ((month == 12) && !leap_year_p)
52  month = 13;
53  switch (month)
54  {
55  case 1: /* Nissan */
56  switch (day)
57  {
58  case 1:
59  if (shabbat_p)
60  holidays <<
61  i18n
62  ("These are Jewish holidays and mostly do not have translations. They may have different spellings in your language; otherwise, just translate the sound to your characters",
63  "Sh. HaHodesh");
64  break;
65  case 14:
66  if (!shabbat_p)
67  // If it's Shabbat, we have three pieces of info.
68  // This is the least important.
69  holidays << i18n("Erev Pesach");
70  /* Fall thru */
71  case 8:
72  case 9:
73  case 10:
74  case 11:
75  case 12:
76  case 13:
77  // The Saturday before Pesach (8th-14th)
78  if (shabbat_p)
79  holidays << i18n("Sh. HaGadol");
80  break;
81  case 15:
82  case 16:
83  case 21:
84  case 22:
85  if (!israel_p || (day == 15) || (day == 21))
86  {
87  holidays << i18n("Pesach");
88  break;
89  }
90  else if (day == 22)
91  break;
92  /* else fall through */
93  case 17:
94  case 18:
95  case 19:
96  case 20:
97  if (CholP)
98  holidays << i18n("Chol Hamoed");
99  break;
100  case 27:
101  // Yom HaShoah only exists since Israel was established.
102  if (year > 1948 + 3760)
103  holidays << i18n("Yom HaShoah");
104  break;
105  }
106  if ((day > 15) && OmerP)
107  // Count the Omer, starting after the first day of Pesach.
108  holidays << Sfirah(day - 15);
109  break;
110 
111  case 2: /* Iyar */
112  switch (day)
113  {
114  case 2:
115  case 3:
116  case 4:
117  case 5:
118  // Yom HaAtzmaut is on the 5th, unless that's a Saturday, in which
119  // case it is moved back two days to Thursday. Yom HaZikaron is
120  // the day before Yom HaAtzmaut.
121  if (year >= 1948 + 3760)
122  { // only after Israel established.
123  switch (weekday)
124  {
125  case Wednesday:
126  if (day == 5)
127  holidays << i18n("Yom HaAtzmaut");
128  else
129  holidays << i18n("Yom HaZikaron");
130  break;
131  case Thursday:
132  // This can't be 2 Iyar.
133  holidays << i18n("Yom HaAtzmaut");
134  break;
135  case Friday:
136  case Saturday:
137  // These are never either of them.
138  break;
139  default:
140  // All other days follow the normal rules.
141  if (day == 4)
142  holidays << i18n("Yom HaZikaron");
143  else if (day == 5)
144  holidays << i18n("Yom HaAtzmaut");
145  }
146  }
147  break;
148  case 28:
149  // only since the 1967 war
150  if (year > 1967 + 3760)
151  holidays << i18n("Yom Yerushalayim");
152  break;
153  case 18:
154  holidays << i18n("Lag BaOmer");
155  break;
156  }
157  if ((day != 18) && OmerP)
158  // Sfirah the whole month. But Lag BaOmer is already mentioned.
159  holidays << Sfirah(day + 15);
160 
161  break;
162 
163  case 3: /* Sivan */
164  switch (day)
165  {
166  case 1:
167  case 2:
168  case 3:
169  case 4:
170  // Sfirah until Shavuot
171  if (OmerP)
172  holidays << Sfirah(day + 44);
173  break;
174  case 5:
175  // Don't need to mention Sfira(49) if there's already two other
176  // pieces of information
177  if (OmerP && !shabbat_p)
178  holidays << Sfirah(49);
179  holidays << i18n("Erev Shavuot");
180  break;
181  case 6:
182  case 7:
183  if (!israel_p || (day == 6))
184  holidays << i18n("Shavuot");
185  break;
186  }
187  break;
188 
189  case 4: /* Tamuz */
190  // 17th of Tamuz, except Shabbat pushes it to Sunday.
191  if ((!shabbat_p && (day == 17))
192  || ((weekday == 1) && (day == 18)))
193  holidays << i18n("Tzom Tammuz");
194  break;
195 
196  case 5: /* Ab */
197  if (shabbat_p && (3 <= day) && (day <= 16))
198  // The shabbat before and after Tisha B'Av are special
199  if (day <= 9)
200  holidays << i18n("Sh. Hazon");
201  else
202  holidays << i18n("Sh. Nahamu");
203  else if ((!shabbat_p && (day == 9))
204  || ((weekday == 1) && (day == 10)))
205  // 9th of Av, except Shabbat pushes it to Sunday.
206  holidays << i18n("Tisha B'Av");
207  break;
208 
209  case 6: /* Elul */
210  if ((day >= 20) && (day <= 26) && shabbat_p)
211  holidays << i18n("S'lichot");
212  else if (day == 29)
213  holidays << i18n("Erev R.H.");
214  break;
215 
216  case 7: /* Tishrei */
217  switch (day)
218  {
219  case 1:
220  case 2:
221  holidays << i18n("Rosh Hashana");
222  break;
223  case 3:
224  if (shabbat_p)
225  holidays << i18n("Sh. Shuvah");
226  else
227  holidays << i18n("Tzom Gedalia");
228  break;
229  case 4:
230  if (weekday == 1)
231  holidays << i18n("Tzom Gedalia");
232  /* fall through */
233  case 5:
234  case 6:
235  case 7:
236  case 8:
237  if (shabbat_p)
238  holidays << i18n("Sh. Shuvah");
239  break;
240  case 9:
241  holidays << i18n("Erev Y.K.");
242  break;
243  case 10:
244  holidays << i18n("Yom Kippur");
245  break;
246  case 14:
247  holidays << i18n("Erev Sukkot");
248  break;
249  case 15:
250  case 16:
251  if (!israel_p || (day == 15))
252  {
253  holidays << i18n("Sukkot");
254  break;
255  }
256  /* else fall through */
257  case 17:
258  case 18:
259  case 19:
260  case 20:
261  if (CholP)
262  holidays << i18n("Chol Hamoed");
263  break;
264  case 21:
265  holidays << i18n("Hoshana Rabah");
266  break;
267  case 22:
268  holidays << i18n("Shmini Atzeret");
269  break;
270  case 23:
271  if (!israel_p)
272  holidays << i18n("Simchat Torah");
273  break;
274  }
275  break;
276  case 8: /* Cheshvan */
277  break;
278 
279  case 9: /* Kislev */
280  if (day == 24)
281  holidays << i18n("Erev Hanukah");
282  else if (day >= 25)
283  holidays << i18n("Hanukah");
284  break;
285 
286  case 10: /* Tevet */
287  if (day <= (kvia == 0 ? 3 : 2))
288  // Need to know length of Kislev to determine last day of Chanukah
289  holidays << i18n("Hanukah");
290  else if (((day == 10) && !shabbat_p)
291  || ((day == 11) && (weekday == 1)))
292  // 10th of Tevet. Shabbat pushes it to Sunday
293  holidays << i18n("Tzom Tevet");
294  break;
295 
296  case 11: /* Shvat */
297  switch (day)
298  {
299  // The info for figuring out Shabbat Shirah is from the Gnu code. I
300  // assume it's correct.
301 // static char *song = i18n("Sh. Shirah";
302  case 10:
303  if ((kvia != 0) && shabbat_p)
304  holidays << i18n("Sh. Shirah");
305  break;
306  case 11:
307  case 12:
308  case 13:
309  case 14:
310  case 16:
311  if (shabbat_p)
312  holidays << i18n("Sh. Shirah");
313  break;
314  case 15:
315  if (shabbat_p)
316  holidays << i18n("Sh. Shirah");
317  holidays << i18n("Tu B'Shvat");
318  case 17:
319  if ((kvia == 0) && shabbat_p)
320  holidays << i18n("Sh. Shirah");
321  break;
322  case 25:
323  case 26:
324  case 27:
325  case 28:
326  case 29:
327  case 30:
328  // The last shabbat on or before 1 Adar or 1 AdarII
329  if (shabbat_p && !leap_year_p)
330  holidays << i18n("Sh. Shekalim");
331  break;
332  }
333  break;
334 
335  case 12: /* Adar I */
336  if (day == 14)
337  // Eat Purim Katan Candy
338  holidays << i18n("Purim Katan");
339  else if ((day >= 25) && shabbat_p)
340  // The last shabbat on or before 1 Adar II.
341  holidays << i18n("Sh. Shekalim");
342  break;
343 
344  case 13: /* Adar II or Adar */
345  switch (day)
346  {
347  case 1:
348  if (shabbat_p)
349  holidays << i18n("Sh. Shekalim");
350  break;
351  case 11:
352  case 12:
353  // Ta'anit ester is on the 13th. But shabbat moves it back to
354  // Thursday.
355  if (weekday == Thursday)
356  holidays << i18n("Ta'anit Ester");
357  /* Fall thru */
358  case 7:
359  case 8:
360  case 9:
361  case 10:
362  // The Shabbat before purim is Shabbat Zachor
363  if (shabbat_p)
364  holidays << i18n("Sh. Zachor");
365  break;
366  case 13:
367  if (shabbat_p)
368  holidays << i18n("Sh. Zachor");
369  else
370  holidays << i18n("Erev Purim");
371  // It's Ta'anit Esther, unless it's a Friday or Saturday
372  if (weekday < Friday)
373  holidays << i18n("Ta'anit Ester");
374  break;
375  case 14:
376  holidays << i18n("Purim");
377  break;
378  case 15:
379  if (!shabbat_p)
380  holidays << i18n("Shushan Purim");
381  break;
382  case 16:
383  if (weekday == 1)
384  holidays << i18n("Shushan Purim");
385  break;
386  case 17:
387  case 18:
388  case 19:
389  case 20:
390  case 21:
391  case 22:
392  case 23:
393  if (shabbat_p)
394  holidays << i18n("Sh. Parah");
395  break;
396  case 24:
397  case 25:
398  case 26:
399  case 27:
400  case 28:
401  case 29:
402  if (shabbat_p)
403  holidays << i18n("Sh. HaHodesh");
404  break;
405  }
406  break;
407  }
408  if (shabbat_p && ParshaP)
409  // Find the Parsha on Shabbat.
410  holidays << Parsha::FindParshaName(day_number, kvia, leap_year_p,
411  israel_p);
412  return holidays;
413 }
414 
415 /* Return a string corresponding to the nth day of the Omer */
416 TQString Holiday::Sfirah(int day)
417 {
418  /*static char buffer[40];
419  char *endings[] = {"th", "st", "nd", "rd"};
420  int remainder = day % 10;
421  // 11-19 and anything not ending with 1, 2, or 3 uses -th as suffix.
422  if ( ((day >= 11) && (day <= 19)) || (remainder > 3)) remainder = 0;
423  sprintf(buffer, "%d%s day Omer", day, endings[remainder]);
424  return buffer; */
425  TQString buffer;
426 
427  buffer.setNum(day);
428  buffer + i18n(" Omer"); // Fix this to original function
429  return buffer;
430 
431 }