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   Calendar routines from Hebrew Calendar by Frank Yellin.
7   SPDX-FileCopyrightText: 1994-2006 Danny Sadinoff <danny@sadinoff.com>.
8 
9   SPDX-License-Identifier: GPL-2.0-or-later
10 */
11 #pragma once
12 
13 // needed for Q_REQUIRED_RESULT
14 #include <QtGlobal>
15 
16 struct DateResult {
17     int year;
18     int month;
19     int day;
20     int day_of_week;
21 
22     int hebrew_month_length, secular_month_length;
23     bool hebrew_leap_year_p, secular_leap_year_p;
24     int kvia;
25     int hebrew_day_number;
26 };
27 
28 /**
29   This class converts dates between the Hebrew and Gregorian (secular)
30   calendars.
31 
32   @author Loïc Corbasson
33  */
34 class HebrewDate
35 {
36 public:
37     explicit HebrewDate(const DateResult &);
38     ~HebrewDate();
39 
40     static HebrewDate fromSecular(int year, int month, int day);
41     static HebrewDate fromHebrew(int year, int month, int day);
42 
43     Q_REQUIRED_RESULT int year() const;
44     Q_REQUIRED_RESULT int month() const;
45     Q_REQUIRED_RESULT int day() const;
46     Q_REQUIRED_RESULT int dayOfWeek() const;
47 
48     Q_REQUIRED_RESULT int hebrewMonthLength() const;
49     Q_REQUIRED_RESULT int secularMonthLength() const;
50     Q_REQUIRED_RESULT bool isOnHebrewLeapYear() const;
51     Q_REQUIRED_RESULT bool isOnSecularLeapYear() const;
52     Q_REQUIRED_RESULT int kvia() const;
53     Q_REQUIRED_RESULT int hebrewDayNumber() const;
54 
55 private:
56     int mYear, mMonth, mDay, mDayOfWeek;
57     int mHebrewMonthLength, mSecularMonthLength;
58     bool mOnHebrewLeapYear, mOnSecularLeapYear;
59     int mKvia, mHebrewDayNumber;
60 };
61 
62 /**
63   This class is used internally to convert dates between the Hebrew and
64   Gregorian (secular) calendars.
65 
66   Calendar routines from Hebrew Calendar by Frank Yellin.
67 
68   For more information, see “The Comprehensive Hebrew Calendar” by Arthur Spier
69   and “Calendrical Calculations” by E. M. Reingold and Nachum Dershowitz,
70   or the documentation of Remind by Roaring Penguin Software Inc.
71 
72   @author Jonathan Singer
73 */
74 class Converter
75 {
76     friend class HebrewDate;
77 
78 public:
79     enum HebrewMonths {
80         Nissan = 1,
81         Iyar,
82         Sivan,
83         Tamuz,
84         Ab,
85         Elul,
86         Tishrei,
87         Cheshvan,
88         Kislev,
89         Tevet,
90         Shvat,
91         Adar,
92         AdarII,
93         AdarI = 12,
94     };
95 
96     enum SecularMonths {
97         January = 1,
98         February,
99         March,
100         April,
101         May,
102         June,
103         July,
104         August,
105         September,
106         October,
107         November,
108         December,
109     };
110 
111 private:
112     static bool hebrew_leap_year_p(int year);
113     static bool gregorian_leap_year_p(int year);
114 
115     static long absolute_from_gregorian(int year, int month, int day);
116     static long absolute_from_hebrew(int year, int month, int day);
117 
118     static void gregorian_from_absolute(long date, int *yearp, int *monthp, int *dayp);
119     static void hebrew_from_absolute(long date, int *yearp, int *monthp, int *dayp);
120 
121     static int hebrew_months_in_year(int year);
122     static int hebrew_month_length(int year, int month);
123     static int secular_month_length(int year, int month);
124 
125     static long hebrew_elapsed_days(int year);
126     static long hebrew_elapsed_days2(int year);
127     static int hebrew_year_length(int year);
128 
129     static void finish_up(long absolute, int hyear, int hmonth, int syear, int smonth, struct DateResult *result);
130 
131     static void secularToHebrewConversion(int year, int month, int day, struct DateResult *result);
132     static void hebrewToSecularConversion(int year, int month, int day, struct DateResult *result);
133 };
134 
135