File indexing completed on 2024-03-24 15:27:14

0001 /*
0002     Copyright (c) 2002-2003 Carlos Moro <cfmoro@correo.uniovi.es>
0003     Copyright (c) 2002-2003 Hans Petter Bieker <bieker@kde.org>
0004     Copyright 2007, 2008, 2009, 2010 John Layt <john@layt.net>
0005 
0006     This library is free software; you can redistribute it and/or
0007     modify it under the terms of the GNU Library General Public
0008     License as published by the Free Software Foundation; either
0009     version 2 of the License, or (at your option) any later version.
0010 
0011     This library is distributed in the hope that it will be useful,
0012     but WITHOUT ANY WARRANTY; without even the implied warranty of
0013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014     Library General Public License for more details.
0015 
0016     You should have received a copy of the GNU Library General Public License
0017     along with this library; see the file COPYING.LIB.  If not, write to
0018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019     Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "kcalendarsystemislamiccivil_p.h"
0023 #include "kcalendarsystemprivate_p.h"
0024 
0025 #include <QDate>
0026 
0027 #include <klocalizedstring.h>
0028 
0029 class KCalendarSystemIslamicCivilPrivate : public KCalendarSystemPrivate
0030 {
0031 public:
0032     KDELIBS4SUPPORT_DEPRECATED explicit KCalendarSystemIslamicCivilPrivate(KCalendarSystemIslamicCivil *q);
0033 
0034     ~KCalendarSystemIslamicCivilPrivate() 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 KCalendarSystemIslamicCivilPrivate::KCalendarSystemIslamicCivilPrivate(KCalendarSystemIslamicCivil *q)
0054     : KCalendarSystemPrivate(q)
0055 {
0056 }
0057 
0058 KCalendarSystemIslamicCivilPrivate::~KCalendarSystemIslamicCivilPrivate()
0059 {
0060 }
0061 
0062 void KCalendarSystemIslamicCivilPrivate::loadDefaultEraList()
0063 {
0064     QString name, shortName, format;
0065     // Islamic Era, Anno Hegirae, "Year of the Hijra".
0066     name = i18nc("Calendar Era: Hijri Islamic Era, years > 0, LongFormat", "Anno Hegirae");
0067     shortName = i18nc("Calendar Era: Hijri Islamic Era, years > 0, ShortFormat", "AH");
0068     format = i18nc("(kdedt-format) Hijri, AH, full era year format used for %EY, e.g. 2000 AH", "%Ey %EC");
0069     addEra('+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format);
0070 }
0071 
0072 int KCalendarSystemIslamicCivilPrivate::monthsInYear(int year) const
0073 {
0074     Q_UNUSED(year)
0075     return 12;
0076 }
0077 
0078 int KCalendarSystemIslamicCivilPrivate::daysInMonth(int year, int month) const
0079 {
0080     if (month == 12 && isLeapYear(year)) {
0081         return 30;
0082     }
0083 
0084     if (month % 2 == 0) {   // Even number months have 29 days
0085         return 29;
0086     } else {  // Odd number months have 30 days
0087         return 30;
0088     }
0089 }
0090 
0091 int KCalendarSystemIslamicCivilPrivate::daysInYear(int year) const
0092 {
0093     if (isLeapYear(year)) {
0094         return 355;
0095     } else {
0096         return 354;
0097     }
0098 }
0099 
0100 bool KCalendarSystemIslamicCivilPrivate::isLeapYear(int year) const
0101 {
0102     // Years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29 of the 30 year cycle
0103 
0104     /*
0105     The following C++ code is translated from the Lisp code
0106     in ``Calendrical Calculations'' by Nachum Dershowitz and
0107     Edward M. Reingold, Software---Practice & Experience,
0108     vol. 20, no. 9 (September, 1990), pp. 899--928.
0109 
0110     This code is in the public domain, but any use of it
0111     should publically acknowledge its source.
0112     */
0113 
0114     if ((((11 * year) + 14) % 30) < 11) {
0115         return true;
0116     } else {
0117         return false;
0118     }
0119 
0120     // The following variations will be implemented in separate classes in 4.5
0121     // May be cleaner to formally define using a case statement switch on (year % 30)
0122 
0123     // Variation used by Bar Habraeus / Graves / Birashk / Some Microsoft products
0124     // Years 2, 5, 7, 10, 13, 15, 18, 21, 24, 26, 29 of the 30 year cycle
0125     // if ( ( ( ( 11 * year ) + 15 ) % 30 ) < 11 ) {
0126 
0127     // Variation used by Bohras / Sahifa with epoch 15 July 622 jd = 1948440
0128     // Years 2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29 of the 30 year cycle
0129     // if ( ( ( ( 11 * year ) + 1 ) % 30 ) < 11 ) {
0130 }
0131 
0132 bool KCalendarSystemIslamicCivilPrivate::hasLeapMonths() const
0133 {
0134     return false;
0135 }
0136 
0137 bool KCalendarSystemIslamicCivilPrivate::hasYearZero() const
0138 {
0139     return false;
0140 }
0141 
0142 int KCalendarSystemIslamicCivilPrivate::maxMonthsInYear() const
0143 {
0144     return 12;
0145 }
0146 
0147 int KCalendarSystemIslamicCivilPrivate::earliestValidYear() const
0148 {
0149     return 1;
0150 }
0151 
0152 int KCalendarSystemIslamicCivilPrivate::latestValidYear() const
0153 {
0154     return 9999;
0155 }
0156 
0157 QString KCalendarSystemIslamicCivilPrivate::monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const
0158 {
0159     Q_UNUSED(year);
0160 
0161     QStringList languages = locale()->languageList();
0162 
0163     if (format == KLocale::NarrowName) {
0164         switch (month) {
0165         case 1:
0166             return ki18nc("Hijri month 1 - KLocale::NarrowName",  "M").toString(languages);
0167         case 2:
0168             return ki18nc("Hijri month 2 - KLocale::NarrowName",  "S").toString(languages);
0169         case 3:
0170             return ki18nc("Hijri month 3 - KLocale::NarrowName",  "A").toString(languages);
0171         case 4:
0172             return ki18nc("Hijri month 4 - KLocale::NarrowName",  "T").toString(languages);
0173         case 5:
0174             return ki18nc("Hijri month 5 - KLocale::NarrowName",  "A").toString(languages);
0175         case 6:
0176             return ki18nc("Hijri month 6 - KLocale::NarrowName",  "T").toString(languages);
0177         case 7:
0178             return ki18nc("Hijri month 7 - KLocale::NarrowName",  "R").toString(languages);
0179         case 8:
0180             return ki18nc("Hijri month 8 - KLocale::NarrowName",  "S").toString(languages);
0181         case 9:
0182             return ki18nc("Hijri month 9 - KLocale::NarrowName",  "R").toString(languages);
0183         case 10:
0184             return ki18nc("Hijri month 10 - KLocale::NarrowName", "S").toString(languages);
0185         case 11:
0186             return ki18nc("Hijri month 11 - KLocale::NarrowName", "Q").toString(languages);
0187         case 12:
0188             return ki18nc("Hijri month 12 - KLocale::NarrowName", "H").toString(languages);
0189         default:
0190             return QString();
0191         }
0192     }
0193 
0194     if (format == KLocale::ShortName && possessive) {
0195         switch (month) {
0196         case 1:
0197             return ki18nc("Hijri month 1 - KLocale::ShortName Possessive",  "of Muh").toString(languages);
0198         case 2:
0199             return ki18nc("Hijri month 2 - KLocale::ShortName Possessive",  "of Saf").toString(languages);
0200         case 3:
0201             return ki18nc("Hijri month 3 - KLocale::ShortName Possessive",  "of R.A").toString(languages);
0202         case 4:
0203             return ki18nc("Hijri month 4 - KLocale::ShortName Possessive",  "of R.T").toString(languages);
0204         case 5:
0205             return ki18nc("Hijri month 5 - KLocale::ShortName Possessive",  "of J.A").toString(languages);
0206         case 6:
0207             return ki18nc("Hijri month 6 - KLocale::ShortName Possessive",  "of J.T").toString(languages);
0208         case 7:
0209             return ki18nc("Hijri month 7 - KLocale::ShortName Possessive",  "of Raj").toString(languages);
0210         case 8:
0211             return ki18nc("Hijri month 8 - KLocale::ShortName Possessive",  "of Sha").toString(languages);
0212         case 9:
0213             return ki18nc("Hijri month 9 - KLocale::ShortName Possessive",  "of Ram").toString(languages);
0214         case 10:
0215             return ki18nc("Hijri month 10 - KLocale::ShortName Possessive", "of Shw").toString(languages);
0216         case 11:
0217             return ki18nc("Hijri month 11 - KLocale::ShortName Possessive", "of Qid").toString(languages);
0218         case 12:
0219             return ki18nc("Hijri month 12 - KLocale::ShortName Possessive", "of Hij").toString(languages);
0220         default:
0221             return QString();
0222         }
0223     }
0224 
0225     if (format == KLocale::ShortName && !possessive) {
0226         switch (month) {
0227         case 1:
0228             return ki18nc("Hijri month 1 - KLocale::ShortName",  "Muh").toString(languages);
0229         case 2:
0230             return ki18nc("Hijri month 2 - KLocale::ShortName",  "Saf").toString(languages);
0231         case 3:
0232             return ki18nc("Hijri month 3 - KLocale::ShortName",  "R.A").toString(languages);
0233         case 4:
0234             return ki18nc("Hijri month 4 - KLocale::ShortName",  "R.T").toString(languages);
0235         case 5:
0236             return ki18nc("Hijri month 5 - KLocale::ShortName",  "J.A").toString(languages);
0237         case 6:
0238             return ki18nc("Hijri month 6 - KLocale::ShortName",  "J.T").toString(languages);
0239         case 7:
0240             return ki18nc("Hijri month 7 - KLocale::ShortName",  "Raj").toString(languages);
0241         case 8:
0242             return ki18nc("Hijri month 8 - KLocale::ShortName",  "Sha").toString(languages);
0243         case 9:
0244             return ki18nc("Hijri month 9 - KLocale::ShortName",  "Ram").toString(languages);
0245         case 10:
0246             return ki18nc("Hijri month 10 - KLocale::ShortName", "Shw").toString(languages);
0247         case 11:
0248             return ki18nc("Hijri month 11 - KLocale::ShortName", "Qid").toString(languages);
0249         case 12:
0250             return ki18nc("Hijri month 12 - KLocale::ShortName", "Hij").toString(languages);
0251         default:
0252             return QString();
0253         }
0254     }
0255 
0256     if (format == KLocale::LongName && possessive) {
0257         switch (month) {
0258         case 1:
0259             return ki18nc("Hijri month 1 - KLocale::LongName Possessive",  "of Muharram").toString(languages);
0260         case 2:
0261             return ki18nc("Hijri month 2 - KLocale::LongName Possessive",  "of Safar").toString(languages);
0262         case 3:
0263             return ki18nc("Hijri month 3 - KLocale::LongName Possessive",  "of Rabi` al-Awal").toString(languages);
0264         case 4:
0265             return ki18nc("Hijri month 4 - KLocale::LongName Possessive",  "of Rabi` al-Thaani").toString(languages);
0266         case 5:
0267             return ki18nc("Hijri month 5 - KLocale::LongName Possessive",  "of Jumaada al-Awal").toString(languages);
0268         case 6:
0269             return ki18nc("Hijri month 6 - KLocale::LongName Possessive",  "of Jumaada al-Thaani").toString(languages);
0270         case 7:
0271             return ki18nc("Hijri month 7 - KLocale::LongName Possessive",  "of Rajab").toString(languages);
0272         case 8:
0273             return ki18nc("Hijri month 8 - KLocale::LongName Possessive",  "of Sha`ban").toString(languages);
0274         case 9:
0275             return ki18nc("Hijri month 9 - KLocale::LongName Possessive",  "of Ramadan").toString(languages);
0276         case 10:
0277             return ki18nc("Hijri month 10 - KLocale::LongName Possessive", "of Shawwal").toString(languages);
0278         case 11:
0279             return ki18nc("Hijri month 11 - KLocale::LongName Possessive", "of Thu al-Qi`dah").toString(languages);
0280         case 12:
0281             return ki18nc("Hijri month 12 - KLocale::LongName Possessive", "of Thu al-Hijjah").toString(languages);
0282         default:
0283             return QString();
0284         }
0285     }
0286 
0287     // Default to LongName
0288     switch (month) {
0289     case 1:
0290         return ki18nc("Hijri month 1 - KLocale::LongName",  "Muharram").toString(languages);
0291     case 2:
0292         return ki18nc("Hijri month 2 - KLocale::LongName",  "Safar").toString(languages);
0293     case 3:
0294         return ki18nc("Hijri month 3 - KLocale::LongName",  "Rabi` al-Awal").toString(languages);
0295     case 4:
0296         return ki18nc("Hijri month 4 - KLocale::LongName",  "Rabi` al-Thaani").toString(languages);
0297     case 5:
0298         return ki18nc("Hijri month 5 - KLocale::LongName",  "Jumaada al-Awal").toString(languages);
0299     case 6:
0300         return ki18nc("Hijri month 6 - KLocale::LongName",  "Jumaada al-Thaani").toString(languages);
0301     case 7:
0302         return ki18nc("Hijri month 7 - KLocale::LongName",  "Rajab").toString(languages);
0303     case 8:
0304         return ki18nc("Hijri month 8 - KLocale::LongName",  "Sha`ban").toString(languages);
0305     case 9:
0306         return ki18nc("Hijri month 9 - KLocale::LongName",  "Ramadan").toString(languages);
0307     case 10:
0308         return ki18nc("Hijri month 10 - KLocale::LongName", "Shawwal").toString(languages);
0309     case 11:
0310         return ki18nc("Hijri month 11 - KLocale::LongName", "Thu al-Qi`dah").toString(languages);
0311     case 12:
0312         return ki18nc("Hijri month 12 - KLocale::LongName", "Thu al-Hijjah").toString(languages);
0313     default:
0314         return QString();
0315     }
0316 }
0317 
0318 QString KCalendarSystemIslamicCivilPrivate::weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const
0319 {
0320     QStringList languages = locale()->languageList();
0321 
0322     if (format == KLocale::NarrowName) {
0323         switch (weekDay) {
0324         case 1:
0325             return ki18nc("Hijri weekday 1 - KLocale::NarrowName ", "I").toString(languages);
0326         case 2:
0327             return ki18nc("Hijri weekday 2 - KLocale::NarrowName ", "T").toString(languages);
0328         case 3:
0329             return ki18nc("Hijri weekday 3 - KLocale::NarrowName ", "A").toString(languages);
0330         case 4:
0331             return ki18nc("Hijri weekday 4 - KLocale::NarrowName ", "K").toString(languages);
0332         case 5:
0333             return ki18nc("Hijri weekday 5 - KLocale::NarrowName ", "J").toString(languages);
0334         case 6:
0335             return ki18nc("Hijri weekday 6 - KLocale::NarrowName ", "S").toString(languages);
0336         case 7:
0337             return ki18nc("Hijri weekday 7 - KLocale::NarrowName ", "A").toString(languages);
0338         default:
0339             return QString();
0340         }
0341     }
0342 
0343     if (format == KLocale::ShortName  || format == KLocale:: ShortNumber) {
0344         switch (weekDay) {
0345         case 1:
0346             return ki18nc("Hijri weekday 1 - KLocale::ShortName", "Ith").toString(languages);
0347         case 2:
0348             return ki18nc("Hijri weekday 2 - KLocale::ShortName", "Thl").toString(languages);
0349         case 3:
0350             return ki18nc("Hijri weekday 3 - KLocale::ShortName", "Arb").toString(languages);
0351         case 4:
0352             return ki18nc("Hijri weekday 4 - KLocale::ShortName", "Kha").toString(languages);
0353         case 5:
0354             return ki18nc("Hijri weekday 5 - KLocale::ShortName", "Jum").toString(languages);
0355         case 6:
0356             return ki18nc("Hijri weekday 6 - KLocale::ShortName", "Sab").toString(languages);
0357         case 7:
0358             return ki18nc("Hijri weekday 7 - KLocale::ShortName", "Ahd").toString(languages);
0359         default: return QString();
0360         }
0361     }
0362 
0363     switch (weekDay) {
0364     case 1:
0365         return ki18nc("Hijri weekday 1 - KLocale::LongName", "Yaum al-Ithnain").toString(languages);
0366     case 2:
0367         return ki18nc("Hijri weekday 2 - KLocale::LongName", "Yau al-Thulatha").toString(languages);
0368     case 3:
0369         return ki18nc("Hijri weekday 3 - KLocale::LongName", "Yaum al-Arbi'a").toString(languages);
0370     case 4:
0371         return ki18nc("Hijri weekday 4 - KLocale::LongName", "Yaum al-Khamees").toString(languages);
0372     case 5:
0373         return ki18nc("Hijri weekday 5 - KLocale::LongName", "Yaum al-Jumma").toString(languages);
0374     case 6:
0375         return ki18nc("Hijri weekday 6 - KLocale::LongName", "Yaum al-Sabt").toString(languages);
0376     case 7:
0377         return ki18nc("Hijri weekday 7 - KLocale::LongName", "Yaum al-Ahad").toString(languages);
0378     default:
0379         return QString();
0380     }
0381 }
0382 
0383 KCalendarSystemIslamicCivil::KCalendarSystemIslamicCivil(const KSharedConfig::Ptr config, const KLocale *locale)
0384     : KCalendarSystem(*new KCalendarSystemIslamicCivilPrivate(this), config, locale)
0385 {
0386     d_ptr->loadConfig(calendarType());
0387 }
0388 
0389 KCalendarSystemIslamicCivil::KCalendarSystemIslamicCivil(KCalendarSystemIslamicCivilPrivate &dd,
0390         const KSharedConfig::Ptr config, const KLocale *locale)
0391     : KCalendarSystem(dd, config, locale)
0392 {
0393     d_ptr->loadConfig(calendarType());
0394 }
0395 
0396 KCalendarSystemIslamicCivil::~KCalendarSystemIslamicCivil()
0397 {
0398 }
0399 
0400 QString KCalendarSystemIslamicCivil::calendarType() const
0401 {
0402     return QLatin1String("hijri");
0403 }
0404 
0405 KLocale::CalendarSystem KCalendarSystemIslamicCivil::calendarSystem() const
0406 {
0407     return KLocale::IslamicCivilCalendar;
0408 }
0409 
0410 QDate KCalendarSystemIslamicCivil::epoch() const
0411 {
0412     // 16 July 622 in the Julian calendar
0413     return QDate::fromJulianDay(1948440);
0414 }
0415 
0416 QDate KCalendarSystemIslamicCivil::earliestValidDate() const
0417 {
0418     return epoch();
0419 }
0420 
0421 QDate KCalendarSystemIslamicCivil::latestValidDate() const
0422 {
0423     // Set to last day of year 9999
0424     // Last day of Islamic Civil year 9999 is 9999-12-29
0425     return QDate::fromJulianDay(5491751);
0426 }
0427 
0428 QString KCalendarSystemIslamicCivil::monthName(int month, int year, MonthNameFormat format) const
0429 {
0430     return KCalendarSystem::monthName(month, year, format);
0431 }
0432 
0433 QString KCalendarSystemIslamicCivil::monthName(const QDate &date, MonthNameFormat format) const
0434 {
0435     return KCalendarSystem::monthName(date, format);
0436 }
0437 
0438 QString KCalendarSystemIslamicCivil::weekDayName(int weekDay, WeekDayNameFormat format) const
0439 {
0440     return KCalendarSystem::weekDayName(weekDay, format);
0441 }
0442 
0443 QString KCalendarSystemIslamicCivil::weekDayName(const QDate &date, WeekDayNameFormat format) const
0444 {
0445     return KCalendarSystem::weekDayName(date, format);
0446 }
0447 
0448 bool KCalendarSystemIslamicCivil::isLunar() const
0449 {
0450     return true;
0451 }
0452 
0453 bool KCalendarSystemIslamicCivil::isLunisolar() const
0454 {
0455     return false;
0456 }
0457 
0458 bool KCalendarSystemIslamicCivil::isSolar() const
0459 {
0460     return false;
0461 }
0462 
0463 bool KCalendarSystemIslamicCivil::isProleptic() const
0464 {
0465     return false;
0466 }
0467 
0468 bool KCalendarSystemIslamicCivil::julianDayToDate(qint64 jd, int &year, int &month, int &day) const
0469 {
0470     Q_D(const KCalendarSystemIslamicCivil);
0471 
0472     /*
0473     The following C++ code is translated from the Lisp code
0474     in ``Calendrical Calculations'' by Nachum Dershowitz and
0475     Edward M. Reingold, Software---Practice & Experience,
0476     vol. 20, no. 9 (September, 1990), pp. 899--928.
0477 
0478     This code is in the public domain, but any use of it
0479     should publically acknowledge its source.
0480     */
0481 
0482     // Search forward year by year from approximate year
0483     year = (jd - epoch().toJulianDay()) / 355;
0484     qint64 testJd;
0485     dateToJulianDay(year, 12, d->daysInMonth(year, 12), testJd);
0486     while (jd > testJd) {
0487         year++;
0488         dateToJulianDay(year, 12, d->daysInMonth(year, 12), testJd);
0489     }
0490 
0491     // Search forward month by month from Muharram
0492     month = 1;
0493     dateToJulianDay(year, month, d->daysInMonth(year, month), testJd);
0494     while (jd > testJd) {
0495         month++;
0496         dateToJulianDay(year, month, d->daysInMonth(year, month), testJd);
0497     }
0498 
0499     dateToJulianDay(year, month, 1, testJd);
0500     day = jd - testJd + 1;
0501 
0502     return true;
0503 
0504     // Alternative implementations
0505 
0506     // More recent editions of "Calendrical Calculations" by Dershowitz & Reingold have a more
0507     // efficient direct calculation without recusrion, but this cannot be used due to licensing
0508 
0509     /*
0510     Formula from "Explanatory Supplement to the Astronomical Almanac" 2006, derived from Fliegel & Van Flandern 1968
0511     int L = jd - epoch().toJulianDay() + 10632;
0512     int N = ( L - 1 ) / 10631;
0513     L = L - 10631 * N + 354;
0514     int J = ( ( 10985 - L ) / 5316 ) x ( ( 50* L ) / 17719 ) + ( L / 5670 ) * ( ( 43 * L ) / 15238 );
0515     L = L - ( ( 30 - J ) / 15 ) * ( ( 17719 * J ) / 50 ) - ( J / 16 ) * ( ( 15238 * J ) / 43 ) + 29;
0516     year = ( 30 * N ) + J - 30;
0517     month = ( 24 * L ) / 709;
0518     day = L - ( ( 709 * month ) / 24 );
0519     */
0520 
0521     /*
0522     Formula from Fourmilab website
0523     jd = Math.floor(jd) + 0.5;
0524     year = Math.floor(((30 * (jd - epoch().toJulianDay())) + 10646) / 10631);
0525     month = qMin(12, Math.ceil((jd - (29 + islamic_to_jd(year, 1, 1))) / 29.5) + 1);
0526     day = (jd - islamic_to_jd(year, month, 1)) + 1;
0527     */
0528 }
0529 
0530 bool KCalendarSystemIslamicCivil::dateToJulianDay(int year, int month, int day, qint64 &jd) const
0531 {
0532     /*
0533     The following C++ code is translated from the Lisp code
0534     in ``Calendrical Calculations'' by Nachum Dershowitz and
0535     Edward M. Reingold, Software---Practice & Experience,
0536     vol. 20, no. 9 (September, 1990), pp. 899--928.
0537 
0538     This code is in the public domain, but any use of it
0539     should publically acknowledge its source.
0540     */
0541 
0542     jd = epoch().toJulianDay() - 1 +   // days before start of calendar
0543          (year - 1) * 354 +            // non-leap days in prior years
0544          (3 + (11 * year)) / 30 +      // leap days in prior years
0545          29 * (month - 1) +            // days so far...
0546          month / 2          +          //            ...this year
0547          day;                          // days so far this month
0548 
0549     return true;
0550 
0551     // Alternative implementations
0552 
0553     /*
0554     Formula from "Explanatory Supplement to the Astronomical Almanac" 2006, derived from Fliegel & Van Flandern 1968
0555     jd = ( 3 + ( 11 * year ) ) / 30 + 354 * year + 30 * month - ( month - 1 ) / 2 + day + epoch().toJulianDay() - 385;
0556     */
0557 }