File indexing completed on 2023-09-24 04:04:44
0001 /* 0002 Copyright (C) 2002-2003 Arash Bijanzadeh and FarsiKDE Project <www.farsikde.org> 0003 Contact: Arash Bijanzadeh <a.bijanzadeh@linuxiran.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 /* 0023 This is an implementation of the artithmetic Persian calendar using the 0024 Birashk algorithm with adjustments to always be correct in the period 1244 0025 and 1530 (1865 to 2152 Gregorian). 0026 0027 In future this will be replaced with the correct astronomical calendar. 0028 */ 0029 0030 #include "kcalendarsystemjalali_p.h" 0031 #include "kcalendarsystemprivate_p.h" 0032 0033 #include <QDate> 0034 0035 #include <klocalizedstring.h> 0036 0037 class KCalendarSystemJalaliPrivate : public KCalendarSystemPrivate 0038 { 0039 public: 0040 KDELIBS4SUPPORT_DEPRECATED explicit KCalendarSystemJalaliPrivate(KCalendarSystemJalali *q); 0041 0042 ~KCalendarSystemJalaliPrivate() override; 0043 0044 // Virtual methods each calendar system must re-implement 0045 void loadDefaultEraList() override; 0046 int monthsInYear(int year) const override; 0047 int daysInMonth(int year, int month) const override; 0048 int daysInYear(int year) const override; 0049 bool isLeapYear(int year) const override; 0050 bool hasLeapMonths() const override; 0051 bool hasYearZero() const override; 0052 int maxMonthsInYear() const override; 0053 int earliestValidYear() const override; 0054 int latestValidYear() const override; 0055 QString monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const override; 0056 QString weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const override; 0057 }; 0058 0059 // Shared d pointer base class definitions 0060 0061 KCalendarSystemJalaliPrivate::KCalendarSystemJalaliPrivate(KCalendarSystemJalali *q) 0062 : KCalendarSystemPrivate(q) 0063 { 0064 } 0065 0066 KCalendarSystemJalaliPrivate::~KCalendarSystemJalaliPrivate() 0067 { 0068 } 0069 0070 void KCalendarSystemJalaliPrivate::loadDefaultEraList() 0071 { 0072 QString name, shortName, format; 0073 // Islamic Era (Hijri), Anno Persico. 0074 name = i18nc("Calendar Era: Jalali Islamic Era, years > 0, LongFormat", "Anno Persico"); 0075 shortName = i18nc("Calendar Era: Jalali Islamic Era, years > 0, ShortFormat", "AP"); 0076 format = i18nc("(kdedt-format) Jalali, AP, full era year format used for %EY, e.g. 2000 AP", "%Ey %EC"); 0077 addEra('+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format); 0078 } 0079 0080 int KCalendarSystemJalaliPrivate::monthsInYear(int year) const 0081 { 0082 Q_UNUSED(year) 0083 return 12; 0084 } 0085 0086 int KCalendarSystemJalaliPrivate::daysInMonth(int year, int month) const 0087 { 0088 if (month == 12) { 0089 if (isLeapYear(year)) { 0090 return 30; 0091 } else { 0092 return 29; 0093 } 0094 } 0095 0096 if (month <= 6) { 0097 return 31; 0098 } 0099 0100 return 30; 0101 } 0102 0103 int KCalendarSystemJalaliPrivate::daysInYear(int year) const 0104 { 0105 if (isLeapYear(year)) { 0106 return 366; 0107 } else { 0108 return 365; 0109 } 0110 } 0111 0112 bool KCalendarSystemJalaliPrivate::isLeapYear(int year) const 0113 { 0114 // From formilab Public Domain code http://www.fourmilab.ch/documents/calendar/ 0115 // Use Birashk algorithm as it matches the to/from jd code below 0116 0117 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531, 0118 // 1403/1404 and 1436/1437, and so catch them here first 0119 if (year == 1403 || year == 1436) { 0120 return true; 0121 } else if (year == 1404 || year == 1437) { 0122 return false; 0123 } 0124 0125 if (year >= 0) { 0126 year = year - 474; 0127 } else { 0128 year = year - 473; 0129 } 0130 0131 if ((((((year % 2820) + 474) + 38) * 682) % 2816) < 682) { 0132 return true; 0133 } else { 0134 return false; 0135 } 0136 } 0137 0138 bool KCalendarSystemJalaliPrivate::hasLeapMonths() const 0139 { 0140 return false; 0141 } 0142 0143 bool KCalendarSystemJalaliPrivate::hasYearZero() const 0144 { 0145 return false; 0146 } 0147 0148 int KCalendarSystemJalaliPrivate::maxMonthsInYear() const 0149 { 0150 return 12; 0151 } 0152 0153 int KCalendarSystemJalaliPrivate::earliestValidYear() const 0154 { 0155 return 1244; 0156 } 0157 0158 int KCalendarSystemJalaliPrivate::latestValidYear() const 0159 { 0160 return 1530; 0161 } 0162 0163 QString KCalendarSystemJalaliPrivate::monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const 0164 { 0165 Q_UNUSED(year); 0166 0167 QStringList languages = locale()->languageList(); 0168 0169 if (format == KLocale::NarrowName) { 0170 switch (month) { 0171 case 1: 0172 return ki18nc("Jalali month 1 - KLocale::NarrowName", "F").toString(languages); 0173 case 2: 0174 return ki18nc("Jalali month 2 - KLocale::NarrowName", "O").toString(languages); 0175 case 3: 0176 return ki18nc("Jalali month 3 - KLocale::NarrowName", "K").toString(languages); 0177 case 4: 0178 return ki18nc("Jalali month 4 - KLocale::NarrowName", "T").toString(languages); 0179 case 5: 0180 return ki18nc("Jalali month 5 - KLocale::NarrowName", "M").toString(languages); 0181 case 6: 0182 return ki18nc("Jalali month 6 - KLocale::NarrowName", "S").toString(languages); 0183 case 7: 0184 return ki18nc("Jalali month 7 - KLocale::NarrowName", "M").toString(languages); 0185 case 8: 0186 return ki18nc("Jalali month 8 - KLocale::NarrowName", "A").toString(languages); 0187 case 9: 0188 return ki18nc("Jalali month 9 - KLocale::NarrowName", "A").toString(languages); 0189 case 10: 0190 return ki18nc("Jalali month 10 - KLocale::NarrowName", "D").toString(languages); 0191 case 11: 0192 return ki18nc("Jalali month 11 - KLocale::NarrowName", "B").toString(languages); 0193 case 12: 0194 return ki18nc("Jalali month 12 - KLocale::NarrowName", "E").toString(languages); 0195 default: 0196 return QString(); 0197 } 0198 } 0199 0200 if (format == KLocale::ShortName && possessive) { 0201 switch (month) { 0202 case 1: 0203 return ki18nc("Jalali month 1 - KLocale::ShortName Possessive", "of Far").toString(languages); 0204 case 2: 0205 return ki18nc("Jalali month 2 - KLocale::ShortName Possessive", "of Ord").toString(languages); 0206 case 3: 0207 return ki18nc("Jalali month 3 - KLocale::ShortName Possessive", "of Kho").toString(languages); 0208 case 4: 0209 return ki18nc("Jalali month 4 - KLocale::ShortName Possessive", "of Tir").toString(languages); 0210 case 5: 0211 return ki18nc("Jalali month 5 - KLocale::ShortName Possessive", "of Mor").toString(languages); 0212 case 6: 0213 return ki18nc("Jalali month 6 - KLocale::ShortName Possessive", "of Sha").toString(languages); 0214 case 7: 0215 return ki18nc("Jalali month 7 - KLocale::ShortName Possessive", "of Meh").toString(languages); 0216 case 8: 0217 return ki18nc("Jalali month 8 - KLocale::ShortName Possessive", "of Aba").toString(languages); 0218 case 9: 0219 return ki18nc("Jalali month 9 - KLocale::ShortName Possessive", "of Aza").toString(languages); 0220 case 10: 0221 return ki18nc("Jalali month 10 - KLocale::ShortName Possessive", "of Dei").toString(languages); 0222 case 11: 0223 return ki18nc("Jalali month 11 - KLocale::ShortName Possessive", "of Bah").toString(languages); 0224 case 12: 0225 return ki18nc("Jalali month 12 - KLocale::ShortName Possessive", "of Esf").toString(languages); 0226 default: 0227 return QString(); 0228 } 0229 } 0230 0231 if (format == KLocale::ShortName && !possessive) { 0232 switch (month) { 0233 case 1: 0234 return ki18nc("Jalali month 1 - KLocale::ShortName", "Far").toString(languages); 0235 case 2: 0236 return ki18nc("Jalali month 2 - KLocale::ShortName", "Ord").toString(languages); 0237 case 3: 0238 return ki18nc("Jalali month 3 - KLocale::ShortName", "Kho").toString(languages); 0239 case 4: 0240 return ki18nc("Jalali month 4 - KLocale::ShortName", "Tir").toString(languages); 0241 case 5: 0242 return ki18nc("Jalali month 5 - KLocale::ShortName", "Mor").toString(languages); 0243 case 6: 0244 return ki18nc("Jalali month 6 - KLocale::ShortName", "Sha").toString(languages); 0245 case 7: 0246 return ki18nc("Jalali month 7 - KLocale::ShortName", "Meh").toString(languages); 0247 case 8: 0248 return ki18nc("Jalali month 8 - KLocale::ShortName", "Aba").toString(languages); 0249 case 9: 0250 return ki18nc("Jalali month 9 - KLocale::ShortName", "Aza").toString(languages); 0251 case 10: 0252 return ki18nc("Jalali month 10 - KLocale::ShortName", "Dei").toString(languages); 0253 case 11: 0254 return ki18nc("Jalali month 11 - KLocale::ShortName", "Bah").toString(languages); 0255 case 12: 0256 return ki18nc("Jalali month 12 - KLocale::ShortName", "Esf").toString(languages); 0257 default: 0258 return QString(); 0259 } 0260 } 0261 0262 if (format == KLocale::LongName && possessive) { 0263 switch (month) { 0264 case 1: 0265 return ki18nc("Jalali month 1 - KLocale::LongName Possessive", "of Farvardin").toString(languages); 0266 case 2: 0267 return ki18nc("Jalali month 2 - KLocale::LongName Possessive", "of Ordibehesht").toString(languages); 0268 case 3: 0269 return ki18nc("Jalali month 3 - KLocale::LongName Possessive", "of Khordad").toString(languages); 0270 case 4: 0271 return ki18nc("Jalali month 4 - KLocale::LongName Possessive", "of Tir").toString(languages); 0272 case 5: 0273 return ki18nc("Jalali month 5 - KLocale::LongName Possessive", "of Mordad").toString(languages); 0274 case 6: 0275 return ki18nc("Jalali month 6 - KLocale::LongName Possessive", "of Shahrivar").toString(languages); 0276 case 7: 0277 return ki18nc("Jalali month 7 - KLocale::LongName Possessive", "of Mehr").toString(languages); 0278 case 8: 0279 return ki18nc("Jalali month 8 - KLocale::LongName Possessive", "of Aban").toString(languages); 0280 case 9: 0281 return ki18nc("Jalali month 9 - KLocale::LongName Possessive", "of Azar").toString(languages); 0282 case 10: 0283 return ki18nc("Jalali month 10 - KLocale::LongName Possessive", "of Dei").toString(languages); 0284 case 11: 0285 return ki18nc("Jalali month 11 - KLocale::LongName Possessive", "of Bahman").toString(languages); 0286 case 12: 0287 return ki18nc("Jalali month 12 - KLocale::LongName Possessive", "of Esfand").toString(languages); 0288 default: 0289 return QString(); 0290 } 0291 } 0292 0293 // Default to LongName 0294 switch (month) { 0295 case 1: 0296 return ki18nc("Jalali month 1 - KLocale::LongName", "Farvardin").toString(languages); 0297 case 2: 0298 return ki18nc("Jalali month 2 - KLocale::LongName", "Ordibehesht").toString(languages); 0299 case 3: 0300 return ki18nc("Jalali month 3 - KLocale::LongName", "Khordad").toString(languages); 0301 case 4: 0302 return ki18nc("Jalali month 4 - KLocale::LongName", "Tir").toString(languages); 0303 case 5: 0304 return ki18nc("Jalali month 5 - KLocale::LongName", "Mordad").toString(languages); 0305 case 6: 0306 return ki18nc("Jalali month 6 - KLocale::LongName", "Shahrivar").toString(languages); 0307 case 7: 0308 return ki18nc("Jalali month 7 - KLocale::LongName", "Mehr").toString(languages); 0309 case 8: 0310 return ki18nc("Jalali month 8 - KLocale::LongName", "Aban").toString(languages); 0311 case 9: 0312 return ki18nc("Jalali month 9 - KLocale::LongName", "Azar").toString(languages); 0313 case 10: 0314 return ki18nc("Jalali month 10 - KLocale::LongName", "Dei").toString(languages); 0315 case 11: 0316 return ki18nc("Jalali month 11 - KLocale::LongName", "Bahman").toString(languages); 0317 case 12: 0318 return ki18nc("Jalali month 12 - KLocale::LongName", "Esfand").toString(languages); 0319 default: 0320 return QString(); 0321 } 0322 } 0323 0324 QString KCalendarSystemJalaliPrivate::weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const 0325 { 0326 QStringList languages = locale()->languageList(); 0327 0328 if (format == KLocale::NarrowName) { 0329 switch (weekDay) { 0330 case 1: 0331 return ki18nc("Jalali weekday 1 - KLocale::NarrowName ", "2").toString(languages); 0332 case 2: 0333 return ki18nc("Jalali weekday 2 - KLocale::NarrowName ", "3").toString(languages); 0334 case 3: 0335 return ki18nc("Jalali weekday 3 - KLocale::NarrowName ", "4").toString(languages); 0336 case 4: 0337 return ki18nc("Jalali weekday 4 - KLocale::NarrowName ", "5").toString(languages); 0338 case 5: 0339 return ki18nc("Jalali weekday 5 - KLocale::NarrowName ", "J").toString(languages); 0340 case 6: 0341 return ki18nc("Jalali weekday 6 - KLocale::NarrowName ", "S").toString(languages); 0342 case 7: 0343 return ki18nc("Jalali weekday 7 - KLocale::NarrowName ", "1").toString(languages); 0344 default: 0345 return QString(); 0346 } 0347 } 0348 0349 if (format == KLocale::ShortName || format == KLocale:: ShortNumber) { 0350 switch (weekDay) { 0351 case 1: 0352 return ki18nc("Jalali weekday 1 - KLocale::ShortName", "2sh").toString(languages); 0353 case 2: 0354 return ki18nc("Jalali weekday 2 - KLocale::ShortName", "3sh").toString(languages); 0355 case 3: 0356 return ki18nc("Jalali weekday 3 - KLocale::ShortName", "4sh").toString(languages); 0357 case 4: 0358 return ki18nc("Jalali weekday 4 - KLocale::ShortName", "5sh").toString(languages); 0359 case 5: 0360 return ki18nc("Jalali weekday 5 - KLocale::ShortName", "Jom").toString(languages); 0361 case 6: 0362 return ki18nc("Jalali weekday 6 - KLocale::ShortName", "Shn").toString(languages); 0363 case 7: 0364 return ki18nc("Jalali weekday 7 - KLocale::ShortName", "1sh").toString(languages); 0365 default: return QString(); 0366 } 0367 } 0368 0369 switch (weekDay) { 0370 case 1: 0371 return ki18nc("Jalali weekday 1 - KLocale::LongName", "Do shanbe").toString(languages); 0372 case 2: 0373 return ki18nc("Jalali weekday 2 - KLocale::LongName", "Se shanbe").toString(languages); 0374 case 3: 0375 return ki18nc("Jalali weekday 3 - KLocale::LongName", "Chahar shanbe").toString(languages); 0376 case 4: 0377 return ki18nc("Jalali weekday 4 - KLocale::LongName", "Panj shanbe").toString(languages); 0378 case 5: 0379 return ki18nc("Jalali weekday 5 - KLocale::LongName", "Jumee").toString(languages); 0380 case 6: 0381 return ki18nc("Jalali weekday 6 - KLocale::LongName", "Shanbe").toString(languages); 0382 case 7: 0383 return ki18nc("Jalali weekday 7 - KLocale::LongName", "Yek-shanbe").toString(languages); 0384 default: 0385 return QString(); 0386 } 0387 } 0388 0389 KCalendarSystemJalali::KCalendarSystemJalali(const KSharedConfig::Ptr config, const KLocale *locale) 0390 : KCalendarSystem(*new KCalendarSystemJalaliPrivate(this), config, locale) 0391 { 0392 d_ptr->loadConfig(calendarType()); 0393 } 0394 0395 KCalendarSystemJalali::KCalendarSystemJalali(KCalendarSystemJalaliPrivate &dd, 0396 const KSharedConfig::Ptr config, const KLocale *locale) 0397 : KCalendarSystem(dd, config, locale) 0398 { 0399 d_ptr->loadConfig(calendarType()); 0400 } 0401 0402 KCalendarSystemJalali::~KCalendarSystemJalali() 0403 { 0404 } 0405 0406 QString KCalendarSystemJalali::calendarType() const 0407 { 0408 return QLatin1String("jalali"); 0409 } 0410 0411 KLocale::CalendarSystem KCalendarSystemJalali::calendarSystem() const 0412 { 0413 return KLocale::JalaliCalendar; 0414 } 0415 0416 QDate KCalendarSystemJalali::epoch() const 0417 { 0418 // 19 March 622 in the Julian calendar 0419 return QDate::fromJulianDay(1948321); 0420 } 0421 0422 QDate KCalendarSystemJalali::earliestValidDate() const 0423 { 0424 // Using the Birashk formula which is accurate in period AP 1244 to 1530 (AD 1865 to 2152) 0425 // 1244-01-01 Jalali 1865-03-21 Gregorian 0426 return QDate::fromJulianDay(2402317); 0427 } 0428 0429 QDate KCalendarSystemJalali::latestValidDate() const 0430 { 0431 // Using the Birashk formula which is accurate in period AP 1244 to 1530 (AD 1865 to 2152) 0432 // 1530-12-29 Jalali 2152-03-19 Gregorian 0433 return QDate::fromJulianDay(2507140); 0434 } 0435 0436 QString KCalendarSystemJalali::monthName(int month, int year, MonthNameFormat format) const 0437 { 0438 return KCalendarSystem::monthName(month, year, format); 0439 } 0440 0441 QString KCalendarSystemJalali::monthName(const QDate &date, MonthNameFormat format) const 0442 { 0443 return KCalendarSystem::monthName(date, format); 0444 } 0445 0446 QString KCalendarSystemJalali::weekDayName(int weekDay, WeekDayNameFormat format) const 0447 { 0448 return KCalendarSystem::weekDayName(weekDay, format); 0449 } 0450 0451 QString KCalendarSystemJalali::weekDayName(const QDate &date, WeekDayNameFormat format) const 0452 { 0453 return KCalendarSystem::weekDayName(date, format); 0454 } 0455 0456 bool KCalendarSystemJalali::isLunar() const 0457 { 0458 return false; 0459 } 0460 0461 bool KCalendarSystemJalali::isLunisolar() const 0462 { 0463 return false; 0464 } 0465 0466 bool KCalendarSystemJalali::isSolar() const 0467 { 0468 return true; 0469 } 0470 0471 bool KCalendarSystemJalali::isProleptic() const 0472 { 0473 return false; 0474 } 0475 0476 bool KCalendarSystemJalali::julianDayToDate(qint64 jd, int &year, int &month, int &day) const 0477 { 0478 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531. 0479 // This results in a leap day being added to the end of 1404 instead of 1403 0480 // and to the end of 1437 instead of 1436. Check for these dates first and 0481 // return accordingly. Relies on later use of dateToJulianDay() to correctly 0482 // calculate firstDayOfYear in 1404 and 1437, so no other adjustments needed. 0483 if (jd == 2460755) { 0484 year = 1403; 0485 month = 12; 0486 day = 30; 0487 return true; 0488 } 0489 if (jd == 2472808) { 0490 year = 1436; 0491 month = 12; 0492 day = 30; 0493 return true; 0494 } 0495 0496 // From original KDE3 code, source unknown? Unable to contact author or committer to confirm 0497 // Matches Fermilab code, EMACS and D&R so check for PD source, likely Birashk's book 0498 0499 qint64 jdCycleStart; 0500 int daysSinceCycleStart; 0501 int cycle; 0502 int dayInCycle; 0503 int yearInCycle; 0504 dateToJulianDay(475, 1, 1, jdCycleStart); 0505 daysSinceCycleStart = jd - jdCycleStart; 0506 cycle = daysSinceCycleStart / 1029983; 0507 dayInCycle = daysSinceCycleStart % 1029983; 0508 if (dayInCycle == 1029982) { 0509 yearInCycle = 2820; 0510 } else { 0511 int aux1 = dayInCycle / 366; 0512 int aux2 = dayInCycle % 366; 0513 yearInCycle = (((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) + aux1 + 1; 0514 } 0515 year = yearInCycle + (2820 * cycle) + 474; 0516 if (year <= 0) { 0517 year = year - 1; 0518 } 0519 0520 qint64 firstDayOfYear; 0521 dateToJulianDay(year, 1, 1, firstDayOfYear); 0522 int dayinYear = jd - firstDayOfYear + 1; 0523 if (dayinYear <= 186) { 0524 month = ((dayinYear - 1) / 31) + 1; 0525 day = dayinYear - ((month - 1) * 31); 0526 } else { 0527 month = ((dayinYear - 7) / 30) + 1; 0528 day = dayinYear - ((month - 1) * 30) - 6; 0529 } 0530 0531 return true; 0532 } 0533 0534 bool KCalendarSystemJalali::dateToJulianDay(int year, int month, int day, qint64 &jd) const 0535 { 0536 Q_D(const KCalendarSystemJalali); 0537 0538 // Birashk algorithm is incorrect in two years in period AP 1244 to 1531. 0539 // This results in a leap day being added to the end of 1404 instead of 1403 0540 // and to the end of 1437 instead of 1436. Thus all dates in 1404 and 1437 0541 // are off by 1 JD. Check for these dates first and adjust accordingly. 0542 if (year == 1403 && month == 12 && day == 30) { 0543 jd = 2460755; 0544 return true; 0545 } 0546 if (year == 1436 && month == 12 && day == 30) { 0547 jd = 2472808; 0548 return true; 0549 } 0550 if (year == 1404 || year == 1437) { 0551 if (month < 12 && day + 1 > d->daysInMonth(year, month)) { 0552 day = 1; 0553 month = month + 1; 0554 } else { 0555 day = day + 1; 0556 } 0557 } 0558 0559 // From original KDE3 code, source unknown? Unable to contact author or committer to confirm 0560 // Matches Fermilab code, EMACS and D&R so check for PD source, likely Birashk's book 0561 int epbase; 0562 long epyear; 0563 long monthDays; 0564 0565 if (year >= 0) { 0566 epbase = year - 474; 0567 } else { 0568 epbase = year - 473; 0569 } 0570 0571 epyear = 474 + (epbase % 2820); 0572 0573 if (month <= 7) { 0574 monthDays = (month - 1) * 31; 0575 } else { 0576 monthDays = ((month - 1) * 30) + 6; 0577 } 0578 0579 jd = (epoch().toJulianDay() - 1) + // days before epoch 0580 (epyear - 1) * 365 + // normal days in previous years 0581 (((epyear * 682) - 110) / 2816) + // leap days in previous years 0582 (epbase / 2820) * 1029983 + 0583 monthDays + // days in previous months this year 0584 day; // days in this month 0585 0586 return true; 0587 }