KDECore
kcalendarsystemjulian.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2009, 2010 John Layt <john@layt.net> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kcalendarsystemjulian_p.h" 00021 #include "kcalendarsystemprivate_p.h" 00022 00023 #include "kdebug.h" 00024 #include "klocale.h" 00025 #include "kglobal.h" 00026 #include "kconfiggroup.h" 00027 00028 #include <QtCore/QDate> 00029 #include <QtCore/QCharRef> 00030 00031 class KCalendarSystemJulianPrivate : public KCalendarSystemPrivate 00032 { 00033 public: 00034 explicit KCalendarSystemJulianPrivate( KCalendarSystemJulian *q ); 00035 00036 virtual ~KCalendarSystemJulianPrivate(); 00037 00038 // Virtual methods each calendar system must re-implement 00039 virtual KLocale::CalendarSystem calendarSystem() const; 00040 virtual void loadDefaultEraList(); 00041 virtual int monthsInYear( int year ) const; 00042 virtual int daysInMonth( int year, int month ) const; 00043 virtual int daysInYear( int year ) const; 00044 virtual int daysInWeek() const; 00045 virtual bool isLeapYear( int year ) const; 00046 virtual bool hasLeapMonths() const; 00047 virtual bool hasYearZero() const; 00048 virtual int maxDaysInWeek() const; 00049 virtual int maxMonthsInYear() const; 00050 virtual int earliestValidYear() const; 00051 virtual int latestValidYear() const; 00052 00053 bool m_useCommonEra; 00054 }; 00055 00056 // Shared d pointer base class definitions 00057 00058 KCalendarSystemJulianPrivate::KCalendarSystemJulianPrivate( KCalendarSystemJulian *q ) 00059 :KCalendarSystemPrivate( q ) 00060 { 00061 } 00062 00063 KCalendarSystemJulianPrivate::~KCalendarSystemJulianPrivate() 00064 { 00065 } 00066 00067 KLocale::CalendarSystem KCalendarSystemJulianPrivate::calendarSystem() const 00068 { 00069 return KLocale::JulianCalendar; 00070 } 00071 00072 void KCalendarSystemJulianPrivate::loadDefaultEraList() 00073 { 00074 QString name, shortName, format; 00075 00076 KConfigGroup cg( config(), QString::fromLatin1( "KCalendarSystem %1" ).arg( q->calendarType() ) ); 00077 m_useCommonEra = cg.readEntry( "UseCommonEra", false ); 00078 00079 if ( m_useCommonEra ) { 00080 name = i18nc( "Calendar Era: Julian Common Era, years < 0, LongFormat", "Before Common Era" ); 00081 shortName = i18nc( "Calendar Era: Julian Common Era, years < 0, ShortFormat", "BCE" ); 00082 } else { 00083 name = i18nc( "Calendar Era: Julian Christian Era, years < 0, LongFormat", "Before Christ" ); 00084 shortName = i18nc( "Calendar Era: Julian Christian Era, years < 0, ShortFormat", "BC" ); 00085 } 00086 format = i18nc( "(kdedt-format) Julian, BC, full era year format used for %EY, e.g. 2000 BC", "%Ey %EC" ); 00087 addEra( '-', 1, q->epoch().addDays( -1 ), -1, q->earliestValidDate(), name, shortName, format ); 00088 00089 if ( m_useCommonEra ) { 00090 name = i18nc( "Calendar Era: Julian Common Era, years > 0, LongFormat", "Common Era" ); 00091 shortName = i18nc( "Calendar Era: Julian Common Era, years > 0, ShortFormat", "CE" ); 00092 } else { 00093 name = i18nc( "Calendar Era: Julian Christian Era, years > 0, LongFormat", "Anno Domini" ); 00094 shortName = i18nc( "Calendar Era: Julian Christian Era, years > 0, ShortFormat", "AD" ); 00095 } 00096 format = i18nc( "(kdedt-format) Julian, AD, full era year format used for %EY, e.g. 2000 AD", "%Ey %EC" ); 00097 addEra( '+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format ); 00098 } 00099 00100 int KCalendarSystemJulianPrivate::monthsInYear( int year ) const 00101 { 00102 Q_UNUSED( year ) 00103 return 12; 00104 } 00105 00106 int KCalendarSystemJulianPrivate::daysInMonth( int year, int month ) const 00107 { 00108 if ( month == 2 ) { 00109 if ( isLeapYear( year ) ) { 00110 return 29; 00111 } else { 00112 return 28; 00113 } 00114 } 00115 00116 if ( month == 4 || month == 6 || month == 9 || month == 11 ) { 00117 return 30; 00118 } 00119 00120 return 31; 00121 } 00122 00123 int KCalendarSystemJulianPrivate::daysInYear( int year ) const 00124 { 00125 if ( isLeapYear( year ) ) { 00126 return 366; 00127 } else { 00128 return 365; 00129 } 00130 } 00131 00132 int KCalendarSystemJulianPrivate::daysInWeek() const 00133 { 00134 return 7; 00135 } 00136 00137 bool KCalendarSystemJulianPrivate::isLeapYear( int year ) const 00138 { 00139 if ( year < 1 ) { 00140 year = year + 1; 00141 } 00142 00143 if ( year % 4 == 0 ) { 00144 return true; 00145 } 00146 00147 return false; 00148 } 00149 00150 bool KCalendarSystemJulianPrivate::hasLeapMonths() const 00151 { 00152 return false; 00153 } 00154 00155 bool KCalendarSystemJulianPrivate::hasYearZero() const 00156 { 00157 return false; 00158 } 00159 00160 int KCalendarSystemJulianPrivate::maxDaysInWeek() const 00161 { 00162 return 7; 00163 } 00164 00165 int KCalendarSystemJulianPrivate::maxMonthsInYear() const 00166 { 00167 return 12; 00168 } 00169 00170 int KCalendarSystemJulianPrivate::earliestValidYear() const 00171 { 00172 return -4712; 00173 } 00174 00175 int KCalendarSystemJulianPrivate::latestValidYear() const 00176 { 00177 return 9999; 00178 } 00179 00180 00181 KCalendarSystemJulian::KCalendarSystemJulian( const KLocale *locale ) 00182 : KCalendarSystem( *new KCalendarSystemJulianPrivate( this ), KSharedConfig::Ptr(), locale ), 00183 dont_use( 0 ) 00184 { 00185 d_ptr->loadConfig( calendarType() ); 00186 } 00187 00188 KCalendarSystemJulian::KCalendarSystemJulian( const KSharedConfig::Ptr config, const KLocale *locale ) 00189 : KCalendarSystem( *new KCalendarSystemJulianPrivate( this ), config, locale ), 00190 dont_use( 0 ) 00191 { 00192 d_ptr->loadConfig( calendarType() ); 00193 } 00194 00195 KCalendarSystemJulian::KCalendarSystemJulian( KCalendarSystemJulianPrivate &dd, 00196 const KSharedConfig::Ptr config, const KLocale *locale ) 00197 : KCalendarSystem( dd, config, locale ), 00198 dont_use( 0 ) 00199 { 00200 d_ptr->loadConfig( calendarType() ); 00201 } 00202 00203 KCalendarSystemJulian::~KCalendarSystemJulian() 00204 { 00205 delete dont_use; 00206 } 00207 00208 QString KCalendarSystemJulian::calendarType() const 00209 { 00210 return QLatin1String( "julian" ); 00211 } 00212 00213 QDate KCalendarSystemJulian::epoch() const 00214 { 00215 return QDate::fromJulianDay( 1721426 ); 00216 } 00217 00218 QDate KCalendarSystemJulian::earliestValidDate() const 00219 { 00220 // 1 Jan 4712 BC, no year zero, cant be 4713BC due to error in QDate that day 0 is not valid 00221 // and we really need the first in each year to be valid for the date maths 00222 return QDate::fromJulianDay( 366 ); 00223 } 00224 00225 QDate KCalendarSystemJulian::latestValidDate() const 00226 { 00227 // Set to last day of year 9999 until confirm date formats & widgets support > 9999 00228 // 31 Dec 9999 AD, no year zero 00229 return QDate::fromJulianDay( 5373557 ); 00230 } 00231 00232 bool KCalendarSystemJulian::isValid( int year, int month, int day ) const 00233 { 00234 return KCalendarSystem::isValid( year, month, day ); 00235 } 00236 00237 bool KCalendarSystemJulian::isValid( const QDate &date ) const 00238 { 00239 return KCalendarSystem::isValid( date ); 00240 } 00241 00242 bool KCalendarSystemJulian::setDate( QDate &date, int year, int month, int day ) const 00243 { 00244 return KCalendarSystem::setDate( date, year, month, day ); 00245 } 00246 00247 // Deprecated 00248 bool KCalendarSystemJulian::setYMD( QDate &date, int y, int m, int d ) const 00249 { 00250 return KCalendarSystem::setDate( date, y, m, d ); 00251 } 00252 00253 int KCalendarSystemJulian::year( const QDate &date ) const 00254 { 00255 return KCalendarSystem::year( date ); 00256 } 00257 00258 int KCalendarSystemJulian::month( const QDate &date ) const 00259 { 00260 return KCalendarSystem::month( date ); 00261 } 00262 00263 int KCalendarSystemJulian::day( const QDate &date ) const 00264 { 00265 return KCalendarSystem::day( date ); 00266 } 00267 00268 QDate KCalendarSystemJulian::addYears( const QDate &date, int nyears ) const 00269 { 00270 return KCalendarSystem::addYears( date, nyears ); 00271 } 00272 00273 QDate KCalendarSystemJulian::addMonths( const QDate &date, int nmonths ) const 00274 { 00275 return KCalendarSystem::addMonths( date, nmonths ); 00276 } 00277 00278 QDate KCalendarSystemJulian::addDays( const QDate &date, int ndays ) const 00279 { 00280 return KCalendarSystem::addDays( date, ndays ); 00281 } 00282 00283 int KCalendarSystemJulian::monthsInYear( const QDate &date ) const 00284 { 00285 return KCalendarSystem::monthsInYear( date ); 00286 } 00287 00288 int KCalendarSystemJulian::weeksInYear( const QDate &date ) const 00289 { 00290 return KCalendarSystem::weeksInYear( date ); 00291 } 00292 00293 int KCalendarSystemJulian::weeksInYear( int year ) const 00294 { 00295 return KCalendarSystem::weeksInYear( year ); 00296 } 00297 00298 int KCalendarSystemJulian::daysInYear( const QDate &date ) const 00299 { 00300 return KCalendarSystem::daysInYear( date ); 00301 } 00302 00303 int KCalendarSystemJulian::daysInMonth( const QDate &date ) const 00304 { 00305 return KCalendarSystem::daysInMonth( date ); 00306 } 00307 00308 int KCalendarSystemJulian::daysInWeek( const QDate &date ) const 00309 { 00310 return KCalendarSystem::daysInWeek( date ); 00311 } 00312 00313 int KCalendarSystemJulian::dayOfYear( const QDate &date ) const 00314 { 00315 return KCalendarSystem::dayOfYear( date ); 00316 } 00317 00318 int KCalendarSystemJulian::dayOfWeek( const QDate &date ) const 00319 { 00320 return KCalendarSystem::dayOfWeek( date ); 00321 } 00322 00323 int KCalendarSystemJulian::weekNumber( const QDate &date, int * yearNum ) const 00324 { 00325 return KCalendarSystem::weekNumber( date, yearNum ); 00326 } 00327 00328 bool KCalendarSystemJulian::isLeapYear( int year ) const 00329 { 00330 return KCalendarSystem::isLeapYear( year ); 00331 } 00332 00333 bool KCalendarSystemJulian::isLeapYear( const QDate &date ) const 00334 { 00335 return KCalendarSystem::isLeapYear( date ); 00336 } 00337 00338 QString KCalendarSystemJulian::monthName( int month, int year, MonthNameFormat format ) const 00339 { 00340 Q_UNUSED( year ); 00341 00342 if ( format == ShortNamePossessive ) { 00343 switch ( month ) { 00344 case 1: 00345 return ki18nc( "of January", "of Jan" ).toString( locale() ); 00346 case 2: 00347 return ki18nc( "of February", "of Feb" ).toString( locale() ); 00348 case 3: 00349 return ki18nc( "of March", "of Mar" ).toString( locale() ); 00350 case 4: 00351 return ki18nc( "of April", "of Apr" ).toString( locale() ); 00352 case 5: 00353 return ki18nc( "of May short", "of May" ).toString( locale() ); 00354 case 6: 00355 return ki18nc( "of June", "of Jun" ).toString( locale() ); 00356 case 7: 00357 return ki18nc( "of July", "of Jul" ).toString( locale() ); 00358 case 8: 00359 return ki18nc( "of August", "of Aug" ).toString( locale() ); 00360 case 9: 00361 return ki18nc( "of September", "of Sep" ).toString( locale() ); 00362 case 10: 00363 return ki18nc( "of October", "of Oct" ).toString( locale() ); 00364 case 11: 00365 return ki18nc( "of November", "of Nov" ).toString( locale() ); 00366 case 12: 00367 return ki18nc( "of December", "of Dec" ).toString( locale() ); 00368 default: 00369 return QString(); 00370 } 00371 } 00372 00373 if ( format == LongNamePossessive ) { 00374 switch ( month ) { 00375 case 1: 00376 return ki18n( "of January" ).toString( locale() ); 00377 case 2: 00378 return ki18n( "of February" ).toString( locale() ); 00379 case 3: 00380 return ki18n( "of March" ).toString( locale() ); 00381 case 4: 00382 return ki18n( "of April" ).toString( locale() ); 00383 case 5: 00384 return ki18nc( "of May long", "of May" ).toString( locale() ); 00385 case 6: 00386 return ki18n( "of June" ).toString( locale() ); 00387 case 7: 00388 return ki18n( "of July" ).toString( locale() ); 00389 case 8: 00390 return ki18n( "of August" ).toString( locale() ); 00391 case 9: 00392 return ki18n( "of September" ).toString( locale() ); 00393 case 10: 00394 return ki18n( "of October" ).toString( locale() ); 00395 case 11: 00396 return ki18n( "of November" ).toString( locale() ); 00397 case 12: 00398 return ki18n( "of December" ).toString( locale() ); 00399 default: 00400 return QString(); 00401 } 00402 } 00403 00404 if ( format == ShortName ) { 00405 switch ( month ) { 00406 case 1: 00407 return ki18nc( "January", "Jan" ).toString( locale() ); 00408 case 2: 00409 return ki18nc( "February", "Feb" ).toString( locale() ); 00410 case 3: 00411 return ki18nc( "March", "Mar" ).toString( locale() ); 00412 case 4: 00413 return ki18nc( "April", "Apr" ).toString( locale() ); 00414 case 5: 00415 return ki18nc( "May short", "May" ).toString( locale() ); 00416 case 6: 00417 return ki18nc( "June", "Jun" ).toString( locale() ); 00418 case 7: 00419 return ki18nc( "July", "Jul" ).toString( locale() ); 00420 case 8: 00421 return ki18nc( "August", "Aug" ).toString( locale() ); 00422 case 9: 00423 return ki18nc( "September", "Sep" ).toString( locale() ); 00424 case 10: 00425 return ki18nc( "October", "Oct" ).toString( locale() ); 00426 case 11: 00427 return ki18nc( "November", "Nov" ).toString( locale() ); 00428 case 12: 00429 return ki18nc( "December", "Dec" ).toString( locale() ); 00430 default: 00431 return QString(); 00432 } 00433 } 00434 00435 // Default to LongName 00436 switch ( month ) { 00437 case 1: 00438 return ki18n( "January" ).toString( locale() ); 00439 case 2: 00440 return ki18n( "February" ).toString( locale() ); 00441 case 3: 00442 return ki18nc( "March long", "March" ).toString( locale() ); 00443 case 4: 00444 return ki18n( "April" ).toString( locale() ); 00445 case 5: 00446 return ki18nc( "May long", "May" ).toString( locale() ); 00447 case 6: 00448 return ki18n( "June" ).toString( locale() ); 00449 case 7: 00450 return ki18n( "July" ).toString( locale() ); 00451 case 8: 00452 return ki18nc( "August long", "August" ).toString( locale() ); 00453 case 9: 00454 return ki18n( "September" ).toString( locale() ); 00455 case 10: 00456 return ki18n( "October" ).toString( locale() ); 00457 case 11: 00458 return ki18n( "November" ).toString( locale() ); 00459 case 12: 00460 return ki18n( "December" ).toString( locale() ); 00461 default: 00462 return QString(); 00463 } 00464 } 00465 00466 QString KCalendarSystemJulian::monthName( const QDate &date, MonthNameFormat format ) const 00467 { 00468 return KCalendarSystem::monthName( date, format ); 00469 } 00470 00471 00472 QString KCalendarSystemJulian::weekDayName( int weekDay, WeekDayNameFormat format ) const 00473 { 00474 if ( format == ShortDayName ) { 00475 switch ( weekDay ) { 00476 case 1: return ki18nc( "Monday", "Mon" ).toString( locale() ); 00477 case 2: return ki18nc( "Tuesday", "Tue" ).toString( locale() ); 00478 case 3: return ki18nc( "Wednesday", "Wed" ).toString( locale() ); 00479 case 4: return ki18nc( "Thursday", "Thu" ).toString( locale() ); 00480 case 5: return ki18nc( "Friday", "Fri" ).toString( locale() ); 00481 case 6: return ki18nc( "Saturday", "Sat" ).toString( locale() ); 00482 case 7: return ki18nc( "Sunday", "Sun" ).toString( locale() ); 00483 default: return QString(); 00484 } 00485 } 00486 00487 switch ( weekDay ) { 00488 case 1: return ki18n( "Monday" ).toString( locale() ); 00489 case 2: return ki18n( "Tuesday" ).toString( locale() ); 00490 case 3: return ki18n( "Wednesday" ).toString( locale() ); 00491 case 4: return ki18n( "Thursday" ).toString( locale() ); 00492 case 5: return ki18n( "Friday" ).toString( locale() ); 00493 case 6: return ki18n( "Saturday" ).toString( locale() ); 00494 case 7: return ki18n( "Sunday" ).toString( locale() ); 00495 default: return QString(); 00496 } 00497 } 00498 00499 QString KCalendarSystemJulian::weekDayName( const QDate &date, WeekDayNameFormat format ) const 00500 { 00501 return KCalendarSystem::weekDayName( date, format ); 00502 } 00503 00504 QString KCalendarSystemJulian::yearString( const QDate &pDate, StringFormat format ) const 00505 { 00506 return KCalendarSystem::yearString( pDate, format ); 00507 } 00508 00509 QString KCalendarSystemJulian::monthString( const QDate &pDate, StringFormat format ) const 00510 { 00511 return KCalendarSystem::monthString( pDate, format ); 00512 } 00513 00514 QString KCalendarSystemJulian::dayString( const QDate &pDate, StringFormat format ) const 00515 { 00516 return KCalendarSystem::dayString( pDate, format ); 00517 } 00518 00519 int KCalendarSystemJulian::yearStringToInteger( const QString &sNum, int &iLength ) const 00520 { 00521 return KCalendarSystem::yearStringToInteger( sNum, iLength ); 00522 } 00523 00524 int KCalendarSystemJulian::monthStringToInteger( const QString &sNum, int &iLength ) const 00525 { 00526 return KCalendarSystem::monthStringToInteger( sNum, iLength ); 00527 } 00528 00529 int KCalendarSystemJulian::dayStringToInteger( const QString &sNum, int &iLength ) const 00530 { 00531 return KCalendarSystem::dayStringToInteger( sNum, iLength ); 00532 } 00533 00534 QString KCalendarSystemJulian::formatDate( const QDate &date, KLocale::DateFormat format ) const 00535 { 00536 return KCalendarSystem::formatDate( date, format ); 00537 } 00538 00539 QDate KCalendarSystemJulian::readDate( const QString &str, bool *ok ) const 00540 { 00541 return KCalendarSystem::readDate( str, ok ); 00542 } 00543 00544 QDate KCalendarSystemJulian::readDate( const QString &intstr, const QString &fmt, bool *ok ) const 00545 { 00546 return KCalendarSystem::readDate( intstr, fmt, ok ); 00547 } 00548 00549 QDate KCalendarSystemJulian::readDate( const QString &str, KLocale::ReadDateFlags flags, bool *ok ) const 00550 { 00551 return KCalendarSystem::readDate( str, flags, ok ); 00552 } 00553 00554 int KCalendarSystemJulian::weekStartDay() const 00555 { 00556 return KCalendarSystem::weekStartDay(); 00557 } 00558 00559 int KCalendarSystemJulian::weekDayOfPray() const 00560 { 00561 return 7; // sunday 00562 } 00563 00564 bool KCalendarSystemJulian::isLunar() const 00565 { 00566 return false; 00567 } 00568 00569 bool KCalendarSystemJulian::isLunisolar() const 00570 { 00571 return false; 00572 } 00573 00574 bool KCalendarSystemJulian::isSolar() const 00575 { 00576 return true; 00577 } 00578 00579 bool KCalendarSystemJulian::isProleptic() const 00580 { 00581 return true; 00582 } 00583 00584 bool KCalendarSystemJulian::julianDayToDate( int jd, int &year, int &month, int &day ) const 00585 { 00586 // Formula from The Calendar FAQ by Claus Tondering 00587 // http://www.tondering.dk/claus/cal/node3.html#SECTION003161000000000000000 00588 // NOTE: Coded from scratch from mathematical formulas, not copied from 00589 // the Boost licensed source code 00590 00591 int b = 0; 00592 int c = jd + 32082; 00593 int d = ( ( 4 * c ) + 3 ) / 1461; 00594 int e = c - ( ( 1461 * d ) / 4 ); 00595 int m = ( ( 5 * e ) + 2 ) / 153; 00596 day = e - ( ( (153 * m ) + 2 ) / 5 ) + 1; 00597 month = m + 3 - ( 12 * ( m / 10 ) ); 00598 year = ( 100 * b ) + d - 4800 + ( m / 10 ); 00599 00600 // If year is -ve then is BC. In Julian there is no year 0, but the maths 00601 // is easier if we pretend there is, so internally year of 0 = 1BC = -1 outside 00602 if ( year < 1 ) { 00603 year = year - 1; 00604 } 00605 00606 return true; 00607 } 00608 00609 bool KCalendarSystemJulian::dateToJulianDay( int year, int month, int day, int &jd ) const 00610 { 00611 // Formula from The Calendar FAQ by Claus Tondering 00612 // http://www.tondering.dk/claus/cal/node3.html#SECTION003161000000000000000 00613 // NOTE: Coded from scratch from mathematical formulas, not copied from 00614 // the Boost licensed source code 00615 00616 // If year is -ve then is BC. In Julian there is no year 0, but the maths 00617 // is easier if we pretend there is, so internally year of -1 = 1BC = 0 internally 00618 int y; 00619 if ( year < 1 ) { 00620 y = year + 1; 00621 } else { 00622 y = year; 00623 } 00624 00625 int a = ( 14 - month ) / 12; 00626 y = y + 4800 - a; 00627 int m = month + ( 12 * a ) - 3; 00628 00629 jd = day 00630 + ( ( ( 153 * m ) + 2 ) / 5 ) 00631 + ( 365 * y ) 00632 + ( y / 4 ) 00633 - 32083; 00634 00635 return true; 00636 }
KDE 4.6 API Reference