• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
kcalendarsystemhijri.cpp
1 /*
2  Copyright (c) 2002-2003 Carlos Moro <cfmoro@correo.uniovi.es>
3  Copyright (c) 2002-2003 Hans Petter Bieker <bieker@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 // Derived hijri kde calendar class
22 
23 #include <tqdatetime.h>
24 #include <tqstring.h>
25 
26 #include <tdelocale.h>
27 #include <kdebug.h>
28 
29 #include "kcalendarsystemhijri.h"
30 
31 /*
32  The following C++ code is translated from the Lisp code
33  in ``Calendrical Calculations'' by Nachum Dershowitz and
34  Edward M. Reingold, Software---Practice & Experience,
35  vol. 20, no. 9 (September, 1990), pp. 899--928.
36 
37  This code is in the public domain, but any use of it
38  should publically acknowledge its source.
39 
40  Classes GregorianDate, IslamicDate
41  */
42 
43 static int lastDayOfGregorianMonth(int month, int year) {
44 // Compute the last date of the month for the Gregorian calendar.
45 
46  switch (month) {
47  case 2:
48  if ((((year % 4) == 0) && ((year % 100) != 0))
49  || ((year % 400) == 0))
50  return 29;
51  else
52  return 28;
53  case 4:
54  case 6:
55  case 9:
56  case 11: return 30;
57  default: return 31;
58  }
59 }
60 
61 class GregorianDate {
62 private:
63  int year; // 1...
64  int month; // 1 == January, ..., 12 == December
65  int day; // 1..lastDayOfGregorianMonth(month, year)
66 
67 public:
68  GregorianDate(int m, int d, int y) { month = m; day = d; year = y; }
69 
70  GregorianDate(int d) { // Computes the Gregorian date from the absolute date.
71 
72  // Search forward year by year from approximate year
73  year = d/366;
74  while (d >= GregorianDate(1,1,year+1))
75  year++;
76  // Search forward month by month from January
77  month = 1;
78  while (d > GregorianDate(month, lastDayOfGregorianMonth(month,year), year))
79  month++;
80  day = d - GregorianDate(month,1,year) + 1;
81  }
82 
83  operator int() { // Computes the absolute date from the Gregorian date.
84  int N = day; // days this month
85  for (int m = month - 1; m > 0; m--) // days in prior months this year
86  N = N + lastDayOfGregorianMonth(m, year);
87  return
88  (N // days this year
89  + 365 * (year - 1) // days in previous years ignoring leap days
90  + (year - 1)/4 // Julian leap days before this year...
91  - (year - 1)/100 // ...minus prior century years...
92  + (year - 1)/400); // ...plus prior years divisible by 400
93  }
94 
95  int getMonth() { return month; }
96  int getDay() { return day; }
97  int getYear() { return year; }
98 
99 };
100 
101 static int IslamicLeapYear(int year) {
102 // True if year is an Islamic leap year
103 
104  if ((((11 * year) + 14) % 30) < 11)
105  return 1;
106  else
107  return 0;
108 }
109 
110 static const int IslamicEpoch = 227014; // Absolute date of start of
111  // Islamic calendar
112 
113 static int lastDayOfIslamicMonth(int month, int year) {
114 // Last day in month during year on the Islamic calendar.
115 
116  if (((month % 2) == 1) || ((month == 12) && IslamicLeapYear(year)))
117  return 30;
118  else
119  return 29;
120 }
121 
122 class IslamicDate {
123 private:
124  int year; // 1...
125  int month; // 1..13 (12 in a common year)
126  int day; // 1..lastDayOfIslamicMonth(month,year)
127 
128 public:
129  IslamicDate(int m, int d, int y) { month = m; day = d; year = y; }
130 
131  IslamicDate(int d) { // Computes the Islamic date from the absolute date.
132  if (d <= IslamicEpoch) { // Date is pre-Islamic
133  month = 0;
134  day = 0;
135  year = 0;
136  }
137  else {
138  // Search forward year by year from approximate year
139  year = (d - IslamicEpoch) / 355;
140  while (d >= IslamicDate(1,1,year+1))
141  year++;
142  // Search forward month by month from Muharram
143  month = 1;
144  while (d > IslamicDate(month, lastDayOfIslamicMonth(month,year), year))
145  month++;
146  day = d - IslamicDate(month,1,year) + 1;
147  }
148  }
149 
150  operator int() { // Computes the absolute date from the Islamic date.
151  return (day // days so far this month
152  + 29 * (month - 1) // days so far...
153  + month/2 // ...this year
154  + 354 * (year - 1) // non-leap days in prior years
155  + (3 + (11 * year)) / 30 // leap days in prior years
156  + IslamicEpoch); // days before start of calendar
157  }
158 
159  int getMonth() { return month; }
160  int getDay() { return day; }
161  int getYear() { return year; }
162 
163 };
164 
165 static void gregorianToHijri(const TQDate & date, int * pYear, int * pMonth,
166  int * pDay)
167 {
168  GregorianDate gregorian(date.month(),date.day(),date.year());
169  int absolute = gregorian;
170 
171  IslamicDate islamic(absolute);
172 
173  if (pYear)
174  *pYear = islamic.getYear();
175  if (pMonth)
176  *pMonth = islamic.getMonth();
177  if (pDay)
178  *pDay = islamic.getDay();
179 }
180 
181 KCalendarSystemHijri::KCalendarSystemHijri(const TDELocale * locale)
182  : KCalendarSystem(locale)
183 {
184 }
185 
186 KCalendarSystemHijri::~KCalendarSystemHijri()
187 {
188 }
189 
190 int KCalendarSystemHijri::year(const TQDate& date) const
191 {
192  int y;
193  gregorianToHijri(date, &y, 0, 0);
194  return y;
195 }
196 
197 int KCalendarSystemHijri::month(const TQDate& date) const
198 {
199  int m;
200  gregorianToHijri(date, 0, &m, 0);
201  return m;
202 }
203 
204 int KCalendarSystemHijri::day(const TQDate& date) const
205 {
206  int d;
207  gregorianToHijri(date, 0, 0, &d);
208  return d;
209 }
210 
211 int KCalendarSystemHijri::monthsInYear( const TQDate & date ) const
212 {
213  Q_UNUSED( date )
214 
215  return 12;
216 }
217 
218 int KCalendarSystemHijri::weeksInYear(int year) const
219 {
220  TQDate temp;
221  setYMD(temp, year, 12, lastDayOfIslamicMonth(12, year));
222 
223  // If the last day of the year is in the first week, we have to check the
224  // week before
225  if ( weekNumber(temp) == 1 )
226  temp = addDays(temp, -7);
227 
228  return weekNumber(temp);
229 }
230 
231 int KCalendarSystemHijri::weekNumber(const TQDate& date, int * yearNum) const
232 {
233  TQDate firstDayWeek1, lastDayOfYear;
234  int y = year(date);
235  int week;
236  int weekDay1, dayOfWeek1InYear;
237 
238  // let's guess 1st day of 1st week
239  setYMD(firstDayWeek1, y, 1, 1);
240  weekDay1 = dayOfWeek(firstDayWeek1);
241 
242  // iso 8601: week 1 is the first containing thursday and week starts on
243  // monday
244  if (weekDay1 > 4 )
245  firstDayWeek1 = addDays(firstDayWeek1 , 7 - weekDay1 + 1); // next monday
246 
247  dayOfWeek1InYear = dayOfYear(firstDayWeek1);
248 
249  if ( dayOfYear(date) < dayOfWeek1InYear ) // our date in prev year's week
250  {
251  if ( yearNum )
252  *yearNum = y - 1;
253  return weeksInYear(y - 1);
254  }
255 
256  // let' check if its last week belongs to next year
257  setYMD(lastDayOfYear, y, 12, lastDayOfIslamicMonth(12, y));
258  if ( (dayOfYear(date) >= daysInYear(date) - dayOfWeek(lastDayOfYear) + 1)
259  // our date is in last week
260  && dayOfWeek(lastDayOfYear) < 4) // 1st week in next year has thursday
261  {
262  if ( yearNum )
263  *yearNum = y + 1;
264  week = 1;
265  }
266  else
267  {
268  if ( weekDay1 < 5 )
269  firstDayWeek1 = addDays(firstDayWeek1, - (weekDay1 - 1));
270 
271  week = firstDayWeek1.daysTo(date) / 7 + 1;
272  }
273 
274  return week;
275 }
276 
277 TQString KCalendarSystemHijri::monthName(const TQDate& date,
278  bool shortName) const
279 {
280  return monthName(month(date), year(date), shortName);
281 }
282 
283 TQString KCalendarSystemHijri::monthNamePossessive(const TQDate& date,
284  bool shortName) const
285 {
286  return monthNamePossessive(month(date), year(date), shortName);
287 }
288 
289 TQString KCalendarSystemHijri::monthName(int month, int year, bool shortName)
290  const {
291 
292  Q_UNUSED(year);
293 
294  if (shortName)
295  switch ( month )
296  {
297  case 1:
298  return locale()->translate("Muharram");
299  case 2:
300  return locale()->translate("Safar");
301  case 3:
302  return locale()->translate("R. Awal");
303  case 4:
304  return locale()->translate("R. Thaani");
305  case 5:
306  return locale()->translate("J. Awal");
307  case 6:
308  return locale()->translate("J. Thaani");
309  case 7:
310  return locale()->translate("Rajab");
311  case 8:
312  return locale()->translate("Sha`ban");
313  case 9:
314  return locale()->translate("Ramadan");
315  case 10:
316  return locale()->translate("Shawwal");
317  case 11:
318  return locale()->translate("Qi`dah");
319  case 12:
320  return locale()->translate("Hijjah");
321  }
322  else
323  switch ( month )
324  {
325  case 1:
326  return locale()->translate("Muharram");
327  case 2:
328  return locale()->translate("Safar");
329  case 3:
330  return locale()->translate("Rabi` al-Awal");
331  case 4:
332  return locale()->translate("Rabi` al-Thaani");
333  case 5:
334  return locale()->translate("Jumaada al-Awal");
335  case 6:
336  return locale()->translate("Jumaada al-Thaani");
337  case 7:
338  return locale()->translate("Rajab");
339  case 8:
340  return locale()->translate("Sha`ban");
341  case 9:
342  return locale()->translate("Ramadan");
343  case 10:
344  return locale()->translate("Shawwal");
345  case 11:
346  return locale()->translate("Thu al-Qi`dah");
347  case 12:
348  return locale()->translate("Thu al-Hijjah");
349  }
350 
351  return TQString::null;
352 }
353 
354 TQString KCalendarSystemHijri::monthNamePossessive(int month, int year,
355  bool shortName) const
356 {
357  Q_UNUSED(year);
358 
359  if (shortName)
360  switch ( month )
361  {
362  case 1:
363  return locale()->translate("of Muharram");
364  case 2:
365  return locale()->translate("of Safar");
366  case 3:
367  return locale()->translate("of R. Awal");
368  case 4:
369  return locale()->translate("of R. Thaani");
370  case 5:
371  return locale()->translate("of J. Awal");
372  case 6:
373  return locale()->translate("of J. Thaani");
374  case 7:
375  return locale()->translate("of Rajab");
376  case 8:
377  return locale()->translate("of Sha`ban");
378  case 9:
379  return locale()->translate("of Ramadan");
380  case 10:
381  return locale()->translate("of Shawwal");
382  case 11:
383  return locale()->translate("of Qi`dah");
384  case 12:
385  return locale()->translate("of Hijjah");
386  }
387  else
388  switch ( month )
389  {
390  case 1:
391  return locale()->translate("of Muharram");
392  case 2:
393  return locale()->translate("of Safar");
394  case 3:
395  return locale()->translate("of Rabi` al-Awal");
396  case 4:
397  return locale()->translate("of Rabi` al-Thaani");
398  case 5:
399  return locale()->translate("of Jumaada al-Awal");
400  case 6:
401  return locale()->translate("of Jumaada al-Thaani");
402  case 7:
403  return locale()->translate("of Rajab");
404  case 8:
405  return locale()->translate("of Sha`ban");
406  case 9:
407  return locale()->translate("of Ramadan");
408  case 10:
409  return locale()->translate("of Shawwal");
410  case 11:
411  return locale()->translate("of Thu al-Qi`dah");
412  case 12:
413  return locale()->translate("of Thu al-Hijjah");
414  }
415 
416  return TQString::null;
417 }
418 
419 bool KCalendarSystemHijri::setYMD(TQDate & date, int y, int m, int d) const
420 {
421  // range checks
422  if ( y < minValidYear() || y > maxValidYear() )
423  return false;
424 
425  if ( m < 1 || m > 12 )
426  return false;
427 
428  if ( d < 1 || d > lastDayOfIslamicMonth(m, y) )
429  return false;
430 
431  IslamicDate islamic (m, d, y);
432  int absolute = islamic;
433  GregorianDate gregorian(absolute);
434 
435  return date.setYMD(gregorian.getYear(), gregorian.getMonth(),
436  gregorian.getDay());
437 }
438 
439 TQString KCalendarSystemHijri::weekDayName(int day, bool shortName) const
440 {
441  if ( shortName )
442  switch (day)
443  {
444  case 1:
445  return locale()->translate("Ith");
446  case 2:
447  return locale()->translate("Thl");
448  case 3:
449  return locale()->translate("Arb");
450  case 4:
451  return locale()->translate("Kha");
452  case 5:
453  return locale()->translate("Jum");
454  case 6:
455  return locale()->translate("Sab");
456  case 7:
457  return locale()->translate("Ahd");
458  }
459  else
460  switch ( day )
461  {
462  case 1:
463  return locale()->translate("Yaum al-Ithnain");
464  case 2:
465  return locale()->translate("Yau al-Thulatha");
466  case 3:
467  return locale()->translate("Yaum al-Arbi'a");
468  case 4:
469  return locale()->translate("Yaum al-Khamees");
470  case 5:
471  return locale()->translate("Yaum al-Jumma");
472  case 6:
473  return locale()->translate("Yaum al-Sabt");
474  case 7:
475  return locale()->translate("Yaum al-Ahad");
476  }
477 
478  return TQString::null;
479 }
480 
481 TQString KCalendarSystemHijri::weekDayName(const TQDate& date,
482  bool shortName) const
483 {
484  return weekDayName(dayOfWeek(date), shortName);
485 }
486 
487 int KCalendarSystemHijri::dayOfWeek(const TQDate& date) const
488 {
489  return date.dayOfWeek(); // same as gregorian
490 }
491 
492 int KCalendarSystemHijri::dayOfYear(const TQDate & date) const
493 {
494  TQDate first;
495  setYMD(first, year(date), 1, 1);
496 
497  return first.daysTo(date) + 1;
498 
499  return 100;
500 }
501 
502 int KCalendarSystemHijri::daysInMonth(const TQDate& date) const
503 {
504  int y, m;
505  gregorianToHijri(date, &y, &m, 0);
506 
507  return lastDayOfIslamicMonth(m, y);
508 }
509 
510 // Min valid year that may be converted to QDate
511 int KCalendarSystemHijri::minValidYear() const
512 {
513  TQDate date(1753, 1, 1);
514 
515  return year(date);
516 }
517 
518 // Max valid year that may be converted to QDate
519 int KCalendarSystemHijri::maxValidYear() const
520 {
521  TQDate date(8000, 1, 1);
522 
523  return year(date);
524 }
525 
526 int KCalendarSystemHijri::daysInYear(const TQDate & date) const
527 {
528  TQDate first, last;
529  setYMD(first, year(date), 1, 1);
530  setYMD(last, year(date) + 1, 1, 1);
531 
532  return first.daysTo(last);
533 }
534 
535 int KCalendarSystemHijri::weekDayOfPray() const
536 {
537  return 5; // friday
538 }
539 
540 TQDate KCalendarSystemHijri::addDays( const TQDate & date, int ndays ) const
541 {
542  return date.addDays( ndays );
543 }
544 
545 TQDate KCalendarSystemHijri::addMonths( const TQDate & date, int nmonths ) const
546 {
547  TQDate result = date;
548  int m = month(date);
549  int y = year(date);
550 
551  if ( nmonths < 0 )
552  {
553  m += 12;
554  y -= 1;
555  }
556 
557  --m; // this only works if we start counting at zero
558  m += nmonths;
559  y += m / 12;
560  m %= 12;
561  ++m;
562 
563  setYMD( result, y, m, day(date) );
564 
565  return result;
566 }
567 
568 TQDate KCalendarSystemHijri::addYears( const TQDate & date, int nyears ) const
569 {
570  TQDate result = date;
571  int y = year(date) + nyears;
572 
573  setYMD( result, y, month(date), day(date) );
574 
575  return result;
576 }
577 
578 TQString KCalendarSystemHijri::calendarName() const
579 {
580  return TQString::fromLatin1("hijri");
581 }
582 
583 bool KCalendarSystemHijri::isLunar() const
584 {
585  return true;
586 }
587 
588 bool KCalendarSystemHijri::isLunisolar() const
589 {
590  return false;
591 }
592 
593 bool KCalendarSystemHijri::isSolar() const
594 {
595  return false;
596 }
KCalendarSystem
CalendarSystem abstract class, default derived kde gregorian class and factory class.
Definition: kcalendarsystem.h:43
TDELocale
TDELocale provides support for country specific stuff like the national language.
Definition: tdelocale.h:124
tdelocale.h

tdecore

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

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.1
This website is maintained by Timothy Pearson.