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 }; 00057 00058 // Shared d pointer base class definitions 00059 00060 KCalendarSystemJalaliPrivate::KCalendarSystemJalaliPrivate( KCalendarSystemJalali *q ) 00061 :KCalendarSystemPrivate( q ) 00062 { 00063 } 00064 00065 KCalendarSystemJalaliPrivate::~KCalendarSystemJalaliPrivate() 00066 { 00067 } 00068 00069 KLocale::CalendarSystem KCalendarSystemJalaliPrivate::calendarSystem() const 00070 { 00071 return KLocale::JalaliCalendar; 00072 } 00073 00074 void KCalendarSystemJalaliPrivate::loadDefaultEraList() 00075 { 00076 QString name, shortName, format; 00077 // Islamic Era (Hijri), Anno Persico. 00078 name = i18nc( "Calendar Era: Jalali Islamic Era, years > 0, LongFormat", "Anno Persico" ); 00079 shortName = i18nc( "Calendar Era: Jalali Islamic Era, years > 0, ShortFormat", "AP" ); 00080 format = i18nc( "(kdedt-format) Jalali, AP, full era year format used for %EY, e.g. 2000 AP", "%Ey %EC" ); 00081 addEra( '+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format ); 00082 } 00083 00084 int KCalendarSystemJalaliPrivate::monthsInYear( int year ) const 00085 { 00086 Q_UNUSED( year ) 00087 return 12; 00088 } 00089 00090 int KCalendarSystemJalaliPrivate::daysInMonth( int year, int month ) const 00091 { 00092 if ( month == 12 ) { 00093 if ( isLeapYear( year ) ) { 00094 return 30; 00095 } else { 00096 return 29; 00097 } 00098 } 00099 00100 if ( month <= 6 ) { 00101 return 31; 00102 } 00103 00104 return 30; 00105 } 00106 00107 int KCalendarSystemJalaliPrivate::daysInYear( int year ) const 00108 { 00109 if ( isLeapYear( year ) ) { 00110 return 366; 00111 } else { 00112 return 365; 00113 } 00114 } 00115 00116 int KCalendarSystemJalaliPrivate::daysInWeek() const 00117 { 00118 return 7; 00119 } 00120 00121 bool KCalendarSystemJalaliPrivate::isLeapYear( int year ) const 00122 { 00123 // From formilab Public Domain code http://www.fourmilab.ch/documents/calendar/ 00124 // Use Birashk algorithm as it matches the to/from jd code below 00125 00126 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531, 00127 // 1403/1404 and 1436/1437, and so catch them here first 00128 if ( year == 1403 || year == 1436 ) { 00129 return true; 00130 } else if ( year == 1404 || year == 1437 ) { 00131 return false; 00132 } 00133 00134 if ( year >= 0 ) { 00135 year = year - 474; 00136 } else { 00137 year = year - 473; 00138 } 00139 00140 if ( ( ( ( ( ( year % 2820 ) + 474 ) + 38 ) * 682 ) % 2816 ) < 682 ) { 00141 return true; 00142 } else { 00143 return false; 00144 } 00145 } 00146 00147 bool KCalendarSystemJalaliPrivate::hasLeapMonths() const 00148 { 00149 return false; 00150 } 00151 00152 bool KCalendarSystemJalaliPrivate::hasYearZero() const 00153 { 00154 return false; 00155 } 00156 00157 int KCalendarSystemJalaliPrivate::maxDaysInWeek() const 00158 { 00159 return 7; 00160 } 00161 00162 int KCalendarSystemJalaliPrivate::maxMonthsInYear() const 00163 { 00164 return 12; 00165 } 00166 00167 int KCalendarSystemJalaliPrivate::earliestValidYear() const 00168 { 00169 return 1244; 00170 } 00171 00172 int KCalendarSystemJalaliPrivate::latestValidYear() const 00173 { 00174 return 1530; 00175 } 00176 00177 00178 KCalendarSystemJalali::KCalendarSystemJalali( const KLocale *locale ) 00179 : KCalendarSystem( *new KCalendarSystemJalaliPrivate( this ), KSharedConfig::Ptr(), locale ), 00180 dont_use( 0 ) 00181 { 00182 d_ptr->loadConfig( calendarType() ); 00183 } 00184 00185 KCalendarSystemJalali::KCalendarSystemJalali( const KSharedConfig::Ptr config, const KLocale *locale ) 00186 : KCalendarSystem( *new KCalendarSystemJalaliPrivate( this ), config, locale ), 00187 dont_use( 0 ) 00188 { 00189 d_ptr->loadConfig( calendarType() ); 00190 } 00191 00192 KCalendarSystemJalali::KCalendarSystemJalali( KCalendarSystemJalaliPrivate &dd, 00193 const KSharedConfig::Ptr config, const KLocale *locale ) 00194 : KCalendarSystem( dd, config, locale ), 00195 dont_use( 0 ) 00196 { 00197 d_ptr->loadConfig( calendarType() ); 00198 } 00199 00200 KCalendarSystemJalali::~KCalendarSystemJalali() 00201 { 00202 delete dont_use; 00203 } 00204 00205 QString KCalendarSystemJalali::calendarType() const 00206 { 00207 return QLatin1String( "jalali" ); 00208 } 00209 00210 QDate KCalendarSystemJalali::epoch() const 00211 { 00212 // 19 March 622 in the Julian calendar 00213 return QDate::fromJulianDay( 1948321 ); 00214 } 00215 00216 QDate KCalendarSystemJalali::earliestValidDate() const 00217 { 00218 // Using the Birashk formula which is accurate in period AP 1244 to 1530 (AD 1865 to 2152) 00219 // 1244-01-01 Jalali 1865-03-21 Gregorian 00220 return QDate::fromJulianDay( 2402317 ); 00221 } 00222 00223 QDate KCalendarSystemJalali::latestValidDate() const 00224 { 00225 // Using the Birashk formula which is accurate in period AP 1244 to 1530 (AD 1865 to 2152) 00226 // 1530-12-29 Jalali 2152-03-19 Gregorian 00227 return QDate::fromJulianDay( 2507140 ); 00228 } 00229 00230 bool KCalendarSystemJalali::isValid( int year, int month, int day ) const 00231 { 00232 return KCalendarSystem::isValid( year, month, day ); 00233 } 00234 00235 bool KCalendarSystemJalali::isValid( const QDate &date ) const 00236 { 00237 return KCalendarSystem::isValid( date ); 00238 } 00239 00240 bool KCalendarSystemJalali::setDate( QDate &date, int year, int month, int day ) const 00241 { 00242 return KCalendarSystem::setDate( date, year, month, day ); 00243 } 00244 00245 // Deprecated 00246 bool KCalendarSystemJalali::setYMD( QDate &date, int year, int month, int day ) const 00247 { 00248 return KCalendarSystem::setYMD( date, year, month, day ); 00249 } 00250 00251 int KCalendarSystemJalali::year( const QDate &date ) const 00252 { 00253 return KCalendarSystem::year( date ); 00254 } 00255 00256 int KCalendarSystemJalali::month ( const QDate& date ) const 00257 00258 { 00259 return KCalendarSystem::month( date ); 00260 } 00261 00262 int KCalendarSystemJalali::day( const QDate &date ) const 00263 { 00264 return KCalendarSystem::day( date ); 00265 } 00266 00267 QDate KCalendarSystemJalali::addYears( const QDate &date, int nyears ) const 00268 { 00269 return KCalendarSystem::addYears( date, nyears ); 00270 } 00271 00272 QDate KCalendarSystemJalali::addMonths( const QDate &date, int nmonths ) const 00273 { 00274 return KCalendarSystem::addMonths( date, nmonths ); 00275 } 00276 00277 QDate KCalendarSystemJalali::addDays( const QDate &date, int ndays ) const 00278 { 00279 return KCalendarSystem::addDays( date, ndays ); 00280 } 00281 00282 int KCalendarSystemJalali::monthsInYear( const QDate &date ) const 00283 { 00284 return KCalendarSystem::monthsInYear( date ); 00285 } 00286 00287 int KCalendarSystemJalali::weeksInYear( const QDate &date ) const 00288 { 00289 return KCalendarSystem::weeksInYear( date ); 00290 } 00291 00292 int KCalendarSystemJalali::weeksInYear( int year ) const 00293 { 00294 return KCalendarSystem::weeksInYear( year ); 00295 } 00296 00297 int KCalendarSystemJalali::daysInYear( const QDate &date ) const 00298 { 00299 return KCalendarSystem::daysInYear( date ); 00300 } 00301 00302 int KCalendarSystemJalali::daysInMonth( const QDate &date ) const 00303 { 00304 return KCalendarSystem::daysInMonth( date ); 00305 } 00306 00307 int KCalendarSystemJalali::daysInWeek( const QDate &date ) const 00308 { 00309 return KCalendarSystem::daysInWeek( date ); 00310 } 00311 00312 int KCalendarSystemJalali::dayOfYear( const QDate &date ) const 00313 { 00314 return KCalendarSystem::dayOfYear( date ); 00315 } 00316 00317 int KCalendarSystemJalali::dayOfWeek( const QDate &date ) const 00318 { 00319 return KCalendarSystem::dayOfWeek( date ); 00320 } 00321 00322 int KCalendarSystemJalali::weekNumber( const QDate &date, int *yearNum ) const 00323 { 00324 return KCalendarSystem::weekNumber( date, yearNum ); 00325 } 00326 00327 bool KCalendarSystemJalali::isLeapYear( int year ) const 00328 { 00329 return KCalendarSystem::isLeapYear( year ); 00330 } 00331 00332 bool KCalendarSystemJalali::isLeapYear( const QDate &date ) const 00333 { 00334 return KCalendarSystem::isLeapYear( date ); 00335 } 00336 00337 QString KCalendarSystemJalali::monthName( int month, int year, MonthNameFormat format ) const 00338 { 00339 Q_UNUSED( year ); 00340 00341 if ( format == ShortNamePossessive ) { 00342 switch ( month ) { 00343 case 1: 00344 return ki18nc( "of Farvardin short", "of Far" ).toString( locale() ); 00345 case 2: 00346 return ki18nc( "of Ordibehesht short", "of Ord" ).toString( locale() ); 00347 case 3: 00348 return ki18nc( "of Khordad short", "of Kho" ).toString( locale() ); 00349 case 4: 00350 return ki18nc( "of Tir short", "of Tir" ).toString( locale() ); 00351 case 5: 00352 return ki18nc( "of Mordad short", "of Mor" ).toString( locale() ); 00353 case 6: 00354 return ki18nc( "of Shahrivar short", "of Sha" ).toString( locale() ); 00355 case 7: 00356 return ki18nc( "of Mehr short", "of Meh" ).toString( locale() ); 00357 case 8: 00358 return ki18nc( "of Aban short", "of Aba" ).toString( locale() ); 00359 case 9: 00360 return ki18nc( "of Azar short", "of Aza" ).toString( locale() ); 00361 case 10: 00362 return ki18nc( "of Dei short", "of Dei" ).toString( locale() ); 00363 case 11: 00364 return ki18nc( "of Bahman short", "of Bah" ).toString( locale() ); 00365 case 12: 00366 return ki18nc( "of Esfand short", "of Esf" ).toString( locale() ); 00367 default: 00368 return QString(); 00369 } 00370 } 00371 00372 if ( format == ShortName ) { 00373 switch ( month ) { 00374 case 1: 00375 return ki18nc( "Farvardin short", "Far" ).toString( locale() ); 00376 case 2: 00377 return ki18nc( "Ordibehesht short", "Ord" ).toString( locale() ); 00378 case 3: 00379 return ki18nc( "Khordad short", "Kho" ).toString( locale() ); 00380 case 4: 00381 return ki18nc( "Tir short", "Tir" ).toString( locale() ); 00382 case 5: 00383 return ki18nc( "Mordad short", "Mor" ).toString( locale() ); 00384 case 6: 00385 return ki18nc( "Shahrivar short", "Sha" ).toString( locale() ); 00386 case 7: 00387 return ki18nc( "Mehr short", "Meh" ).toString( locale() ); 00388 case 8: 00389 return ki18nc( "Aban short", "Aba" ).toString( locale() ); 00390 case 9: 00391 return ki18nc( "Azar short", "Aza" ).toString( locale() ); 00392 case 10: 00393 return ki18nc( "Dei short", "Dei" ).toString( locale() ); 00394 case 11: 00395 return ki18nc( "Bahman short", "Bah" ).toString( locale() ); 00396 case 12: 00397 return ki18nc( "Esfand", "Esf" ).toString( locale() ); 00398 default: 00399 return QString(); 00400 } 00401 } 00402 00403 if ( format == LongNamePossessive ) { 00404 switch ( month ) { 00405 case 1: 00406 return ki18n( "of Farvardin" ).toString( locale() ); 00407 case 2: 00408 return ki18n( "of Ordibehesht" ).toString( locale() ); 00409 case 3: 00410 return ki18n( "of Khordad" ).toString( locale() ); 00411 case 4: 00412 return ki18nc( "of Tir long", "of Tir" ).toString( locale() ); 00413 case 5: 00414 return ki18n( "of Mordad" ).toString( locale() ); 00415 case 6: 00416 return ki18n( "of Shahrivar" ).toString( locale() ); 00417 case 7: 00418 return ki18n( "of Mehr" ).toString( locale() ); 00419 case 8: 00420 return ki18n( "of Aban" ).toString( locale() ); 00421 case 9: 00422 return ki18n( "of Azar" ).toString( locale() ); 00423 case 10: 00424 return ki18nc( "of Dei long", "of Dei" ).toString( locale() ); 00425 case 11: 00426 return ki18n( "of Bahman" ).toString( locale() ); 00427 case 12: 00428 return ki18n( "of Esfand" ).toString( locale() ); 00429 default: 00430 return QString(); 00431 } 00432 } 00433 00434 // Default to LongName format 00435 switch ( month ) { 00436 case 1: 00437 return ki18n( "Farvardin" ).toString( locale() ); 00438 case 2: 00439 return ki18n( "Ordibehesht" ).toString( locale() ); 00440 case 3: 00441 return ki18n( "Khordad" ).toString( locale() ); 00442 case 4: 00443 return ki18nc( "Tir long", "Tir" ).toString( locale() ); 00444 case 5: 00445 return ki18n( "Mordad" ).toString( locale() ); 00446 case 6: 00447 return ki18n( "Shahrivar" ).toString( locale() ); 00448 case 7: 00449 return ki18n( "Mehr" ).toString( locale() ); 00450 case 8: 00451 return ki18n( "Aban" ).toString( locale() ); 00452 case 9: 00453 return ki18n( "Azar" ).toString( locale() ); 00454 case 10: 00455 return ki18nc( "Dei long", "Dei" ).toString( locale() ); 00456 case 11: 00457 return ki18n( "Bahman" ).toString( locale() ); 00458 case 12: 00459 return ki18n( "Esfand" ).toString( locale() ); 00460 default: 00461 return QString(); 00462 } 00463 } 00464 00465 QString KCalendarSystemJalali::monthName( const QDate &date, MonthNameFormat format ) const 00466 { 00467 return monthName( month( date ), year( date ), format ); 00468 } 00469 00470 QString KCalendarSystemJalali::weekDayName( int day, WeekDayNameFormat format ) const 00471 { 00472 if ( format == ShortDayName ) { 00473 switch ( day ) { 00474 case 1: 00475 return ki18nc( "Do shanbe short", "2sh" ).toString( locale() ); 00476 case 2: 00477 return ki18nc( "Se shanbe short", "3sh" ).toString( locale() ); 00478 case 3: 00479 return ki18nc( "Chahar shanbe short", "4sh" ).toString( locale() ); 00480 case 4: 00481 return ki18nc( "Panj shanbe short", "5sh" ).toString( locale() ); 00482 case 5: 00483 return ki18nc( "Jumee short", "Jom" ).toString( locale() ); 00484 case 6: 00485 return ki18nc( "Shanbe short", "shn" ).toString( locale() ); 00486 case 7: 00487 return ki18nc( "Yek-shanbe short", "1sh" ).toString( locale() ); 00488 default: 00489 return QString(); 00490 } 00491 } 00492 00493 // Default to ShortDayName format 00494 switch ( day ) { 00495 case 1: 00496 return ki18n( "Do shanbe" ).toString( locale() ); 00497 case 2: 00498 return ki18n( "Se shanbe" ).toString( locale() ); 00499 case 3: 00500 return ki18n( "Chahar shanbe" ).toString( locale() ); 00501 case 4: 00502 return ki18n( "Panj shanbe" ).toString( locale() ); 00503 case 5: 00504 return ki18n( "Jumee" ).toString( locale() ); 00505 case 6: 00506 return ki18n( "Shanbe" ).toString( locale() ); 00507 case 7: 00508 return ki18n( "Yek-shanbe" ).toString( locale() ); 00509 default: 00510 return QString(); 00511 } 00512 } 00513 00514 QString KCalendarSystemJalali::weekDayName( const QDate &date, WeekDayNameFormat format ) const 00515 { 00516 return weekDayName( dayOfWeek( date ), format ); 00517 } 00518 00519 QString KCalendarSystemJalali::yearString( const QDate &pDate, StringFormat format ) const 00520 { 00521 return KCalendarSystem::yearString( pDate, format ); 00522 } 00523 00524 QString KCalendarSystemJalali::monthString( const QDate &pDate, StringFormat format ) const 00525 { 00526 return KCalendarSystem::monthString( pDate, format ); 00527 } 00528 00529 QString KCalendarSystemJalali::dayString( const QDate &pDate, StringFormat format ) const 00530 { 00531 return KCalendarSystem::dayString( pDate, format ); 00532 } 00533 00534 int KCalendarSystemJalali::yearStringToInteger( const QString &sNum, int &iLength ) const 00535 { 00536 return KCalendarSystem::yearStringToInteger( sNum, iLength ); 00537 } 00538 00539 int KCalendarSystemJalali::monthStringToInteger( const QString &sNum, int &iLength ) const 00540 { 00541 return KCalendarSystem::monthStringToInteger( sNum, iLength ); 00542 } 00543 00544 int KCalendarSystemJalali::dayStringToInteger( const QString & sNum, int & iLength ) const 00545 { 00546 return KCalendarSystem::dayStringToInteger( sNum, iLength ); 00547 } 00548 00549 QString KCalendarSystemJalali::formatDate( const QDate &date, KLocale::DateFormat format ) const 00550 { 00551 return KCalendarSystem::formatDate( date, format ); 00552 } 00553 00554 QDate KCalendarSystemJalali::readDate( const QString &str, bool *ok ) const 00555 { 00556 return KCalendarSystem::readDate( str, ok ); 00557 } 00558 00559 QDate KCalendarSystemJalali::readDate( const QString &intstr, const QString &fmt, bool *ok ) const 00560 { 00561 return KCalendarSystem::readDate( intstr, fmt, ok ); 00562 } 00563 00564 QDate KCalendarSystemJalali::readDate( const QString &str, KLocale::ReadDateFlags flags, bool *ok ) const 00565 { 00566 return KCalendarSystem::readDate( str, flags, ok ); 00567 } 00568 00569 int KCalendarSystemJalali::weekStartDay() const 00570 { 00571 return KCalendarSystem::weekStartDay(); 00572 } 00573 00574 int KCalendarSystemJalali::weekDayOfPray() const 00575 { 00576 return 5; // friday 00577 } 00578 00579 bool KCalendarSystemJalali::isLunar() const 00580 { 00581 return false; 00582 } 00583 00584 bool KCalendarSystemJalali::isLunisolar() const 00585 { 00586 return false; 00587 } 00588 00589 bool KCalendarSystemJalali::isSolar() const 00590 { 00591 return true; 00592 } 00593 00594 bool KCalendarSystemJalali::isProleptic() const 00595 { 00596 return false; 00597 } 00598 00599 bool KCalendarSystemJalali::julianDayToDate( int jd, int &year, int &month, int &day ) const 00600 { 00601 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531. 00602 // This results in a leap day being added to the end of 1404 instead of 1403 00603 // and to the end of 1437 instead of 1436. Check for these dates first and 00604 // return accordingly. Relies on later use of dateToJulianDay() to correctly 00605 // calculate firstDayOfYear in 1404 and 1437, so no other adjustments needed. 00606 if ( jd == 2460755 ) { 00607 year = 1403; 00608 month = 12; 00609 day = 30; 00610 return true; 00611 } 00612 if ( jd == 2472808 ) { 00613 year = 1436; 00614 month = 12; 00615 day = 30; 00616 return true; 00617 } 00618 00619 // From original KDE3 code, source unknown? Unable to contact author or committer to confirm 00620 // Matches Fermilab code, EMACS and D&R so check for PD source, likely Birashk's book 00621 00622 int jdCycleStart; 00623 int daysSinceCycleStart; 00624 int cycle; 00625 int dayInCycle; 00626 int yearInCycle; 00627 dateToJulianDay( 475, 1, 1, jdCycleStart ); 00628 daysSinceCycleStart = jd - jdCycleStart; 00629 cycle = daysSinceCycleStart / 1029983; 00630 dayInCycle = daysSinceCycleStart % 1029983; 00631 if ( dayInCycle == 1029982 ) { 00632 yearInCycle = 2820; 00633 } else { 00634 int aux1 = dayInCycle / 366; 00635 int aux2 = dayInCycle % 366; 00636 yearInCycle = ( ( ( 2134 * aux1 ) + ( 2816 * aux2 ) + 2815 ) / 1028522 ) + aux1 + 1; 00637 } 00638 year = yearInCycle + ( 2820 * cycle ) + 474; 00639 if ( year <= 0 ) { 00640 year = year - 1; 00641 } 00642 00643 int firstDayOfYear; 00644 dateToJulianDay( year, 1, 1, firstDayOfYear ); 00645 int dayinYear = jd - firstDayOfYear + 1; 00646 if( dayinYear <= 186 ) { 00647 month = ( ( dayinYear - 1 ) / 31 ) + 1; 00648 day = dayinYear - ( ( month - 1 ) * 31 ); 00649 } else { 00650 month = ( ( dayinYear - 7 ) / 30 ) + 1; 00651 day = dayinYear - ( ( month - 1 ) * 30 ) - 6; 00652 } 00653 00654 return true; 00655 } 00656 00657 bool KCalendarSystemJalali::dateToJulianDay( int year, int month, int day, int &jd ) const 00658 { 00659 Q_D( const KCalendarSystemJalali ); 00660 00661 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531. 00662 // This results in a leap day being added to the end of 1404 instead of 1403 00663 // and to the end of 1437 instead of 1436. Thus all dates in 1404 and 1437 00664 // are off by 1 JD. Check for these dates first and adjust accordingly. 00665 if ( year == 1403 && month == 12 && day == 30 ) { 00666 jd = 2460755; 00667 return true; 00668 } 00669 if ( year == 1436 && month == 12 && day == 30 ) { 00670 jd = 2472808; 00671 return true; 00672 } 00673 if ( year == 1404 || year == 1437 ) { 00674 if ( month < 12 && day + 1 > d->daysInMonth( year, month ) ) { 00675 day = 1; 00676 month = month + 1; 00677 } else { 00678 day = day + 1; 00679 } 00680 } 00681 00682 // From original KDE3 code, source unknown? Unable to contact author or committer to confirm 00683 // Matches Fermilab code, EMACS and D&R so check for PD source, likely Birashk's book 00684 int epbase; 00685 long epyear; 00686 long monthDays; 00687 00688 if ( year >= 0 ) { 00689 epbase = year - 474; 00690 } else { 00691 epbase = year - 473; 00692 } 00693 00694 epyear = 474 + ( epbase % 2820 ); 00695 00696 if ( month <= 7 ) { 00697 monthDays = ( month - 1 ) * 31; 00698 } else { 00699 monthDays = ( ( month - 1 ) * 30 ) + 6; 00700 } 00701 00702 jd = ( epoch().toJulianDay() - 1 ) + // days before epoch 00703 ( epyear - 1 ) * 365 + // normal days in previous years 00704 ( ( ( epyear * 682 ) - 110 ) / 2816 ) + // leap days in previous years 00705 ( epbase / 2820 ) * 1029983 + 00706 monthDays + // days in previous months this year 00707 day; // days in this month 00708 00709 return true; 00710 }
KDE 4.6 API Reference