• 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
43static 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
61class GregorianDate {
62private:
63 int year; // 1...
64 int month; // 1 == January, ..., 12 == December
65 int day; // 1..lastDayOfGregorianMonth(month, year)
66
67public:
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
101static 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
110static const int IslamicEpoch = 227014; // Absolute date of start of
111 // Islamic calendar
112
113static 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
122class IslamicDate {
123private:
124 int year; // 1...
125 int month; // 1..13 (12 in a common year)
126 int day; // 1..lastDayOfIslamicMonth(month,year)
127
128public:
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
165static 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
181KCalendarSystemHijri::KCalendarSystemHijri(const TDELocale * locale)
182 : KCalendarSystem(locale)
183{
184}
185
186KCalendarSystemHijri::~KCalendarSystemHijri()
187{
188}
189
190int KCalendarSystemHijri::year(const TQDate& date) const
191{
192 int y;
193 gregorianToHijri(date, &y, 0, 0);
194 return y;
195}
196
197int KCalendarSystemHijri::month(const TQDate& date) const
198{
199 int m;
200 gregorianToHijri(date, 0, &m, 0);
201 return m;
202}
203
204int KCalendarSystemHijri::day(const TQDate& date) const
205{
206 int d;
207 gregorianToHijri(date, 0, 0, &d);
208 return d;
209}
210
211int KCalendarSystemHijri::monthsInYear( const TQDate & date ) const
212{
213 Q_UNUSED( date )
214
215 return 12;
216}
217
218int 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
231int 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
277TQString KCalendarSystemHijri::monthName(const TQDate& date,
278 bool shortName) const
279{
280 return monthName(month(date), year(date), shortName);
281}
282
283TQString KCalendarSystemHijri::monthNamePossessive(const TQDate& date,
284 bool shortName) const
285{
286 return monthNamePossessive(month(date), year(date), shortName);
287}
288
289TQString 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
354TQString 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
419bool 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
439TQString 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
481TQString KCalendarSystemHijri::weekDayName(const TQDate& date,
482 bool shortName) const
483{
484 return weekDayName(dayOfWeek(date), shortName);
485}
486
487int KCalendarSystemHijri::dayOfWeek(const TQDate& date) const
488{
489 return date.dayOfWeek(); // same as gregorian
490}
491
492int 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
502int 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
511int 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
519int KCalendarSystemHijri::maxValidYear() const
520{
521 TQDate date(8000, 1, 1);
522
523 return year(date);
524}
525
526int 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
535int KCalendarSystemHijri::weekDayOfPray() const
536{
537 return 5; // friday
538}
539
540TQDate KCalendarSystemHijri::addDays( const TQDate & date, int ndays ) const
541{
542 return date.addDays( ndays );
543}
544
545TQDate 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
568TQDate 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
578TQString KCalendarSystemHijri::calendarName() const
579{
580 return TQString::fromLatin1("hijri");
581}
582
583bool KCalendarSystemHijri::isLunar() const
584{
585 return true;
586}
587
588bool KCalendarSystemHijri::isLunisolar() const
589{
590 return false;
591}
592
593bool 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.4
This website is maintained by Timothy Pearson.