KDECore
kcalendarsystemjalali.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright (C) 2002-2003 Arash Bijanzadeh and FarsiKDE Project <www.farsikde.org> 00003 Contact: Arash Bijanzadeh <a.bijanzadeh@linuxiran.org> 00004 Copyright 2007, 2008, 2009, 2010 John Layt <john@layt.net> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 /* 00023 This is an implementation of the artithmetic Persian calendar using the 00024 Birashk algorithm with adjustments to always be correct in the period 1244 00025 and 1530 (1865 to 2152 Gregorian). 00026 00027 In future this will be replaced with the correct astronomical calendar. 00028 */ 00029 00030 #include "kcalendarsystemjalali_p.h" 00031 #include "kcalendarsystemprivate_p.h" 00032 00033 #include <QtCore/QDate> 00034 00035 class KCalendarSystemJalaliPrivate : public KCalendarSystemPrivate 00036 { 00037 public: 00038 explicit KCalendarSystemJalaliPrivate(KCalendarSystemJalali *q); 00039 00040 virtual ~KCalendarSystemJalaliPrivate(); 00041 00042 // Virtual methods each calendar system must re-implement 00043 virtual KLocale::CalendarSystem calendarSystem() const; 00044 virtual void loadDefaultEraList(); 00045 virtual int monthsInYear(int year) const; 00046 virtual int daysInMonth(int year, int month) const; 00047 virtual int daysInYear(int year) const; 00048 virtual int daysInWeek() const; 00049 virtual bool isLeapYear(int year) const; 00050 virtual bool hasLeapMonths() const; 00051 virtual bool hasYearZero() const; 00052 virtual int maxDaysInWeek() const; 00053 virtual int maxMonthsInYear() const; 00054 virtual int earliestValidYear() const; 00055 virtual int latestValidYear() const; 00056 virtual QString monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const; 00057 virtual QString weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const; 00058 }; 00059 00060 // Shared d pointer base class definitions 00061 00062 KCalendarSystemJalaliPrivate::KCalendarSystemJalaliPrivate(KCalendarSystemJalali *q) 00063 : KCalendarSystemPrivate(q) 00064 { 00065 } 00066 00067 KCalendarSystemJalaliPrivate::~KCalendarSystemJalaliPrivate() 00068 { 00069 } 00070 00071 KLocale::CalendarSystem KCalendarSystemJalaliPrivate::calendarSystem() const 00072 { 00073 return KLocale::JalaliCalendar; 00074 } 00075 00076 void KCalendarSystemJalaliPrivate::loadDefaultEraList() 00077 { 00078 QString name, shortName, format; 00079 // Islamic Era (Hijri), Anno Persico. 00080 name = i18nc("Calendar Era: Jalali Islamic Era, years > 0, LongFormat", "Anno Persico"); 00081 shortName = i18nc("Calendar Era: Jalali Islamic Era, years > 0, ShortFormat", "AP"); 00082 format = i18nc("(kdedt-format) Jalali, AP, full era year format used for %EY, e.g. 2000 AP", "%Ey %EC"); 00083 addEra('+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format); 00084 } 00085 00086 int KCalendarSystemJalaliPrivate::monthsInYear(int year) const 00087 { 00088 Q_UNUSED(year) 00089 return 12; 00090 } 00091 00092 int KCalendarSystemJalaliPrivate::daysInMonth(int year, int month) const 00093 { 00094 if (month == 12) { 00095 if (isLeapYear(year)) { 00096 return 30; 00097 } else { 00098 return 29; 00099 } 00100 } 00101 00102 if (month <= 6) { 00103 return 31; 00104 } 00105 00106 return 30; 00107 } 00108 00109 int KCalendarSystemJalaliPrivate::daysInYear(int year) const 00110 { 00111 if (isLeapYear(year)) { 00112 return 366; 00113 } else { 00114 return 365; 00115 } 00116 } 00117 00118 int KCalendarSystemJalaliPrivate::daysInWeek() const 00119 { 00120 return 7; 00121 } 00122 00123 bool KCalendarSystemJalaliPrivate::isLeapYear(int year) const 00124 { 00125 // From formilab Public Domain code http://www.fourmilab.ch/documents/calendar/ 00126 // Use Birashk algorithm as it matches the to/from jd code below 00127 00128 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531, 00129 // 1403/1404 and 1436/1437, and so catch them here first 00130 if (year == 1403 || year == 1436) { 00131 return true; 00132 } else if (year == 1404 || year == 1437) { 00133 return false; 00134 } 00135 00136 if (year >= 0) { 00137 year = year - 474; 00138 } else { 00139 year = year - 473; 00140 } 00141 00142 if ((((((year % 2820) + 474) + 38) * 682) % 2816) < 682) { 00143 return true; 00144 } else { 00145 return false; 00146 } 00147 } 00148 00149 bool KCalendarSystemJalaliPrivate::hasLeapMonths() const 00150 { 00151 return false; 00152 } 00153 00154 bool KCalendarSystemJalaliPrivate::hasYearZero() const 00155 { 00156 return false; 00157 } 00158 00159 int KCalendarSystemJalaliPrivate::maxDaysInWeek() const 00160 { 00161 return 7; 00162 } 00163 00164 int KCalendarSystemJalaliPrivate::maxMonthsInYear() const 00165 { 00166 return 12; 00167 } 00168 00169 int KCalendarSystemJalaliPrivate::earliestValidYear() const 00170 { 00171 return 1244; 00172 } 00173 00174 int KCalendarSystemJalaliPrivate::latestValidYear() const 00175 { 00176 return 1530; 00177 } 00178 00179 QString KCalendarSystemJalaliPrivate::monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const 00180 { 00181 Q_UNUSED(year); 00182 00183 if (format == KLocale::NarrowName) { 00184 switch (month) { 00185 case 1: 00186 return ki18nc("Jalali month 1 - KLocale::NarrowName", "F").toString(locale()); 00187 case 2: 00188 return ki18nc("Jalali month 2 - KLocale::NarrowName", "O").toString(locale()); 00189 case 3: 00190 return ki18nc("Jalali month 3 - KLocale::NarrowName", "K").toString(locale()); 00191 case 4: 00192 return ki18nc("Jalali month 4 - KLocale::NarrowName", "T").toString(locale()); 00193 case 5: 00194 return ki18nc("Jalali month 5 - KLocale::NarrowName", "M").toString(locale()); 00195 case 6: 00196 return ki18nc("Jalali month 6 - KLocale::NarrowName", "S").toString(locale()); 00197 case 7: 00198 return ki18nc("Jalali month 7 - KLocale::NarrowName", "M").toString(locale()); 00199 case 8: 00200 return ki18nc("Jalali month 8 - KLocale::NarrowName", "A").toString(locale()); 00201 case 9: 00202 return ki18nc("Jalali month 9 - KLocale::NarrowName", "A").toString(locale()); 00203 case 10: 00204 return ki18nc("Jalali month 10 - KLocale::NarrowName", "D").toString(locale()); 00205 case 11: 00206 return ki18nc("Jalali month 11 - KLocale::NarrowName", "B").toString(locale()); 00207 case 12: 00208 return ki18nc("Jalali month 12 - KLocale::NarrowName", "E").toString(locale()); 00209 default: 00210 return QString(); 00211 } 00212 } 00213 00214 if (format == KLocale::ShortName && possessive) { 00215 switch (month) { 00216 case 1: 00217 return ki18nc("Jalali month 1 - KLocale::ShortName Possessive", "of Far").toString(locale()); 00218 case 2: 00219 return ki18nc("Jalali month 2 - KLocale::ShortName Possessive", "of Ord").toString(locale()); 00220 case 3: 00221 return ki18nc("Jalali month 3 - KLocale::ShortName Possessive", "of Kho").toString(locale()); 00222 case 4: 00223 return ki18nc("Jalali month 4 - KLocale::ShortName Possessive", "of Tir").toString(locale()); 00224 case 5: 00225 return ki18nc("Jalali month 5 - KLocale::ShortName Possessive", "of Mor").toString(locale()); 00226 case 6: 00227 return ki18nc("Jalali month 6 - KLocale::ShortName Possessive", "of Sha").toString(locale()); 00228 case 7: 00229 return ki18nc("Jalali month 7 - KLocale::ShortName Possessive", "of Meh").toString(locale()); 00230 case 8: 00231 return ki18nc("Jalali month 8 - KLocale::ShortName Possessive", "of Aba").toString(locale()); 00232 case 9: 00233 return ki18nc("Jalali month 9 - KLocale::ShortName Possessive", "of Aza").toString(locale()); 00234 case 10: 00235 return ki18nc("Jalali month 10 - KLocale::ShortName Possessive", "of Dei").toString(locale()); 00236 case 11: 00237 return ki18nc("Jalali month 11 - KLocale::ShortName Possessive", "of Bah").toString(locale()); 00238 case 12: 00239 return ki18nc("Jalali month 12 - KLocale::ShortName Possessive", "of Esf").toString(locale()); 00240 default: 00241 return QString(); 00242 } 00243 } 00244 00245 if (format == KLocale::ShortName && !possessive) { 00246 switch (month) { 00247 case 1: 00248 return ki18nc("Jalali month 1 - KLocale::ShortName", "Far").toString(locale()); 00249 case 2: 00250 return ki18nc("Jalali month 2 - KLocale::ShortName", "Ord").toString(locale()); 00251 case 3: 00252 return ki18nc("Jalali month 3 - KLocale::ShortName", "Kho").toString(locale()); 00253 case 4: 00254 return ki18nc("Jalali month 4 - KLocale::ShortName", "Tir").toString(locale()); 00255 case 5: 00256 return ki18nc("Jalali month 5 - KLocale::ShortName", "Mor").toString(locale()); 00257 case 6: 00258 return ki18nc("Jalali month 6 - KLocale::ShortName", "Sha").toString(locale()); 00259 case 7: 00260 return ki18nc("Jalali month 7 - KLocale::ShortName", "Meh").toString(locale()); 00261 case 8: 00262 return ki18nc("Jalali month 8 - KLocale::ShortName", "Aba").toString(locale()); 00263 case 9: 00264 return ki18nc("Jalali month 9 - KLocale::ShortName", "Aza").toString(locale()); 00265 case 10: 00266 return ki18nc("Jalali month 10 - KLocale::ShortName", "Dei").toString(locale()); 00267 case 11: 00268 return ki18nc("Jalali month 11 - KLocale::ShortName", "Bah").toString(locale()); 00269 case 12: 00270 return ki18nc("Jalali month 12 - KLocale::ShortName", "Esf").toString(locale()); 00271 default: 00272 return QString(); 00273 } 00274 } 00275 00276 if (format == KLocale::LongName && possessive) { 00277 switch (month) { 00278 case 1: 00279 return ki18nc("Jalali month 1 - KLocale::LongName Possessive", "of Farvardin").toString(locale()); 00280 case 2: 00281 return ki18nc("Jalali month 2 - KLocale::LongName Possessive", "of Ordibehesht").toString(locale()); 00282 case 3: 00283 return ki18nc("Jalali month 3 - KLocale::LongName Possessive", "of Khordad").toString(locale()); 00284 case 4: 00285 return ki18nc("Jalali month 4 - KLocale::LongName Possessive", "of Tir").toString(locale()); 00286 case 5: 00287 return ki18nc("Jalali month 5 - KLocale::LongName Possessive", "of Mordad").toString(locale()); 00288 case 6: 00289 return ki18nc("Jalali month 6 - KLocale::LongName Possessive", "of Shahrivar").toString(locale()); 00290 case 7: 00291 return ki18nc("Jalali month 7 - KLocale::LongName Possessive", "of Mehr").toString(locale()); 00292 case 8: 00293 return ki18nc("Jalali month 8 - KLocale::LongName Possessive", "of Aban").toString(locale()); 00294 case 9: 00295 return ki18nc("Jalali month 9 - KLocale::LongName Possessive", "of Azar").toString(locale()); 00296 case 10: 00297 return ki18nc("Jalali month 10 - KLocale::LongName Possessive", "of Dei").toString(locale()); 00298 case 11: 00299 return ki18nc("Jalali month 11 - KLocale::LongName Possessive", "of Bahman").toString(locale()); 00300 case 12: 00301 return ki18nc("Jalali month 12 - KLocale::LongName Possessive", "of Esfand").toString(locale()); 00302 default: 00303 return QString(); 00304 } 00305 } 00306 00307 // Default to LongName 00308 switch (month) { 00309 case 1: 00310 return ki18nc("Jalali month 1 - KLocale::LongName", "Farvardin").toString(locale()); 00311 case 2: 00312 return ki18nc("Jalali month 2 - KLocale::LongName", "Ordibehesht").toString(locale()); 00313 case 3: 00314 return ki18nc("Jalali month 3 - KLocale::LongName", "Khordad").toString(locale()); 00315 case 4: 00316 return ki18nc("Jalali month 4 - KLocale::LongName", "Tir").toString(locale()); 00317 case 5: 00318 return ki18nc("Jalali month 5 - KLocale::LongName", "Mordad").toString(locale()); 00319 case 6: 00320 return ki18nc("Jalali month 6 - KLocale::LongName", "Shahrivar").toString(locale()); 00321 case 7: 00322 return ki18nc("Jalali month 7 - KLocale::LongName", "Mehr").toString(locale()); 00323 case 8: 00324 return ki18nc("Jalali month 8 - KLocale::LongName", "Aban").toString(locale()); 00325 case 9: 00326 return ki18nc("Jalali month 9 - KLocale::LongName", "Azar").toString(locale()); 00327 case 10: 00328 return ki18nc("Jalali month 10 - KLocale::LongName", "Dei").toString(locale()); 00329 case 11: 00330 return ki18nc("Jalali month 11 - KLocale::LongName", "Bahman").toString(locale()); 00331 case 12: 00332 return ki18nc("Jalali month 12 - KLocale::LongName", "Esfand").toString(locale()); 00333 default: 00334 return QString(); 00335 } 00336 } 00337 00338 QString KCalendarSystemJalaliPrivate::weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const 00339 { 00340 if (format == KLocale::NarrowName) { 00341 switch (weekDay) { 00342 case 1: 00343 return ki18nc("Jalali weekday 1 - KLocale::NarrowName ", "2").toString(locale()); 00344 case 2: 00345 return ki18nc("Jalali weekday 2 - KLocale::NarrowName ", "3").toString(locale()); 00346 case 3: 00347 return ki18nc("Jalali weekday 3 - KLocale::NarrowName ", "4").toString(locale()); 00348 case 4: 00349 return ki18nc("Jalali weekday 4 - KLocale::NarrowName ", "5").toString(locale()); 00350 case 5: 00351 return ki18nc("Jalali weekday 5 - KLocale::NarrowName ", "J").toString(locale()); 00352 case 6: 00353 return ki18nc("Jalali weekday 6 - KLocale::NarrowName ", "S").toString(locale()); 00354 case 7: 00355 return ki18nc("Jalali weekday 7 - KLocale::NarrowName ", "1").toString(locale()); 00356 default: 00357 return QString(); 00358 } 00359 } 00360 00361 if (format == KLocale::ShortName || format == KLocale:: ShortNumber) { 00362 switch (weekDay) { 00363 case 1: 00364 return ki18nc("Jalali weekday 1 - KLocale::ShortName", "2sh").toString(locale()); 00365 case 2: 00366 return ki18nc("Jalali weekday 2 - KLocale::ShortName", "3sh").toString(locale()); 00367 case 3: 00368 return ki18nc("Jalali weekday 3 - KLocale::ShortName", "4sh").toString(locale()); 00369 case 4: 00370 return ki18nc("Jalali weekday 4 - KLocale::ShortName", "5sh").toString(locale()); 00371 case 5: 00372 return ki18nc("Jalali weekday 5 - KLocale::ShortName", "Jom").toString(locale()); 00373 case 6: 00374 return ki18nc("Jalali weekday 6 - KLocale::ShortName", "Shn").toString(locale()); 00375 case 7: 00376 return ki18nc("Jalali weekday 7 - KLocale::ShortName", "1sh").toString(locale()); 00377 default: return QString(); 00378 } 00379 } 00380 00381 switch (weekDay) { 00382 case 1: 00383 return ki18nc("Jalali weekday 1 - KLocale::LongName", "Do shanbe").toString(locale()); 00384 case 2: 00385 return ki18nc("Jalali weekday 2 - KLocale::LongName", "Se shanbe").toString(locale()); 00386 case 3: 00387 return ki18nc("Jalali weekday 3 - KLocale::LongName", "Chahar shanbe").toString(locale()); 00388 case 4: 00389 return ki18nc("Jalali weekday 4 - KLocale::LongName", "Panj shanbe").toString(locale()); 00390 case 5: 00391 return ki18nc("Jalali weekday 5 - KLocale::LongName", "Jumee").toString(locale()); 00392 case 6: 00393 return ki18nc("Jalali weekday 6 - KLocale::LongName", "Shanbe").toString(locale()); 00394 case 7: 00395 return ki18nc("Jalali weekday 7 - KLocale::LongName", "Yek-shanbe").toString(locale()); 00396 default: 00397 return QString(); 00398 } 00399 } 00400 00401 00402 KCalendarSystemJalali::KCalendarSystemJalali(const KLocale *locale) 00403 : KCalendarSystem(*new KCalendarSystemJalaliPrivate(this), KSharedConfig::Ptr(), locale) 00404 { 00405 d_ptr->loadConfig(calendarType()); 00406 } 00407 00408 KCalendarSystemJalali::KCalendarSystemJalali(const KSharedConfig::Ptr config, const KLocale *locale) 00409 : KCalendarSystem(*new KCalendarSystemJalaliPrivate(this), config, locale) 00410 { 00411 d_ptr->loadConfig(calendarType()); 00412 } 00413 00414 KCalendarSystemJalali::KCalendarSystemJalali(KCalendarSystemJalaliPrivate &dd, 00415 const KSharedConfig::Ptr config, const KLocale *locale) 00416 : KCalendarSystem(dd, config, locale) 00417 { 00418 d_ptr->loadConfig(calendarType()); 00419 } 00420 00421 KCalendarSystemJalali::~KCalendarSystemJalali() 00422 { 00423 } 00424 00425 QString KCalendarSystemJalali::calendarType() const 00426 { 00427 return QLatin1String("jalali"); 00428 } 00429 00430 QDate KCalendarSystemJalali::epoch() const 00431 { 00432 // 19 March 622 in the Julian calendar 00433 return QDate::fromJulianDay(1948321); 00434 } 00435 00436 QDate KCalendarSystemJalali::earliestValidDate() const 00437 { 00438 // Using the Birashk formula which is accurate in period AP 1244 to 1530 (AD 1865 to 2152) 00439 // 1244-01-01 Jalali 1865-03-21 Gregorian 00440 return QDate::fromJulianDay(2402317); 00441 } 00442 00443 QDate KCalendarSystemJalali::latestValidDate() const 00444 { 00445 // Using the Birashk formula which is accurate in period AP 1244 to 1530 (AD 1865 to 2152) 00446 // 1530-12-29 Jalali 2152-03-19 Gregorian 00447 return QDate::fromJulianDay(2507140); 00448 } 00449 00450 bool KCalendarSystemJalali::isValid(int year, int month, int day) const 00451 { 00452 return KCalendarSystem::isValid(year, month, day); 00453 } 00454 00455 bool KCalendarSystemJalali::isValid(const QDate &date) const 00456 { 00457 return KCalendarSystem::isValid(date); 00458 } 00459 00460 bool KCalendarSystemJalali::isLeapYear(int year) const 00461 { 00462 return KCalendarSystem::isLeapYear(year); 00463 } 00464 00465 bool KCalendarSystemJalali::isLeapYear(const QDate &date) const 00466 { 00467 return KCalendarSystem::isLeapYear(date); 00468 } 00469 00470 QString KCalendarSystemJalali::monthName(int month, int year, MonthNameFormat format) const 00471 { 00472 return KCalendarSystem::monthName(month, year, format); 00473 } 00474 00475 QString KCalendarSystemJalali::monthName(const QDate &date, MonthNameFormat format) const 00476 { 00477 return KCalendarSystem::monthName(date, format); 00478 } 00479 00480 QString KCalendarSystemJalali::weekDayName(int weekDay, WeekDayNameFormat format) const 00481 { 00482 return KCalendarSystem::weekDayName(weekDay, format); 00483 } 00484 00485 QString KCalendarSystemJalali::weekDayName(const QDate &date, WeekDayNameFormat format) const 00486 { 00487 return KCalendarSystem::weekDayName(date, format); 00488 } 00489 00490 int KCalendarSystemJalali::weekDayOfPray() const 00491 { 00492 return 5; // friday 00493 } 00494 00495 bool KCalendarSystemJalali::isLunar() const 00496 { 00497 return false; 00498 } 00499 00500 bool KCalendarSystemJalali::isLunisolar() const 00501 { 00502 return false; 00503 } 00504 00505 bool KCalendarSystemJalali::isSolar() const 00506 { 00507 return true; 00508 } 00509 00510 bool KCalendarSystemJalali::isProleptic() const 00511 { 00512 return false; 00513 } 00514 00515 bool KCalendarSystemJalali::julianDayToDate(int jd, int &year, int &month, int &day) const 00516 { 00517 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531. 00518 // This results in a leap day being added to the end of 1404 instead of 1403 00519 // and to the end of 1437 instead of 1436. Check for these dates first and 00520 // return accordingly. Relies on later use of dateToJulianDay() to correctly 00521 // calculate firstDayOfYear in 1404 and 1437, so no other adjustments needed. 00522 if (jd == 2460755) { 00523 year = 1403; 00524 month = 12; 00525 day = 30; 00526 return true; 00527 } 00528 if (jd == 2472808) { 00529 year = 1436; 00530 month = 12; 00531 day = 30; 00532 return true; 00533 } 00534 00535 // From original KDE3 code, source unknown? Unable to contact author or committer to confirm 00536 // Matches Fermilab code, EMACS and D&R so check for PD source, likely Birashk's book 00537 00538 int jdCycleStart; 00539 int daysSinceCycleStart; 00540 int cycle; 00541 int dayInCycle; 00542 int yearInCycle; 00543 dateToJulianDay(475, 1, 1, jdCycleStart); 00544 daysSinceCycleStart = jd - jdCycleStart; 00545 cycle = daysSinceCycleStart / 1029983; 00546 dayInCycle = daysSinceCycleStart % 1029983; 00547 if (dayInCycle == 1029982) { 00548 yearInCycle = 2820; 00549 } else { 00550 int aux1 = dayInCycle / 366; 00551 int aux2 = dayInCycle % 366; 00552 yearInCycle = (((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) + aux1 + 1; 00553 } 00554 year = yearInCycle + (2820 * cycle) + 474; 00555 if (year <= 0) { 00556 year = year - 1; 00557 } 00558 00559 int firstDayOfYear; 00560 dateToJulianDay(year, 1, 1, firstDayOfYear); 00561 int dayinYear = jd - firstDayOfYear + 1; 00562 if (dayinYear <= 186) { 00563 month = ((dayinYear - 1) / 31) + 1; 00564 day = dayinYear - ((month - 1) * 31); 00565 } else { 00566 month = ((dayinYear - 7) / 30) + 1; 00567 day = dayinYear - ((month - 1) * 30) - 6; 00568 } 00569 00570 return true; 00571 } 00572 00573 bool KCalendarSystemJalali::dateToJulianDay(int year, int month, int day, int &jd) const 00574 { 00575 Q_D(const KCalendarSystemJalali); 00576 00577 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531. 00578 // This results in a leap day being added to the end of 1404 instead of 1403 00579 // and to the end of 1437 instead of 1436. Thus all dates in 1404 and 1437 00580 // are off by 1 JD. Check for these dates first and adjust accordingly. 00581 if (year == 1403 && month == 12 && day == 30) { 00582 jd = 2460755; 00583 return true; 00584 } 00585 if (year == 1436 && month == 12 && day == 30) { 00586 jd = 2472808; 00587 return true; 00588 } 00589 if (year == 1404 || year == 1437) { 00590 if (month < 12 && day + 1 > d->daysInMonth(year, month)) { 00591 day = 1; 00592 month = month + 1; 00593 } else { 00594 day = day + 1; 00595 } 00596 } 00597 00598 // From original KDE3 code, source unknown? Unable to contact author or committer to confirm 00599 // Matches Fermilab code, EMACS and D&R so check for PD source, likely Birashk's book 00600 int epbase; 00601 long epyear; 00602 long monthDays; 00603 00604 if (year >= 0) { 00605 epbase = year - 474; 00606 } else { 00607 epbase = year - 473; 00608 } 00609 00610 epyear = 474 + (epbase % 2820); 00611 00612 if (month <= 7) { 00613 monthDays = (month - 1) * 31; 00614 } else { 00615 monthDays = ((month - 1) * 30) + 6; 00616 } 00617 00618 jd = (epoch().toJulianDay() - 1) + // days before epoch 00619 (epyear - 1) * 365 + // normal days in previous years 00620 (((epyear * 682) - 110) / 2816) + // leap days in previous years 00621 (epbase / 2820) * 1029983 + 00622 monthDays + // days in previous months this year 00623 day; // days in this month 00624 00625 return true; 00626 }
KDE 4.7 API Reference