• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

korganizer

  • sources
  • kde-4.14
  • kdepim
  • korganizer
  • plugins
  • hebrew
converter.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KOrganizer.
3 
4  Copyright (c) 2003 Jonathan Singer <jsinger@leeta.net>
5  Copyright (C) 2007 Loïc Corbasson <loic.corbasson@gmail.com>
6  Calendar routines from Hebrew Calendar by Frank Yellin.
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License along
19  with this program; if not, write to the Free Software Foundation, Inc.,
20  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 
23 #include "converter.h"
24 
25 HebrewDate::HebrewDate( struct DateResult d )
26  : mYear ( d.year ), mMonth ( d.month ), mDay ( d.day ),
27  mDayOfWeek ( d.day_of_week ),
28  mHebrewMonthLength ( d.hebrew_month_length ),
29  mSecularMonthLength ( d.secular_month_length ),
30  mOnHebrewLeapYear ( d.hebrew_leap_year_p ),
31  mOnSecularLeapYear ( d.secular_leap_year_p ),
32  mKvia ( d.kvia ), mHebrewDayNumber ( d.hebrew_day_number )
33 {
34 }
35 
36 HebrewDate::~HebrewDate()
37 {
38 }
39 
40 HebrewDate HebrewDate::fromSecular( int year, int month, int day )
41 {
42  struct DateResult result;
43  Converter::secularToHebrewConversion( year, month, day, &result );
44  return HebrewDate( result );
45 }
46 
47 HebrewDate HebrewDate::fromHebrew( int year, int month, int day )
48 {
49  struct DateResult result;
50  Converter::hebrewToSecularConversion( year, month, day, &result );
51  return HebrewDate( result );
52 }
53 
54 int HebrewDate::year() const
55 {
56  return mYear;
57 }
58 
59 int HebrewDate::month() const
60 {
61  return mMonth;
62 }
63 
64 int HebrewDate::day() const
65 {
66  return mDay;
67 }
68 
69 int HebrewDate::dayOfWeek() const
70 {
71  return mDayOfWeek;
72 }
73 
74 int HebrewDate::hebrewMonthLength() const
75 {
76  return mHebrewMonthLength;
77 }
78 
79 int HebrewDate::secularMonthLength() const
80 {
81  return mSecularMonthLength;
82 }
83 
84 bool HebrewDate::isOnHebrewLeapYear() const
85 {
86  return mOnHebrewLeapYear;
87 }
88 
89 bool HebrewDate::isOnSecularLeapYear() const
90 {
91  return mOnSecularLeapYear;
92 }
93 
94 int HebrewDate::kvia() const
95 {
96  return mKvia;
97 }
98 
99 int HebrewDate::hebrewDayNumber() const
100 {
101  return mHebrewDayNumber;
102 }
103 
105 
106 long Converter::absolute_from_gregorian( int year, int month, int day )
107 {
108  int xyear, day_number;
109 
110  xyear = year - 1;
111  day_number = day + 31 * ( month - 1 );
112  if ( month > 2 ) {
113  day_number -= ( 23 + ( 4 * month ) ) / 10;
114  if ( gregorian_leap_year_p( year ) ) {
115  day_number++;
116  }
117  }
118  return day_number /* the day number within the current year */
119  + 365L * xyear /* days in prior years */
120  + ( xyear / 4 ) /* Julian leap years */
121  + ( -( xyear / 100 ) ) /* deduct century years */
122  + ( xyear / 400 ); /* add Gregorian leap years */
123 }
124 
125 /* Given a Hebrew date, calculate the number of days since January 0, 0001,
126  Gregorian */
127 long Converter::absolute_from_hebrew( int year, int month, int day )
128 {
129  long sum = day + hebrew_elapsed_days( year ) - 1373429L;
130  int i;
131 
132  if ( month < 7 ) {
133  int months = hebrew_months_in_year( year );
134  for ( i = 7; i <= months; ++i ) {
135  sum += hebrew_month_length( year, i );
136  }
137  for ( i = 1; i < month; ++i ) {
138  sum += hebrew_month_length( year, i );
139  }
140  } else {
141  for ( i = 7; i < month; ++i ) {
142  sum += hebrew_month_length( year, i );
143  }
144  }
145  return sum;
146 }
147 
148 /* Given an absolute date, calculate the gregorian date */
149 void Converter::gregorian_from_absolute( long date, int *yearp, int *monthp,
150  int *dayp )
151 {
152  int year, month, day;
153 
154  for ( year = date / 366;
155  date >= absolute_from_gregorian( year + 1, 1, 1 ); ++year ) {}
156 
157  for ( month = 1;
158  ( month <= 11 ) &&
159  ( date >= absolute_from_gregorian( year, 1 + month, 1 ) );
160  ++month ) {}
161 
162  day = 1 + date - absolute_from_gregorian( year, month, 1 );
163  *yearp = year;
164  *monthp = month;
165  *dayp = day;
166 }
167 
168 /* Given an absolute date, calculate the Hebrew date */
169 void Converter::hebrew_from_absolute( long date, int *yearp, int *monthp,
170  int *dayp )
171 {
172  int year, month, day, gyear, gmonth, gday, months;
173 
174  gregorian_from_absolute( date, &gyear, &gmonth, &gday );
175  year = gyear + 3760;
176  while ( date >= absolute_from_hebrew( 1 + year, 7, 1 ) ) {
177  year++;
178  }
179  months = hebrew_months_in_year( year );
180  for ( month = 7;
181  date > absolute_from_hebrew( year, month,
182  hebrew_month_length( year, month ) );
183  month = 1 + ( month % months ) ) {}
184  day = 1 + date - absolute_from_hebrew( year, month, 1 );
185  *yearp = year;
186  *monthp = month;
187  *dayp = day;
188 }
189 
190 /* Number of months in a Hebrew year */
191 int Converter::hebrew_months_in_year( int year )
192 {
193  if ( hebrew_leap_year_p( year ) ) {
194  return 13;
195  } else {
196  return 12;
197  }
198 }
199 
200 /* Number of days in a Hebrew month */
201 int Converter::hebrew_month_length( int year, int month )
202 {
203  switch ( month ) {
204  case Tishrei:
205  case Shvat:
206  case Nissan:
207  case Sivan:
208  case Ab:
209  return 30;
210 
211  case Tevet:
212  case Iyar:
213  case Tamuz:
214  case Elul:
215  case AdarII:
216  return 29;
217 
218  case Cheshvan:
219  // 29 days, unless it's a long year.
220  if ( ( hebrew_year_length( year ) % 10 ) == 5 ) {
221  return 30;
222  } else {
223  return 29;
224  }
225 
226  case Kislev:
227  // 30 days, unless it's a short year.
228  if ( ( hebrew_year_length( year ) % 10 ) == 3 ) {
229  return 29;
230  } else {
231  return 30;
232  }
233 
234  case Adar:
235  // Adar (non-leap year) has 29 days. Adar I has 30 days.
236  if ( hebrew_leap_year_p( year ) ) {
237  return 30;
238  } else {
239  return 29;
240  }
241 
242  default:
243  return 0;
244  }
245 }
246 
247 /* Number of days in a Julian or gregorian month */
248 int Converter::secular_month_length( int year, int month /*, bool julianp */)
249 {
250  switch ( month ) {
251  case January:
252  case March:
253  case May:
254  case July:
255  case August:
256  case October:
257  case December:
258  return 31;
259 
260  case April:
261  case June:
262  case September:
263  case November:
264  return 30;
265 
266  case February:
267  if ( gregorian_leap_year_p( year ) ) {
268  return 29;
269  } else {
270  return 28;
271  }
272 
273  default:
274  return 0;
275  }
276 }
277 
278 /* Is it a leap year in the gregorian calendar */
279 bool Converter::gregorian_leap_year_p( int year )
280 {
281  if ( ( year % 4 ) != 0 ) {
282  return 0;
283  }
284  if ( ( year % 400 ) == 0 ) {
285  return 1;
286  }
287  if ( ( year % 100 ) == 0 ) {
288  return 0;
289  }
290  return 1;
291 }
292 
293 /* Is it a leap year in the Jewish Calendar */
294 bool Converter::hebrew_leap_year_p( int year )
295 {
296  switch ( year % 19 ) {
297  case 0:
298  case 3:
299  case 6:
300  case 8:
301  case 11:
302  case 14:
303  case 17:
304  return 1;
305  default:
306  return 0;
307  }
308 }
309 
310 /* Return the number of days from 1 Tishrei 0001 to the beginning of the given
311  year. Since this routine gets called frequently with the same year arguments,
312  we cache the most recent values. */
313 #define MEMORY 5
314 long Converter::hebrew_elapsed_days( int year )
315 {
316  static int saved_year[MEMORY] = { -1, -1, -1, -1, -1 };
317  static long saved_value[MEMORY];
318  int i;
319 
320  for ( i = 0; i < MEMORY; ++i ) {
321  if ( year == saved_year[i] ) {
322  return saved_value[i];
323  }
324  }
325  for ( i = 0; i < MEMORY-1; ++i ) {
326  saved_year[i] = saved_year[1 + i];
327  saved_value[i] = saved_value[1 + i];
328  }
329  saved_year[MEMORY - 1] = year;
330  saved_value[MEMORY - 1] = hebrew_elapsed_days2( year );
331  return saved_value[MEMORY - 1];
332 }
333 
334 /* Called by hebrew_elapsed_days to make the calculations if the result is not
335  in the cache */
336 long Converter::hebrew_elapsed_days2( int year )
337 {
338  long prev_year = year - 1;
339  long months_elapsed = 235L * ( prev_year / 19 ) +
340  /* months in complete cycles so far */
341  12L * ( prev_year % 19 ) +
342  /* regular months in this cycle */
343  ( ( ( prev_year % 19 ) * 7 + 1 ) / 19 );
344  /* leap months in this cycle */
345  long parts_elapsed = 5604 + 13753 * months_elapsed;
346  long day = 1 + 29 * months_elapsed + parts_elapsed / 25920;
347  long parts = parts_elapsed % 25920;
348  int weekday = day % 7;
349  long alt_day =
350  ( ( parts >= 19440 ) ||
351  ( weekday == 2 && ( parts >= 9924 ) && !hebrew_leap_year_p( year ) ) ||
352  ( weekday == 1 && ( parts >= 16789 ) && hebrew_leap_year_p( prev_year ) ) )
353  ? day + 1 : day;
354 
355  switch ( alt_day % 7 ) {
356  case 0:
357  case 3:
358  case 5:
359  return 1 + alt_day;
360  default:
361  return alt_day;
362  }
363 }
364 
365 /* Number of days in the given Hebrew year */
366 int Converter::hebrew_year_length( int year )
367 {
368  return hebrew_elapsed_days( 1 + year ) - hebrew_elapsed_days( year );
369 }
370 
371 /* Fill in the DateResult structure based on the given secular date */
372 void Converter::secularToHebrewConversion( int syear, int smonth, int sday,
373  struct DateResult *result )
374 {
375  int hyear, hmonth, hday;
376  long absolute;
377 
378  absolute = absolute_from_gregorian( syear, smonth, sday );
379 
380  hebrew_from_absolute( absolute, &hyear, &hmonth, &hday );
381 
382  result->year = hyear;
383  result->month = hmonth;
384  result->day = hday;
385  finish_up( absolute, hyear, hmonth, syear, smonth, result );
386 }
387 
388 /* Fill in the DateResult structure based on the given Hebrew date */
389 void Converter::hebrewToSecularConversion( int hyear, int hmonth, int hday,
390  struct DateResult *result )
391 {
392  int syear, smonth, sday;
393  long absolute;
394 
395  absolute = absolute_from_hebrew( hyear, hmonth, hday );
396  gregorian_from_absolute( absolute, &syear, &smonth, &sday );
397  result->year = hyear;
398  result->month = hmonth;
399  result->day = hday;
400  finish_up( absolute, hyear, hmonth, syear, smonth, result );
401 }
402 
403 /* This is common code for filling up the DateResult structure */
404 void Converter::finish_up( long absolute, int hyear, int hmonth,
405  int syear, int smonth,
406  struct DateResult *result )
407 {
408  result->hebrew_month_length = hebrew_month_length( hyear, hmonth );
409  result->secular_month_length = secular_month_length( syear, smonth );
410  result->hebrew_leap_year_p = hebrew_leap_year_p( hyear );
411  result->secular_leap_year_p = gregorian_leap_year_p( syear );
412  result->kvia = ( hebrew_year_length( hyear ) % 10 ) - 3;
413  // absolute is -1 on 1/1/0001 Julian
414  result->day_of_week = ( 7 + absolute ) % 7;
415  result->hebrew_day_number = absolute - absolute_from_hebrew( hyear, 7, 1 ) + 1;
416 }
417 
DateResult::kvia
int kvia
Definition: converter.h:35
DateResult::hebrew_day_number
int hebrew_day_number
Definition: converter.h:36
DateResult::hebrew_leap_year_p
bool hebrew_leap_year_p
Definition: converter.h:34
Converter::March
Definition: converter.h:110
HebrewDate::hebrewMonthLength
int hebrewMonthLength() const
Definition: converter.cpp:74
Converter::Kislev
Definition: converter.h:99
Converter::Sivan
Definition: converter.h:93
HebrewDate::fromHebrew
static HebrewDate fromHebrew(int year, int month, int day)
Definition: converter.cpp:47
Converter::July
Definition: converter.h:114
Converter::Cheshvan
Definition: converter.h:98
HebrewDate::fromSecular
static HebrewDate fromSecular(int year, int month, int day)
Definition: converter.cpp:40
DateResult::day_of_week
int day_of_week
Definition: converter.h:31
Converter::February
Definition: converter.h:109
Converter::Iyar
Definition: converter.h:92
DateResult::hebrew_month_length
int hebrew_month_length
Definition: converter.h:33
HebrewDate::isOnSecularLeapYear
bool isOnSecularLeapYear() const
Definition: converter.cpp:89
HebrewDate::month
int month() const
Definition: converter.cpp:59
Converter::Elul
Definition: converter.h:96
HebrewDate
This class converts dates between the Hebrew and Gregorian (secular) calendars.
Definition: converter.h:45
DateResult::day
int day
Definition: converter.h:30
DateResult::month
int month
Definition: converter.h:29
HebrewDate::HebrewDate
HebrewDate(struct DateResult)
Definition: converter.cpp:25
Converter::August
Definition: converter.h:115
HebrewDate::year
int year() const
Definition: converter.cpp:54
DateResult::year
int year
Definition: converter.h:28
Converter::Ab
Definition: converter.h:95
MEMORY
#define MEMORY
Definition: converter.cpp:313
converter.h
Converter::Tamuz
Definition: converter.h:94
HebrewDate::hebrewDayNumber
int hebrewDayNumber() const
Definition: converter.cpp:99
HebrewDate::isOnHebrewLeapYear
bool isOnHebrewLeapYear() const
Definition: converter.cpp:84
Converter::June
Definition: converter.h:113
DateResult::secular_month_length
int secular_month_length
Definition: converter.h:33
Converter::May
Definition: converter.h:112
HebrewDate::~HebrewDate
~HebrewDate()
Definition: converter.cpp:36
Converter::Tishrei
Definition: converter.h:97
Converter::December
Definition: converter.h:119
HebrewDate::day
int day() const
Definition: converter.cpp:64
Converter::Tevet
Definition: converter.h:100
Converter::Shvat
Definition: converter.h:101
HebrewDate::kvia
int kvia() const
Definition: converter.cpp:94
Converter::January
Definition: converter.h:108
Converter::AdarII
Definition: converter.h:103
Converter::Nissan
Definition: converter.h:91
HebrewDate::dayOfWeek
int dayOfWeek() const
Definition: converter.cpp:69
DateResult
Definition: converter.h:26
DateResult::secular_leap_year_p
bool secular_leap_year_p
Definition: converter.h:34
Converter::October
Definition: converter.h:117
Converter::April
Definition: converter.h:111
Converter::Adar
Definition: converter.h:102
Converter::September
Definition: converter.h:116
HebrewDate::secularMonthLength
int secularMonthLength() const
Definition: converter.cpp:79
Converter::November
Definition: converter.h:118
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:59 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

korganizer

Skip menu "korganizer"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal