File indexing completed on 2024-04-21 14:55:28

0001 /*
0002     Copyright 2009, 2010 John Layt <john@layt.net>
0003 
0004     This library is free software; you can redistribute it and/or
0005     modify it under the terms of the GNU Library General Public
0006     License as published by the Free Software Foundation; either
0007     version 2 of the License, or (at your option) any later version.
0008 
0009     This library is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012     Library General Public License for more details.
0013 
0014     You should have received a copy of the GNU Library General Public License
0015     along with this library; see the file COPYING.LIB.  If not, write to
0016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017     Boston, MA 02110-1301, USA.
0018 */
0019 
0020 // Derived gregorian kde calendar class
0021 
0022 #include "kcalendarsystemgregorian_p.h"
0023 #include "kcalendarsystemgregorianprivate_p.h"
0024 #include "kcalendarera_p.h"
0025 
0026 #include "klocale.h"
0027 #include "klocalizedstring.h"
0028 #include "kconfiggroup.h"
0029 
0030 #include <QDate>
0031 #include <QCharRef>
0032 
0033 // Shared d pointer base class definitions
0034 
0035 KCalendarSystemGregorianPrivate::KCalendarSystemGregorianPrivate(KCalendarSystemGregorian *q)
0036     : KCalendarSystemPrivate(q)
0037 {
0038 }
0039 
0040 KCalendarSystemGregorianPrivate::~KCalendarSystemGregorianPrivate()
0041 {
0042 }
0043 
0044 void KCalendarSystemGregorianPrivate::loadDefaultEraList()
0045 {
0046     QString name, shortName, format;
0047 
0048     KConfigGroup lcg(config(), QString::fromLatin1("Locale"));
0049     KConfigGroup cg = lcg.group(QString::fromLatin1("KCalendarSystem %1").arg(q->calendarType()));
0050     m_useCommonEra = cg.readEntry("UseCommonEra", false);
0051 
0052     if (m_useCommonEra) {
0053         name = i18nc("Calendar Era: Gregorian Common Era, years < 0, LongFormat", "Before Common Era");
0054         shortName = i18nc("Calendar Era: Gregorian Common Era, years < 0, ShortFormat", "BCE");
0055     } else {
0056         name = i18nc("Calendar Era: Gregorian Christian Era, years < 0, LongFormat", "Before Christ");
0057         shortName = i18nc("Calendar Era: Gregorian Christian Era, years < 0, ShortFormat", "BC");
0058     }
0059     format = i18nc("(kdedt-format) Gregorian, BC, full era year format used for %EY, e.g. 2000 BC", "%Ey %EC");
0060     addEra('-', 1, q->epoch().addDays(-1), -1, q->earliestValidDate(), name, shortName, format);
0061 
0062     if (m_useCommonEra) {
0063         name = i18nc("Calendar Era: Gregorian Common Era, years > 0, LongFormat", "Common Era");
0064         shortName = i18nc("Calendar Era: Gregorian Common Era, years > 0, ShortFormat", "CE");
0065     } else {
0066         name = i18nc("Calendar Era: Gregorian Christian Era, years > 0, LongFormat", "Anno Domini");
0067         shortName = i18nc("Calendar Era: Gregorian Christian Era, years > 0, ShortFormat", "AD");
0068     }
0069     format = i18nc("(kdedt-format) Gregorian, AD, full era year format used for %EY, e.g. 2000 AD", "%Ey %EC");
0070     addEra('+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format);
0071 }
0072 
0073 int KCalendarSystemGregorianPrivate::monthsInYear(int year) const
0074 {
0075     Q_UNUSED(year)
0076     return 12;
0077 }
0078 
0079 int KCalendarSystemGregorianPrivate::daysInMonth(int year, int month) const
0080 {
0081     if (hasYearZero() && year <= 0) {
0082         --year;
0083     }
0084     return QDate(year, month, 1).daysInMonth();
0085 }
0086 
0087 int KCalendarSystemGregorianPrivate::daysInYear(int year) const
0088 {
0089     if (isLeapYear(year)) {
0090         return 366;
0091     } else {
0092         return 365;
0093     }
0094 }
0095 
0096 bool KCalendarSystemGregorianPrivate::isLeapYear(int year) const
0097 {
0098     if (hasYearZero() && year <= 0) {
0099         --year;
0100     }
0101     return QDate::isLeapYear(year);
0102 }
0103 
0104 bool KCalendarSystemGregorianPrivate::hasLeapMonths() const
0105 {
0106     return false;
0107 }
0108 
0109 bool KCalendarSystemGregorianPrivate::hasYearZero() const
0110 {
0111     return false;
0112 }
0113 
0114 int KCalendarSystemGregorianPrivate::maxMonthsInYear() const
0115 {
0116     return 12;
0117 }
0118 
0119 int KCalendarSystemGregorianPrivate::earliestValidYear() const
0120 {
0121     return -9999;
0122 }
0123 
0124 int KCalendarSystemGregorianPrivate::latestValidYear() const
0125 {
0126     return 9999;
0127 }
0128 
0129 QString KCalendarSystemGregorianPrivate::monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const
0130 {
0131     Q_UNUSED(year);
0132 
0133     QStringList languages = locale()->languageList();
0134 
0135     if (format == KLocale::NarrowName) {
0136         switch (month) {
0137         case 1:
0138             return ki18nc("Gregorian month 1 - KLocale::NarrowName",  "J").toString(languages);
0139         case 2:
0140             return ki18nc("Gregorian month 2 - KLocale::NarrowName",  "F").toString(languages);
0141         case 3:
0142             return ki18nc("Gregorian month 3 - KLocale::NarrowName",  "M").toString(languages);
0143         case 4:
0144             return ki18nc("Gregorian month 4 - KLocale::NarrowName",  "A").toString(languages);
0145         case 5:
0146             return ki18nc("Gregorian month 5 - KLocale::NarrowName",  "M").toString(languages);
0147         case 6:
0148             return ki18nc("Gregorian month 6 - KLocale::NarrowName",  "J").toString(languages);
0149         case 7:
0150             return ki18nc("Gregorian month 7 - KLocale::NarrowName",  "J").toString(languages);
0151         case 8:
0152             return ki18nc("Gregorian month 8 - KLocale::NarrowName",  "A").toString(languages);
0153         case 9:
0154             return ki18nc("Gregorian month 9 - KLocale::NarrowName",  "S").toString(languages);
0155         case 10:
0156             return ki18nc("Gregorian month 10 - KLocale::NarrowName", "O").toString(languages);
0157         case 11:
0158             return ki18nc("Gregorian month 11 - KLocale::NarrowName", "N").toString(languages);
0159         case 12:
0160             return ki18nc("Gregorian month 12 - KLocale::NarrowName", "D").toString(languages);
0161         default:
0162             return QString();
0163         }
0164     }
0165 
0166     if (format == KLocale::ShortName && possessive) {
0167         switch (month) {
0168         case 1:
0169             return ki18nc("Gregorian month 1 - KLocale::ShortName Possessive",  "of Jan").toString(languages);
0170         case 2:
0171             return ki18nc("Gregorian month 2 - KLocale::ShortName Possessive",  "of Feb").toString(languages);
0172         case 3:
0173             return ki18nc("Gregorian month 3 - KLocale::ShortName Possessive",  "of Mar").toString(languages);
0174         case 4:
0175             return ki18nc("Gregorian month 4 - KLocale::ShortName Possessive",  "of Apr").toString(languages);
0176         case 5:
0177             return ki18nc("Gregorian month 5 - KLocale::ShortName Possessive",  "of May").toString(languages);
0178         case 6:
0179             return ki18nc("Gregorian month 6 - KLocale::ShortName Possessive",  "of Jun").toString(languages);
0180         case 7:
0181             return ki18nc("Gregorian month 7 - KLocale::ShortName Possessive",  "of Jul").toString(languages);
0182         case 8:
0183             return ki18nc("Gregorian month 8 - KLocale::ShortName Possessive",  "of Aug").toString(languages);
0184         case 9:
0185             return ki18nc("Gregorian month 9 - KLocale::ShortName Possessive",  "of Sep").toString(languages);
0186         case 10:
0187             return ki18nc("Gregorian month 10 - KLocale::ShortName Possessive", "of Oct").toString(languages);
0188         case 11:
0189             return ki18nc("Gregorian month 11 - KLocale::ShortName Possessive", "of Nov").toString(languages);
0190         case 12:
0191             return ki18nc("Gregorian month 12 - KLocale::ShortName Possessive", "of Dec").toString(languages);
0192         default:
0193             return QString();
0194         }
0195     }
0196 
0197     if (format == KLocale::ShortName && !possessive) {
0198         switch (month) {
0199         case 1:
0200             return ki18nc("Gregorian month 1 - KLocale::ShortName",  "Jan").toString(languages);
0201         case 2:
0202             return ki18nc("Gregorian month 2 - KLocale::ShortName",  "Feb").toString(languages);
0203         case 3:
0204             return ki18nc("Gregorian month 3 - KLocale::ShortName",  "Mar").toString(languages);
0205         case 4:
0206             return ki18nc("Gregorian month 4 - KLocale::ShortName",  "Apr").toString(languages);
0207         case 5:
0208             return ki18nc("Gregorian month 5 - KLocale::ShortName",  "May").toString(languages);
0209         case 6:
0210             return ki18nc("Gregorian month 6 - KLocale::ShortName",  "Jun").toString(languages);
0211         case 7:
0212             return ki18nc("Gregorian month 7 - KLocale::ShortName",  "Jul").toString(languages);
0213         case 8:
0214             return ki18nc("Gregorian month 8 - KLocale::ShortName",  "Aug").toString(languages);
0215         case 9:
0216             return ki18nc("Gregorian month 9 - KLocale::ShortName",  "Sep").toString(languages);
0217         case 10:
0218             return ki18nc("Gregorian month 10 - KLocale::ShortName", "Oct").toString(languages);
0219         case 11:
0220             return ki18nc("Gregorian month 11 - KLocale::ShortName", "Nov").toString(languages);
0221         case 12:
0222             return ki18nc("Gregorian month 12 - KLocale::ShortName", "Dec").toString(languages);
0223         default:
0224             return QString();
0225         }
0226     }
0227 
0228     if (format == KLocale::LongName && possessive) {
0229         switch (month) {
0230         case 1:
0231             return ki18nc("Gregorian month 1 - KLocale::LongName Possessive",  "of January").toString(languages);
0232         case 2:
0233             return ki18nc("Gregorian month 2 - KLocale::LongName Possessive",  "of February").toString(languages);
0234         case 3:
0235             return ki18nc("Gregorian month 3 - KLocale::LongName Possessive",  "of March").toString(languages);
0236         case 4:
0237             return ki18nc("Gregorian month 4 - KLocale::LongName Possessive",  "of April").toString(languages);
0238         case 5:
0239             return ki18nc("Gregorian month 5 - KLocale::LongName Possessive",  "of May").toString(languages);
0240         case 6:
0241             return ki18nc("Gregorian month 6 - KLocale::LongName Possessive",  "of June").toString(languages);
0242         case 7:
0243             return ki18nc("Gregorian month 7 - KLocale::LongName Possessive",  "of July").toString(languages);
0244         case 8:
0245             return ki18nc("Gregorian month 8 - KLocale::LongName Possessive",  "of August").toString(languages);
0246         case 9:
0247             return ki18nc("Gregorian month 9 - KLocale::LongName Possessive",  "of September").toString(languages);
0248         case 10:
0249             return ki18nc("Gregorian month 10 - KLocale::LongName Possessive", "of October").toString(languages);
0250         case 11:
0251             return ki18nc("Gregorian month 11 - KLocale::LongName Possessive", "of November").toString(languages);
0252         case 12:
0253             return ki18nc("Gregorian month 12 - KLocale::LongName Possessive", "of December").toString(languages);
0254         default:
0255             return QString();
0256         }
0257     }
0258 
0259     // Default to LongName
0260     switch (month) {
0261     case 1:
0262         return ki18nc("Gregorian month 1 - KLocale::LongName",  "January").toString(languages);
0263     case 2:
0264         return ki18nc("Gregorian month 2 - KLocale::LongName",  "February").toString(languages);
0265     case 3:
0266         return ki18nc("Gregorian month 3 - KLocale::LongName",  "March").toString(languages);
0267     case 4:
0268         return ki18nc("Gregorian month 4 - KLocale::LongName",  "April").toString(languages);
0269     case 5:
0270         return ki18nc("Gregorian month 5 - KLocale::LongName",  "May").toString(languages);
0271     case 6:
0272         return ki18nc("Gregorian month 6 - KLocale::LongName",  "June").toString(languages);
0273     case 7:
0274         return ki18nc("Gregorian month 7 - KLocale::LongName",  "July").toString(languages);
0275     case 8:
0276         return ki18nc("Gregorian month 8 - KLocale::LongName",  "August").toString(languages);
0277     case 9:
0278         return ki18nc("Gregorian month 9 - KLocale::LongName",  "September").toString(languages);
0279     case 10:
0280         return ki18nc("Gregorian month 10 - KLocale::LongName", "October").toString(languages);
0281     case 11:
0282         return ki18nc("Gregorian month 11 - KLocale::LongName", "November").toString(languages);
0283     case 12:
0284         return ki18nc("Gregorian month 12 - KLocale::LongName", "December").toString(languages);
0285     default:
0286         return QString();
0287     }
0288 }
0289 
0290 QString KCalendarSystemGregorianPrivate::weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const
0291 {
0292     QStringList languages = locale()->languageList();
0293 
0294     if (format == KLocale::NarrowName) {
0295         switch (weekDay) {
0296         case 1:
0297             return ki18nc("Gregorian weekday 1 - KLocale::NarrowName ", "M").toString(languages);
0298         case 2:
0299             return ki18nc("Gregorian weekday 2 - KLocale::NarrowName ", "T").toString(languages);
0300         case 3:
0301             return ki18nc("Gregorian weekday 3 - KLocale::NarrowName ", "W").toString(languages);
0302         case 4:
0303             return ki18nc("Gregorian weekday 4 - KLocale::NarrowName ", "T").toString(languages);
0304         case 5:
0305             return ki18nc("Gregorian weekday 5 - KLocale::NarrowName ", "F").toString(languages);
0306         case 6:
0307             return ki18nc("Gregorian weekday 6 - KLocale::NarrowName ", "S").toString(languages);
0308         case 7:
0309             return ki18nc("Gregorian weekday 7 - KLocale::NarrowName ", "S").toString(languages);
0310         default:
0311             return QString();
0312         }
0313     }
0314 
0315     if (format == KLocale::ShortName  || format == KLocale:: ShortNumber) {
0316         switch (weekDay) {
0317         case 1:
0318             return ki18nc("Gregorian weekday 1 - KLocale::ShortName", "Mon").toString(languages);
0319         case 2:
0320             return ki18nc("Gregorian weekday 2 - KLocale::ShortName", "Tue").toString(languages);
0321         case 3:
0322             return ki18nc("Gregorian weekday 3 - KLocale::ShortName", "Wed").toString(languages);
0323         case 4:
0324             return ki18nc("Gregorian weekday 4 - KLocale::ShortName", "Thu").toString(languages);
0325         case 5:
0326             return ki18nc("Gregorian weekday 5 - KLocale::ShortName", "Fri").toString(languages);
0327         case 6:
0328             return ki18nc("Gregorian weekday 6 - KLocale::ShortName", "Sat").toString(languages);
0329         case 7:
0330             return ki18nc("Gregorian weekday 7 - KLocale::ShortName", "Sun").toString(languages);
0331         default: return QString();
0332         }
0333     }
0334 
0335     switch (weekDay) {
0336     case 1:
0337         return ki18nc("Gregorian weekday 1 - KLocale::LongName", "Monday").toString(languages);
0338     case 2:
0339         return ki18nc("Gregorian weekday 2 - KLocale::LongName", "Tuesday").toString(languages);
0340     case 3:
0341         return ki18nc("Gregorian weekday 3 - KLocale::LongName", "Wednesday").toString(languages);
0342     case 4:
0343         return ki18nc("Gregorian weekday 4 - KLocale::LongName", "Thursday").toString(languages);
0344     case 5:
0345         return ki18nc("Gregorian weekday 5 - KLocale::LongName", "Friday").toString(languages);
0346     case 6:
0347         return ki18nc("Gregorian weekday 6 - KLocale::LongName", "Saturday").toString(languages);
0348     case 7:
0349         return ki18nc("Gregorian weekday 7 - KLocale::LongName", "Sunday").toString(languages);
0350     default:
0351         return QString();
0352     }
0353 }
0354 
0355 KCalendarSystemGregorian::KCalendarSystemGregorian(const KSharedConfig::Ptr config,
0356         const KLocale *locale)
0357     : KCalendarSystem(*new KCalendarSystemGregorianPrivate(this), config, locale)
0358 {
0359     d_ptr->loadConfig(calendarType());
0360 }
0361 
0362 KCalendarSystemGregorian::KCalendarSystemGregorian(KCalendarSystemGregorianPrivate &dd,
0363         const KSharedConfig::Ptr config,
0364         const KLocale *locale)
0365     : KCalendarSystem(dd, config, locale)
0366 {
0367     d_ptr->loadConfig(calendarType());
0368 }
0369 
0370 KCalendarSystemGregorian::~KCalendarSystemGregorian()
0371 {
0372 }
0373 
0374 QString KCalendarSystemGregorian::calendarType() const
0375 {
0376     return QLatin1String("gregorian");
0377 }
0378 
0379 KLocale::CalendarSystem KCalendarSystemGregorian::calendarSystem() const
0380 {
0381     return KLocale::GregorianCalendar;
0382 }
0383 
0384 QDate KCalendarSystemGregorian::epoch() const
0385 {
0386     return QDate::fromJulianDay(1721426);
0387 }
0388 
0389 QDate KCalendarSystemGregorian::earliestValidDate() const
0390 {
0391     Q_D(const KCalendarSystemGregorian);
0392 
0393     // Set to first day of year 9999 until confirm date formats & widgets support > 9999
0394     return QDate(d->hasYearZero() ? -10000 : -9999, 1, 1);
0395     // return QDate(std::num_limits<int>::min(), 1, 1);
0396 }
0397 
0398 QDate KCalendarSystemGregorian::latestValidDate() const
0399 {
0400     // Set to last day of year 9999 until confirm date formats & widgets support > 9999
0401     // In Gregorian this is 9999-12-31, which is  is jd 5373484
0402     return QDate(9999, 12, 31);
0403     // return QDate(std::num_limits<int>::max(), 12, 31);
0404 }
0405 
0406 QString KCalendarSystemGregorian::monthName(int month, int year, MonthNameFormat format) const
0407 {
0408     return KCalendarSystem::monthName(month, year, format);
0409 }
0410 
0411 QString KCalendarSystemGregorian::monthName(const QDate &date, MonthNameFormat format) const
0412 {
0413     return KCalendarSystem::monthName(date, format);
0414 }
0415 
0416 QString KCalendarSystemGregorian::weekDayName(int weekDay, WeekDayNameFormat format) const
0417 {
0418     return KCalendarSystem::weekDayName(weekDay, format);
0419 }
0420 
0421 QString KCalendarSystemGregorian::weekDayName(const QDate &date, WeekDayNameFormat format) const
0422 {
0423     return KCalendarSystem::weekDayName(date, format);
0424 }
0425 
0426 int KCalendarSystemGregorian::yearStringToInteger(const QString &sNum, int &iLength) const
0427 {
0428     return KCalendarSystem::yearStringToInteger(sNum, iLength);
0429 }
0430 
0431 bool KCalendarSystemGregorian::isLunar() const
0432 {
0433     return false;
0434 }
0435 
0436 bool KCalendarSystemGregorian::isLunisolar() const
0437 {
0438     return false;
0439 }
0440 
0441 bool KCalendarSystemGregorian::isSolar() const
0442 {
0443     return true;
0444 }
0445 
0446 bool KCalendarSystemGregorian::isProleptic() const
0447 {
0448     return true;
0449 }
0450 
0451 bool KCalendarSystemGregorian::julianDayToDate(qint64 jd, int &year, int &month, int &day) const
0452 {
0453     Q_D(const KCalendarSystemGregorian);
0454 
0455     QDate date = QDate::fromJulianDay(jd);
0456     date.getDate(&year, &month, &day);
0457 
0458     if (d->hasYearZero() && year < 0) {
0459         ++year;
0460     }
0461 
0462     return date.isValid();
0463 }
0464 
0465 bool KCalendarSystemGregorian::dateToJulianDay(int year, int month, int day, qint64 &jd) const
0466 {
0467     Q_D(const KCalendarSystemGregorian);
0468 
0469     if (d->hasYearZero() && year <= 0) {
0470         --year;
0471     }
0472 
0473     QDate date;
0474     date.setDate(year, month, day);
0475 
0476     jd = date.toJulianDay();
0477     return date.isValid();
0478 }