File indexing completed on 2024-07-21 12:07:33

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 #include "kcalendarsystemindiannational_p.h"
0021 #include "kcalendarsystemprivate_p.h"
0022 
0023 #include "klocale.h"
0024 #include "klocalizedstring.h"
0025 
0026 #include <QDate>
0027 #include <QCharRef>
0028 
0029 class KCalendarSystemIndianNationalPrivate : public KCalendarSystemPrivate
0030 {
0031 public:
0032     KDELIBS4SUPPORT_DEPRECATED explicit KCalendarSystemIndianNationalPrivate(KCalendarSystemIndianNational *q);
0033 
0034     ~KCalendarSystemIndianNationalPrivate() override;
0035 
0036     // Virtual methods each calendar system must re-implement
0037     void loadDefaultEraList() override;
0038     int monthsInYear(int year) const override;
0039     int daysInMonth(int year, int month) const override;
0040     int daysInYear(int year) const override;
0041     bool isLeapYear(int year) const override;
0042     bool hasLeapMonths() const override;
0043     bool hasYearZero() const override;
0044     int maxMonthsInYear() const override;
0045     int earliestValidYear() const override;
0046     int latestValidYear() const override;
0047     QString monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const override;
0048     QString weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const override;
0049 };
0050 
0051 // Shared d pointer base class definitions
0052 
0053 KCalendarSystemIndianNationalPrivate::KCalendarSystemIndianNationalPrivate(KCalendarSystemIndianNational *q)
0054     : KCalendarSystemPrivate(q)
0055 {
0056 }
0057 
0058 KCalendarSystemIndianNationalPrivate::~KCalendarSystemIndianNationalPrivate()
0059 {
0060 }
0061 
0062 void KCalendarSystemIndianNationalPrivate::loadDefaultEraList()
0063 {
0064     QString name, shortName, format;
0065     // Saka Era
0066     name = i18nc("Calendar Era: Indian National Saka Era, years > 0, LongFormat", "Saka Era");
0067     shortName = i18nc("Calendar Era: Indian National Saka Era, years > 0, ShortFormat", "SE");
0068     format = i18nc("(kdedt-format) Indian National, SE, full era year format used for %EY, e.g. 2000 SE", "%Ey %EC");
0069     addEra('+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format);
0070 }
0071 
0072 int KCalendarSystemIndianNationalPrivate::monthsInYear(int year) const
0073 {
0074     Q_UNUSED(year)
0075     return 12;
0076 }
0077 
0078 int KCalendarSystemIndianNationalPrivate::daysInMonth(int year, int month) const
0079 {
0080     if (month == 1) {
0081         if (isLeapYear(year)) {
0082             return 31;
0083         } else {
0084             return 30;
0085         }
0086     }
0087 
0088     if (month >= 2 && month <= 6) {
0089         return 31;
0090     }
0091 
0092     return 30;
0093 }
0094 
0095 int KCalendarSystemIndianNationalPrivate::daysInYear(int year) const
0096 {
0097     if (isLeapYear(year)) {
0098         return 366;
0099     } else {
0100         return 365;
0101     }
0102 }
0103 
0104 bool KCalendarSystemIndianNationalPrivate::isLeapYear(int year) const
0105 {
0106     //Uses same rule as Gregorian, and is explicitly synchronized to Gregorian
0107     //so add 78 years to get Gregorian year and apply Gregorian calculation
0108     year = year + 78;
0109     if (!hasYearZero() && year < 1) {
0110         year = year + 1;
0111     }
0112 
0113     if (year % 4 == 0) {
0114         if (year % 100 != 0) {
0115             return true;
0116         } else if (year % 400 == 0) {
0117             return true;
0118         }
0119     }
0120 
0121     return false;
0122 }
0123 
0124 bool KCalendarSystemIndianNationalPrivate::hasLeapMonths() const
0125 {
0126     return false;
0127 }
0128 
0129 bool KCalendarSystemIndianNationalPrivate::hasYearZero() const
0130 {
0131     return true;
0132 }
0133 
0134 int KCalendarSystemIndianNationalPrivate::maxMonthsInYear() const
0135 {
0136     return 12;
0137 }
0138 
0139 int KCalendarSystemIndianNationalPrivate::earliestValidYear() const
0140 {
0141     return 0;
0142 }
0143 
0144 int KCalendarSystemIndianNationalPrivate::latestValidYear() const
0145 {
0146     return 9999;
0147 }
0148 
0149 QString KCalendarSystemIndianNationalPrivate::monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const
0150 {
0151     Q_UNUSED(year);
0152 
0153     QStringList languages = locale()->languageList();
0154 
0155     if (format == KLocale::NarrowName) {
0156         switch (month) {
0157         case 1:
0158             return ki18nc("Indian National month 1 - KLocale::NarrowName",  "C").toString(languages);
0159         case 2:
0160             return ki18nc("Indian National month 2 - KLocale::NarrowName",  "V").toString(languages);
0161         case 3:
0162             return ki18nc("Indian National month 3 - KLocale::NarrowName",  "J").toString(languages);
0163         case 4:
0164             return ki18nc("Indian National month 4 - KLocale::NarrowName",  "Ā").toString(languages);
0165         case 5:
0166             return ki18nc("Indian National month 5 - KLocale::NarrowName",  "S").toString(languages);
0167         case 6:
0168             return ki18nc("Indian National month 6 - KLocale::NarrowName",  "B").toString(languages);
0169         case 7:
0170             return ki18nc("Indian National month 7 - KLocale::NarrowName",  "Ā").toString(languages);
0171         case 8:
0172             return ki18nc("Indian National month 8 - KLocale::NarrowName",  "K").toString(languages);
0173         case 9:
0174             return ki18nc("Indian National month 9 - KLocale::NarrowName",  "A").toString(languages);
0175         case 10:
0176             return ki18nc("Indian National month 10 - KLocale::NarrowName", "P").toString(languages);
0177         case 11:
0178             return ki18nc("Indian National month 11 - KLocale::NarrowName", "M").toString(languages);
0179         case 12:
0180             return ki18nc("Indian National month 12 - KLocale::NarrowName", "P").toString(languages);
0181         default:
0182             return QString();
0183         }
0184     }
0185 
0186     if (format == KLocale::ShortName && possessive) {
0187         switch (month) {
0188         case 1:
0189             return ki18nc("Indian National month 1 - KLocale::ShortName Possessive",  "of Cha").toString(languages);
0190         case 2:
0191             return ki18nc("Indian National month 2 - KLocale::ShortName Possessive",  "of Vai").toString(languages);
0192         case 3:
0193             return ki18nc("Indian National month 3 - KLocale::ShortName Possessive",  "of Jya").toString(languages);
0194         case 4:
0195             return ki18nc("Indian National month 4 - KLocale::ShortName Possessive",  "of Āsh").toString(languages);
0196         case 5:
0197             return ki18nc("Indian National month 5 - KLocale::ShortName Possessive",  "of Shr").toString(languages);
0198         case 6:
0199             return ki18nc("Indian National month 6 - KLocale::ShortName Possessive",  "of Bhā").toString(languages);
0200         case 7:
0201             return ki18nc("Indian National month 7 - KLocale::ShortName Possessive",  "of Āsw").toString(languages);
0202         case 8:
0203             return ki18nc("Indian National month 8 - KLocale::ShortName Possessive",  "of Kār").toString(languages);
0204         case 9:
0205             return ki18nc("Indian National month 9 - KLocale::ShortName Possessive",  "of Agr").toString(languages);
0206         case 10:
0207             return ki18nc("Indian National month 10 - KLocale::ShortName Possessive", "of Pau").toString(languages);
0208         case 11:
0209             return ki18nc("Indian National month 11 - KLocale::ShortName Possessive", "of Māg").toString(languages);
0210         case 12:
0211             return ki18nc("Indian National month 12 - KLocale::ShortName Possessive", "of Phā").toString(languages);
0212         default:
0213             return QString();
0214         }
0215     }
0216 
0217     if (format == KLocale::ShortName && !possessive) {
0218         switch (month) {
0219         case 1:
0220             return ki18nc("Indian National month 1 - KLocale::ShortName",  "Cha").toString(languages);
0221         case 2:
0222             return ki18nc("Indian National month 2 - KLocale::ShortName",  "Vai").toString(languages);
0223         case 3:
0224             return ki18nc("Indian National month 3 - KLocale::ShortName",  "Jya").toString(languages);
0225         case 4:
0226             return ki18nc("Indian National month 4 - KLocale::ShortName",  "Āsh").toString(languages);
0227         case 5:
0228             return ki18nc("Indian National month 5 - KLocale::ShortName",  "Shr").toString(languages);
0229         case 6:
0230             return ki18nc("Indian National month 6 - KLocale::ShortName",  "Bhā").toString(languages);
0231         case 7:
0232             return ki18nc("Indian National month 7 - KLocale::ShortName",  "Āsw").toString(languages);
0233         case 8:
0234             return ki18nc("Indian National month 8 - KLocale::ShortName",  "Kār").toString(languages);
0235         case 9:
0236             return ki18nc("Indian National month 9 - KLocale::ShortName",  "Agr").toString(languages);
0237         case 10:
0238             return ki18nc("Indian National month 10 - KLocale::ShortName", "Pau").toString(languages);
0239         case 11:
0240             return ki18nc("Indian National month 11 - KLocale::ShortName", "Māg").toString(languages);
0241         case 12:
0242             return ki18nc("Indian National month 12 - KLocale::ShortName", "Phā").toString(languages);
0243         default:
0244             return QString();
0245         }
0246     }
0247 
0248     if (format == KLocale::LongName && possessive) {
0249         switch (month) {
0250         case 1:
0251             return ki18nc("Indian National month 1 - KLocale::LongName Possessive",  "of Chaitra").toString(languages);
0252         case 2:
0253             return ki18nc("Indian National month 2 - KLocale::LongName Possessive",  "of Vaishākh").toString(languages);
0254         case 3:
0255             return ki18nc("Indian National month 3 - KLocale::LongName Possessive",  "of Jyaishtha").toString(languages);
0256         case 4:
0257             return ki18nc("Indian National month 4 - KLocale::LongName Possessive",  "of Āshādha").toString(languages);
0258         case 5:
0259             return ki18nc("Indian National month 5 - KLocale::LongName Possessive",  "of Shrāvana").toString(languages);
0260         case 6:
0261             return ki18nc("Indian National month 6 - KLocale::LongName Possessive",  "of Bhādrapad").toString(languages);
0262         case 7:
0263             return ki18nc("Indian National month 7 - KLocale::LongName Possessive",  "of Āshwin").toString(languages);
0264         case 8:
0265             return ki18nc("Indian National month 8 - KLocale::LongName Possessive",  "of Kārtik").toString(languages);
0266         case 9:
0267             return ki18nc("Indian National month 9 - KLocale::LongName Possessive",  "of Agrahayana").toString(languages);
0268         case 10:
0269             return ki18nc("Indian National month 10 - KLocale::LongName Possessive", "of Paush").toString(languages);
0270         case 11:
0271             return ki18nc("Indian National month 11 - KLocale::LongName Possessive", "of Māgh").toString(languages);
0272         case 12:
0273             return ki18nc("Indian National month 12 - KLocale::LongName Possessive", "of Phālgun").toString(languages);
0274         default:
0275             return QString();
0276         }
0277     }
0278 
0279     // Default to LongName
0280     switch (month) {
0281     case 1:
0282         return ki18nc("Indian National month 1 - KLocale::LongName",  "Chaitra").toString(languages);
0283     case 2:
0284         return ki18nc("Indian National month 2 - KLocale::LongName",  "Vaishākh").toString(languages);
0285     case 3:
0286         return ki18nc("Indian National month 3 - KLocale::LongName",  "Jyaishtha").toString(languages);
0287     case 4:
0288         return ki18nc("Indian National month 4 - KLocale::LongName",  "Āshādha").toString(languages);
0289     case 5:
0290         return ki18nc("Indian National month 5 - KLocale::LongName",  "Shrāvana").toString(languages);
0291     case 6:
0292         return ki18nc("Indian National month 6 - KLocale::LongName",  "Bhādrapad").toString(languages);
0293     case 7:
0294         return ki18nc("Indian National month 7 - KLocale::LongName",  "Āshwin").toString(languages);
0295     case 8:
0296         return ki18nc("Indian National month 8 - KLocale::LongName",  "Kārtik").toString(languages);
0297     case 9:
0298         return ki18nc("Indian National month 9 - KLocale::LongName",  "Agrahayana").toString(languages);
0299     case 10:
0300         return ki18nc("Indian National month 10 - KLocale::LongName", "Paush").toString(languages);
0301     case 11:
0302         return ki18nc("Indian National month 11 - KLocale::LongName", "Māgh").toString(languages);
0303     case 12:
0304         return ki18nc("Indian National month 12 - KLocale::LongName", "Phālgun").toString(languages);
0305     default:
0306         return QString();
0307     }
0308 }
0309 
0310 QString KCalendarSystemIndianNationalPrivate::weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const
0311 {
0312     QStringList languages = locale()->languageList();
0313 
0314     if (format == KLocale::NarrowName) {
0315         switch (weekDay) {
0316         case 1:
0317             return ki18nc("Indian National weekday 1 - KLocale::NarrowName ", "S").toString(languages);
0318         case 2:
0319             return ki18nc("Indian National weekday 2 - KLocale::NarrowName ", "M").toString(languages);
0320         case 3:
0321             return ki18nc("Indian National weekday 3 - KLocale::NarrowName ", "B").toString(languages);
0322         case 4:
0323             return ki18nc("Indian National weekday 4 - KLocale::NarrowName ", "G").toString(languages);
0324         case 5:
0325             return ki18nc("Indian National weekday 5 - KLocale::NarrowName ", "S").toString(languages);
0326         case 6:
0327             return ki18nc("Indian National weekday 6 - KLocale::NarrowName ", "S").toString(languages);
0328         case 7:
0329             return ki18nc("Indian National weekday 7 - KLocale::NarrowName ", "R").toString(languages);
0330         default:
0331             return QString();
0332         }
0333     }
0334 
0335     if (format == KLocale::ShortName  || format == KLocale:: ShortNumber) {
0336         switch (weekDay) {
0337         case 1:
0338             return ki18nc("Indian National weekday 1 - KLocale::ShortName", "Som").toString(languages);
0339         case 2:
0340             return ki18nc("Indian National weekday 2 - KLocale::ShortName", "Mañ").toString(languages);
0341         case 3:
0342             return ki18nc("Indian National weekday 3 - KLocale::ShortName", "Bud").toString(languages);
0343         case 4:
0344             return ki18nc("Indian National weekday 4 - KLocale::ShortName", "Gur").toString(languages);
0345         case 5:
0346             return ki18nc("Indian National weekday 5 - KLocale::ShortName", "Suk").toString(languages);
0347         case 6:
0348             return ki18nc("Indian National weekday 6 - KLocale::ShortName", "San").toString(languages);
0349         case 7:
0350             return ki18nc("Indian National weekday 7 - KLocale::ShortName", "Rav").toString(languages);
0351         default: return QString();
0352         }
0353     }
0354 
0355     switch (weekDay) {
0356     case 1:
0357         return ki18nc("Indian National weekday 1 - KLocale::LongName", "Somavãra").toString(languages);
0358     case 2:
0359         return ki18nc("Indian National weekday 2 - KLocale::LongName", "Mañgalvã").toString(languages);
0360     case 3:
0361         return ki18nc("Indian National weekday 3 - KLocale::LongName", "Budhavãra").toString(languages);
0362     case 4:
0363         return ki18nc("Indian National weekday 4 - KLocale::LongName", "Guruvãra").toString(languages);
0364     case 5:
0365         return ki18nc("Indian National weekday 5 - KLocale::LongName", "Sukravãra").toString(languages);
0366     case 6:
0367         return ki18nc("Indian National weekday 6 - KLocale::LongName", "Sanivãra").toString(languages);
0368     case 7:
0369         return ki18nc("Indian National weekday 7 - KLocale::LongName", "Raviãra").toString(languages);
0370     default:
0371         return QString();
0372     }
0373 }
0374 
0375 KCalendarSystemIndianNational::KCalendarSystemIndianNational(const KSharedConfig::Ptr config, const KLocale *locale)
0376     : KCalendarSystem(*new KCalendarSystemIndianNationalPrivate(this), config, locale)
0377 {
0378     d_ptr->loadConfig(calendarType());
0379 }
0380 
0381 KCalendarSystemIndianNational::KCalendarSystemIndianNational(KCalendarSystemIndianNationalPrivate &dd,
0382         const KSharedConfig::Ptr config,
0383         const KLocale *locale)
0384     : KCalendarSystem(dd, config, locale)
0385 {
0386     d_ptr->loadConfig(calendarType());
0387 }
0388 
0389 KCalendarSystemIndianNational::~KCalendarSystemIndianNational()
0390 {
0391 }
0392 
0393 QString KCalendarSystemIndianNational::calendarType() const
0394 {
0395     return QLatin1String("indian-national");
0396 }
0397 
0398 KLocale::CalendarSystem KCalendarSystemIndianNational::calendarSystem() const
0399 {
0400     return KLocale::IndianNationalCalendar;
0401 }
0402 
0403 QDate KCalendarSystemIndianNational::epoch() const
0404 {
0405     //0000-01-01, has Year 0.
0406     //0078-03-22 AD Gregorian / 0078-03-24 AD Julian
0407     return QDate::fromJulianDay(1749994);
0408 }
0409 
0410 QDate KCalendarSystemIndianNational::earliestValidDate() const
0411 {
0412     //0000-01-01, has Year 0.
0413     //0078-03-22 AD Gregorian / 0078-03-24 AD Julian
0414     //Don't do proleptic yet, need to check
0415     return QDate::fromJulianDay(1749630);
0416 }
0417 
0418 QDate KCalendarSystemIndianNational::latestValidDate() const
0419 {
0420     // Set to last day of year 9999 until confirm date formats & widgets support > 9999
0421     //9999-12-30
0422     //10078-03-21 AD Gregorian
0423     return QDate::fromJulianDay(5402054);
0424 }
0425 
0426 QString KCalendarSystemIndianNational::monthName(int month, int year, MonthNameFormat format) const
0427 {
0428     return KCalendarSystem::monthName(month, year, format);
0429 }
0430 
0431 QString KCalendarSystemIndianNational::monthName(const QDate &date, MonthNameFormat format) const
0432 {
0433     return KCalendarSystem::monthName(date, format);
0434 }
0435 
0436 QString KCalendarSystemIndianNational::weekDayName(int weekDay, WeekDayNameFormat format) const
0437 {
0438     return KCalendarSystem::weekDayName(weekDay, format);
0439 }
0440 
0441 QString KCalendarSystemIndianNational::weekDayName(const QDate &date, WeekDayNameFormat format) const
0442 {
0443     return KCalendarSystem::weekDayName(date, format);
0444 }
0445 
0446 bool KCalendarSystemIndianNational::isLunar() const
0447 {
0448     return false;
0449 }
0450 
0451 bool KCalendarSystemIndianNational::isLunisolar() const
0452 {
0453     return true;
0454 }
0455 
0456 bool KCalendarSystemIndianNational::isSolar() const
0457 {
0458     return false;
0459 }
0460 
0461 bool KCalendarSystemIndianNational::isProleptic() const
0462 {
0463     return false;
0464 }
0465 
0466 bool KCalendarSystemIndianNational::julianDayToDate(qint64 jd, int &year, int &month, int &day) const
0467 {
0468     int L, N, I, J, D, M, Y;
0469 
0470     // "Explanatory Supplement to the Astronomical Almanac" 2006 section 12.94 pp 605-606
0471     // Originally from "Report of the Calendar Reform Committee" 1955
0472     L = jd + 68518;
0473     N = (4 * L) / 146097;
0474     L = L - (146097 * N + 3) / 4;
0475     I = (4000 * (L + 1)) / 1461001;
0476     L = L - (1461 * I) / 4 + 1;
0477     J = ((L - 1) / 31) * (1 - L / 185) + (L / 185) * ((L - 156) / 30 + 5) - L / 366;
0478     D = L - 31 * J + ((J + 2) / 8) * (J - 5);
0479     L = J / 11;
0480     M = J + 2 - 12 * L;
0481     Y = 100 * (N - 49) + L + I - 78;
0482 
0483     day = D;
0484     month = M;
0485     year = Y;
0486 
0487     return true;
0488 }
0489 
0490 bool KCalendarSystemIndianNational::dateToJulianDay(int year, int month, int day, qint64 &jd) const
0491 {
0492     int Y = year;
0493     int M = month;
0494     int D = day;
0495 
0496     // "Explanatory Supplement to the Astronomical Almanac" 2006 section 12.94 pp 605-606
0497     // Originally from "Report of the Calendar Reform Committee" 1955
0498     jd = 365 * Y
0499          + (Y + 78 - 1 / M) / 4
0500          + 31 * M
0501          - (M + 9) / 11
0502          - (M / 7) * (M - 7)
0503          - (3 * ((Y  + 78 - 1 / M) / 100 + 1)) / 4
0504          + D
0505          + 1749579;
0506 
0507     return true;
0508 }