• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KDECore

kcalendarsystemhijri.cpp

Go to the documentation of this file.
00001 /*
00002    Copyright (c) 2002-2003 Carlos Moro <cfmoro@correo.uniovi.es>
00003    Copyright (c) 2002-2003 Hans Petter Bieker <bieker@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 // Derived hijri kde calendar class
00022 
00023 #include <qdatetime.h>
00024 #include <qstring.h>
00025 
00026 #include <klocale.h>
00027 #include <kdebug.h>
00028 
00029 #include "kcalendarsystemhijri.h"
00030 
00031 /*
00032   The following C++ code is translated from the Lisp code
00033   in ``Calendrical Calculations'' by Nachum Dershowitz and
00034   Edward M. Reingold, Software---Practice & Experience,
00035   vol. 20, no. 9 (September, 1990), pp. 899--928.
00036 
00037   This code is in the public domain, but any use of it
00038   should publically acknowledge its source.
00039 
00040   Classes GregorianDate, IslamicDate
00041  */
00042 
00043 static int lastDayOfGregorianMonth(int month, int year) {
00044 // Compute the last date of the month for the Gregorian calendar.
00045 
00046   switch (month) {
00047   case 2:
00048     if ((((year % 4) == 0) && ((year % 100) != 0))
00049         || ((year % 400) == 0))
00050       return 29;
00051     else
00052       return 28;
00053   case 4:
00054   case 6:
00055   case 9:
00056   case 11: return 30;
00057   default: return 31;
00058   }
00059 }
00060 
00061 class GregorianDate {
00062 private:
00063   int year;   // 1...
00064   int month;  // 1 == January, ..., 12 == December
00065   int day;    // 1..lastDayOfGregorianMonth(month, year)
00066 
00067 public:
00068   GregorianDate(int m, int d, int y) { month = m; day = d; year = y; }
00069 
00070   GregorianDate(int d) { // Computes the Gregorian date from the absolute date.
00071 
00072     // Search forward year by year from approximate year
00073     year = d/366;
00074     while (d >= GregorianDate(1,1,year+1))
00075       year++;
00076     // Search forward month by month from January
00077     month = 1;
00078     while (d > GregorianDate(month, lastDayOfGregorianMonth(month,year), year))
00079       month++;
00080     day = d - GregorianDate(month,1,year) + 1;
00081   }
00082 
00083   operator int() { // Computes the absolute date from the Gregorian date.
00084     int N = day;           // days this month
00085     for (int m = month - 1;  m > 0; m--) // days in prior months this year
00086       N = N + lastDayOfGregorianMonth(m, year);
00087     return
00088       (N                    // days this year
00089        + 365 * (year - 1)   // days in previous years ignoring leap days
00090        + (year - 1)/4       // Julian leap days before this year...
00091        - (year - 1)/100     // ...minus prior century years...
00092        + (year - 1)/400);   // ...plus prior years divisible by 400
00093   }
00094 
00095   int getMonth() { return month; }
00096   int getDay() { return day; }
00097   int getYear() { return year; }
00098 
00099 };
00100 
00101 static int IslamicLeapYear(int year) {
00102 // True if year is an Islamic leap year
00103 
00104   if ((((11 * year) + 14) % 30) < 11)
00105     return 1;
00106   else
00107     return 0;
00108 }
00109 
00110 static const int IslamicEpoch = 227014; // Absolute date of start of
00111                                         // Islamic calendar
00112 
00113 static int lastDayOfIslamicMonth(int month, int year) {
00114 // Last day in month during year on the Islamic calendar.
00115 
00116   if (((month % 2) == 1) || ((month == 12) && IslamicLeapYear(year)))
00117     return 30;
00118   else
00119     return 29;
00120 }
00121 
00122 class IslamicDate {
00123 private:
00124   int year;   // 1...
00125   int month;  // 1..13 (12 in a common year)
00126   int day;    // 1..lastDayOfIslamicMonth(month,year)
00127 
00128 public:
00129   IslamicDate(int m, int d, int y) { month = m; day = d; year = y; }
00130 
00131   IslamicDate(int d) { // Computes the Islamic date from the absolute date.
00132     if (d <= IslamicEpoch) { // Date is pre-Islamic
00133       month = 0;
00134       day = 0;
00135       year = 0;
00136     }
00137     else {
00138       // Search forward year by year from approximate year
00139       year = (d - IslamicEpoch) / 355;
00140       while (d >= IslamicDate(1,1,year+1))
00141         year++;
00142       // Search forward month by month from Muharram
00143       month = 1;
00144       while (d > IslamicDate(month, lastDayOfIslamicMonth(month,year), year))
00145         month++;
00146       day = d - IslamicDate(month,1,year) + 1;
00147     }
00148   }
00149 
00150   operator int() { // Computes the absolute date from the Islamic date.
00151     return (day                      // days so far this month
00152             + 29 * (month - 1)       // days so far...
00153             + month/2                //            ...this year
00154             + 354 * (year - 1)       // non-leap days in prior years
00155             + (3 + (11 * year)) / 30 // leap days in prior years
00156             + IslamicEpoch);                // days before start of calendar
00157   }
00158 
00159   int getMonth() { return month; }
00160   int getDay() { return day; }
00161   int getYear() { return year; }
00162 
00163 };
00164 
00165 static void gregorianToHijri(const QDate & date, int * pYear, int * pMonth,
00166    int * pDay)
00167 {
00168   GregorianDate gregorian(date.month(),date.day(),date.year());
00169   int absolute = gregorian;
00170 
00171   IslamicDate islamic(absolute);
00172 
00173   if (pYear)
00174     *pYear = islamic.getYear();
00175   if (pMonth)
00176     *pMonth = islamic.getMonth();
00177   if (pDay)
00178     *pDay = islamic.getDay();
00179 }
00180 
00181 KCalendarSystemHijri::KCalendarSystemHijri(const KLocale * locale)
00182   : KCalendarSystem(locale)
00183 {
00184 }
00185 
00186 KCalendarSystemHijri::~KCalendarSystemHijri()
00187 {
00188 }
00189 
00190 int KCalendarSystemHijri::year(const QDate& date) const
00191 {
00192   int y;
00193   gregorianToHijri(date, &y, 0, 0);
00194   return y;
00195 }
00196 
00197 int KCalendarSystemHijri::month(const QDate& date) const
00198 {
00199   int m;
00200   gregorianToHijri(date, 0, &m, 0);
00201   return m;
00202 }
00203 
00204 int KCalendarSystemHijri::day(const QDate& date) const
00205 {
00206   int d;
00207   gregorianToHijri(date, 0, 0, &d);
00208   return d;
00209 }
00210 
00211 int KCalendarSystemHijri::monthsInYear( const QDate & date ) const
00212 {
00213   Q_UNUSED( date )
00214 
00215   return 12;
00216 }
00217 
00218 int KCalendarSystemHijri::weeksInYear(int year) const
00219 {
00220   QDate temp;
00221   setYMD(temp, year, 12, lastDayOfIslamicMonth(12, year));
00222 
00223   // If the last day of the year is in the first week, we have to check the
00224   // week before
00225   if ( weekNumber(temp) == 1 )
00226     temp = addDays(temp, -7);
00227 
00228   return weekNumber(temp);
00229 }
00230 
00231 int KCalendarSystemHijri::weekNumber(const QDate& date, int * yearNum) const
00232 {
00233   QDate firstDayWeek1, lastDayOfYear;
00234   int y = year(date);
00235   int week;
00236   int weekDay1, dayOfWeek1InYear;
00237 
00238   // let's guess 1st day of 1st week
00239   setYMD(firstDayWeek1, y, 1, 1);
00240   weekDay1 = dayOfWeek(firstDayWeek1);
00241 
00242   // iso 8601: week 1  is the first containing thursday and week starts on
00243   // monday
00244   if (weekDay1 > 4 )
00245     firstDayWeek1 = addDays(firstDayWeek1 , 7 - weekDay1 + 1); // next monday
00246 
00247   dayOfWeek1InYear = dayOfYear(firstDayWeek1);
00248 
00249   if ( dayOfYear(date) < dayOfWeek1InYear ) // our date in prev year's week
00250   {
00251     if ( yearNum )
00252       *yearNum = y - 1;
00253     return weeksInYear(y - 1);
00254   }
00255 
00256   // let' check if its last week belongs to next year
00257   setYMD(lastDayOfYear, y, 12, lastDayOfIslamicMonth(12, y));
00258   if ( (dayOfYear(date) >= daysInYear(date) - dayOfWeek(lastDayOfYear) + 1)
00259        // our date is in last week
00260        && dayOfWeek(lastDayOfYear) < 4) // 1st week in next year has thursday
00261     {
00262       if ( yearNum )
00263         *yearNum = y + 1;
00264       week = 1;
00265     }
00266   else
00267   {
00268     if ( weekDay1 < 5 )
00269       firstDayWeek1 = addDays(firstDayWeek1, - (weekDay1 - 1));
00270 
00271     week = firstDayWeek1.daysTo(date) / 7 + 1;
00272   }
00273 
00274   return week;
00275 }
00276 
00277 QString KCalendarSystemHijri::monthName(const QDate& date,
00278                                         bool shortName) const
00279 {
00280   return monthName(month(date), year(date), shortName);
00281 }
00282 
00283 QString KCalendarSystemHijri::monthNamePossessive(const QDate& date,
00284                                                   bool shortName) const
00285 {
00286   return monthNamePossessive(month(date), year(date), shortName);
00287 }
00288 
00289 QString KCalendarSystemHijri::monthName(int month, int year, bool shortName)
00290   const {
00291 
00292   Q_UNUSED(year);
00293 
00294   if (shortName)
00295     switch ( month )
00296       {
00297       case 1:
00298         return locale()->translate("Muharram");
00299       case 2:
00300         return locale()->translate("Safar");
00301       case 3:
00302         return locale()->translate("R. Awal");
00303       case 4:
00304         return locale()->translate("R. Thaani");
00305       case 5:
00306         return locale()->translate("J. Awal");
00307       case 6:
00308         return locale()->translate("J. Thaani");
00309       case 7:
00310         return locale()->translate("Rajab");
00311       case 8:
00312         return locale()->translate("Sha`ban");
00313       case 9:
00314         return locale()->translate("Ramadan");
00315       case 10:
00316         return locale()->translate("Shawwal");
00317       case 11:
00318         return locale()->translate("Qi`dah");
00319       case 12:
00320         return locale()->translate("Hijjah");
00321     }
00322   else
00323     switch ( month )
00324       {
00325       case 1:
00326         return locale()->translate("Muharram");
00327       case 2:
00328         return locale()->translate("Safar");
00329       case 3:
00330         return locale()->translate("Rabi` al-Awal");
00331       case 4:
00332         return locale()->translate("Rabi` al-Thaani");
00333       case 5:
00334         return locale()->translate("Jumaada al-Awal");
00335       case 6:
00336         return locale()->translate("Jumaada al-Thaani");
00337       case 7:
00338         return locale()->translate("Rajab");
00339       case 8:
00340         return locale()->translate("Sha`ban");
00341       case 9:
00342         return locale()->translate("Ramadan");
00343       case 10:
00344         return locale()->translate("Shawwal");
00345       case 11:
00346         return locale()->translate("Thu al-Qi`dah");
00347       case 12:
00348         return locale()->translate("Thu al-Hijjah");
00349       }
00350 
00351   return QString::null;
00352 }
00353 
00354 QString KCalendarSystemHijri::monthNamePossessive(int month, int year,
00355                                                   bool shortName) const
00356 {
00357   Q_UNUSED(year);
00358 
00359   if (shortName)
00360     switch ( month )
00361       {
00362       case 1:
00363         return locale()->translate("of Muharram");
00364       case 2:
00365         return locale()->translate("of Safar");
00366       case 3:
00367         return locale()->translate("of R. Awal");
00368       case 4:
00369         return locale()->translate("of R. Thaani");
00370       case 5:
00371         return locale()->translate("of J. Awal");
00372       case 6:
00373         return locale()->translate("of J. Thaani");
00374       case 7:
00375         return locale()->translate("of Rajab");
00376       case 8:
00377         return locale()->translate("of Sha`ban");
00378       case 9:
00379         return locale()->translate("of Ramadan");
00380       case 10:
00381         return locale()->translate("of Shawwal");
00382       case 11:
00383         return locale()->translate("of Qi`dah");
00384       case 12:
00385         return locale()->translate("of Hijjah");
00386     }
00387   else
00388     switch ( month )
00389       {
00390       case 1:
00391         return locale()->translate("of Muharram");
00392       case 2:
00393         return locale()->translate("of Safar");
00394       case 3:
00395         return locale()->translate("of Rabi` al-Awal");
00396       case 4:
00397         return locale()->translate("of Rabi` al-Thaani");
00398       case 5:
00399         return locale()->translate("of Jumaada al-Awal");
00400       case 6:
00401         return locale()->translate("of Jumaada al-Thaani");
00402       case 7:
00403         return locale()->translate("of Rajab");
00404       case 8:
00405         return locale()->translate("of Sha`ban");
00406       case 9:
00407         return locale()->translate("of Ramadan");
00408       case 10:
00409         return locale()->translate("of Shawwal");
00410       case 11:
00411         return locale()->translate("of Thu al-Qi`dah");
00412       case 12:
00413         return locale()->translate("of Thu al-Hijjah");
00414       }
00415 
00416   return QString::null;
00417 }
00418 
00419 bool KCalendarSystemHijri::setYMD(QDate & date, int y, int m, int d) const
00420 {
00421   // range checks
00422   if ( y < minValidYear() || y > maxValidYear() )
00423     return false;
00424 
00425   if ( m < 1 || m > 12 )
00426     return false;
00427 
00428   if ( d < 1 || d > lastDayOfIslamicMonth(m, y) )
00429     return false;
00430 
00431   IslamicDate islamic (m, d, y);
00432   int absolute = islamic;
00433   GregorianDate gregorian(absolute);
00434 
00435   return date.setYMD(gregorian.getYear(), gregorian.getMonth(),
00436     gregorian.getDay());
00437 }
00438 
00439 QString KCalendarSystemHijri::weekDayName(int day, bool shortName) const
00440 {
00441   if ( shortName )
00442     switch (day)
00443       {
00444       case 1:
00445         return locale()->translate("Ith");
00446       case 2:
00447         return locale()->translate("Thl");
00448       case 3:
00449         return locale()->translate("Arb");
00450       case 4:
00451         return locale()->translate("Kha");
00452       case 5:
00453         return locale()->translate("Jum");
00454       case 6:
00455         return locale()->translate("Sab");
00456       case 7:
00457         return locale()->translate("Ahd");
00458       }
00459   else
00460     switch ( day )
00461       {
00462       case 1:
00463         return locale()->translate("Yaum al-Ithnain");
00464       case 2:
00465         return locale()->translate("Yau al-Thulatha");
00466       case 3:
00467         return locale()->translate("Yaum al-Arbi'a");
00468       case 4:
00469         return locale()->translate("Yaum al-Khamees");
00470       case 5:
00471         return locale()->translate("Yaum al-Jumma");
00472       case 6:
00473         return locale()->translate("Yaum al-Sabt");
00474       case 7:
00475         return locale()->translate("Yaum al-Ahad");
00476       }
00477 
00478   return QString::null;
00479 }
00480 
00481 QString KCalendarSystemHijri::weekDayName(const QDate& date,
00482                                           bool shortName) const
00483 {
00484   return weekDayName(dayOfWeek(date), shortName);
00485 }
00486 
00487 int KCalendarSystemHijri::dayOfWeek(const QDate& date) const
00488 {
00489   return date.dayOfWeek(); // same as gregorian
00490 }
00491 
00492 int KCalendarSystemHijri::dayOfYear(const QDate & date) const
00493 {
00494   QDate first;
00495   setYMD(first, year(date), 1, 1);
00496 
00497   return first.daysTo(date) + 1;
00498 
00499   return 100;
00500 }
00501 
00502 int KCalendarSystemHijri::daysInMonth(const QDate& date) const
00503 {
00504   int y, m;
00505   gregorianToHijri(date, &y, &m, 0);
00506 
00507   return lastDayOfIslamicMonth(m, y);
00508 }
00509 
00510 // Min valid year that may be converted to QDate
00511 int KCalendarSystemHijri::minValidYear() const
00512 {
00513   QDate date(1753, 1, 1);
00514 
00515   return year(date);
00516 }
00517 
00518 // Max valid year that may be converted to QDate
00519 int KCalendarSystemHijri::maxValidYear() const
00520 {
00521   QDate date(8000, 1, 1);
00522 
00523   return year(date);
00524 }
00525 
00526 int KCalendarSystemHijri::daysInYear(const QDate & date) const
00527 {
00528   QDate first, last;
00529   setYMD(first, year(date), 1, 1);
00530   setYMD(last, year(date) + 1, 1, 1);
00531 
00532   return first.daysTo(last);
00533 }
00534 
00535 int KCalendarSystemHijri::weekDayOfPray() const
00536 {
00537   return 5; // friday
00538 }
00539 
00540 QDate KCalendarSystemHijri::addDays( const QDate & date, int ndays ) const
00541 {
00542   return date.addDays( ndays );
00543 }
00544 
00545 QDate KCalendarSystemHijri::addMonths( const QDate & date, int nmonths ) const
00546 {
00547   QDate result = date;
00548   int m = month(date);
00549   int y = year(date);
00550 
00551   if ( nmonths < 0 )
00552   {
00553     m += 12;
00554     y -= 1;
00555   }
00556 
00557   --m; // this only works if we start counting at zero
00558   m += nmonths;
00559   y += m / 12;
00560   m %= 12;
00561   ++m;
00562 
00563   setYMD( result, y, m, day(date) );
00564 
00565   return result;
00566 }
00567 
00568 QDate KCalendarSystemHijri::addYears( const QDate & date, int nyears ) const
00569 {
00570   QDate result = date;
00571   int y = year(date) + nyears;
00572 
00573   setYMD( result, y, month(date), day(date) );
00574 
00575   return result;
00576 }
00577 
00578 QString KCalendarSystemHijri::calendarName() const
00579 {
00580   return QString::fromLatin1("hijri");
00581 }
00582 
00583 bool KCalendarSystemHijri::isLunar() const
00584 {
00585   return true;
00586 }
00587 
00588 bool KCalendarSystemHijri::isLunisolar() const
00589 {
00590   return false;
00591 }
00592 
00593 bool KCalendarSystemHijri::isSolar() const
00594 {
00595   return false;
00596 }

KDECore

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal