• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDECore

kcalendarsystemhebrew.cpp
Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2003 Hans Petter Bieker <bieker@kde.org>
00003     Copyright 2007, 2009, 2010 John Layt <john@layt.net>
00004         Calendar conversion routines based on Hdate v6, by Amos
00005         Shapir 1978 (rev. 1985, 1992)
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 // Derived hebrew kde calendar class
00024 
00025 #include "kcalendarsystemhebrew_p.h"
00026 #include "kcalendarsystemprivate_p.h"
00027 
00028 #include "kdebug.h"
00029 #include "klocale.h"
00030 
00031 #include <QtCore/QDate>
00032 #include <QtCore/QCharRef>
00033 
00034 static int hebrewDaysElapsed(int y);
00035 
00036 class h_date
00037 {
00038 public:
00039     int hd_day;
00040     int hd_mon;
00041     int hd_year;
00042     int hd_dw;
00043     int hd_flg;
00044 };
00045 
00046 /*
00047  * compute general date structure from hebrew date
00048  */
00049 static class h_date * hebrewToGregorian(int y, int m, int d)
00050 {
00051     static class h_date h;
00052     int s;
00053 
00054     y -= 3744;
00055     s = hebrewDaysElapsed(y);
00056     d += s;
00057     s = hebrewDaysElapsed(y + 1) - s;      /* length of year */
00058 
00059     if (s > 365 && m > 6) {
00060         --m;
00061         d += 30;
00062     }
00063     d += (59 * (m - 1) + 1) / 2;      /* regular months */
00064     /* special cases */
00065     if (s % 10 > 4 && m > 2) {    /* long Heshvan */
00066         d++;
00067     }
00068     if (s % 10 < 4 && m > 3) {    /* short Kislev */
00069         d--;
00070     }
00071     // ### HPB: Broken in leap years
00072     //if (s > 365 && m > 6)  /* leap year */
00073     //  d += 30;
00074     d -= 6002;
00075 
00076     y = (d + 36525) * 4 / 146097 - 1;
00077     d -= y / 4 * 146097 + (y % 4) * 36524;
00078     y *= 100;
00079 
00080     /* compute year */
00081     s = (d + 366) * 4 / 1461 - 1;
00082     d -= s / 4 * 1461 + (s % 4) * 365;
00083     y += s;
00084     /* compute month */
00085     m = (d + 245) * 12 / 367 - 7;
00086     d -= m * 367 / 12 - 30;
00087     if (++m >= 12) {
00088         m -= 12;
00089         y++;
00090     }
00091     h.hd_day = d;
00092     h.hd_mon = m;
00093     h.hd_year = y;
00094     return(&h);
00095 }
00096 
00097 /*
00098  * compute date structure from no. of days since 1 Tishrei 3744
00099  */
00100 static class h_date * gregorianToHebrew(int y, int m, int d)
00101 {
00102     static class h_date h;
00103     int s;
00104 
00105     if ((m -= 2) <= 0) {
00106         m += 12;
00107         y--;
00108     }
00109     /* no. of days, Julian calendar */
00110     d += 365 * y + y / 4 + 367 * m / 12 + 5968;
00111     /* Gregorian calendar */
00112     d -= y / 100 - y / 400 - 2;
00113     h.hd_dw = (d + 1) % 7;
00114 
00115     /* compute the year */
00116     y += 16;
00117     s = hebrewDaysElapsed(y);
00118     m = hebrewDaysElapsed(y + 1);
00119     while (d >= m) {   /* computed year was underestimated */
00120         s = m;
00121         y++;
00122         m = hebrewDaysElapsed(y + 1);
00123     }
00124     d -= s;
00125     s = m - s;  /* size of current year */
00126     y += 3744;
00127 
00128     h.hd_flg = s % 10 - 4;
00129 
00130     /* compute day and month */
00131     if (d >= s - 236) {    /* last 8 months are regular */
00132         d -= s - 236;
00133         m = d * 2 / 59;
00134         d -= (m * 59 + 1) / 2;
00135         m += 4;
00136         if (s > 365 && m <= 5) {    /* Adar of Meuberet */
00137             m += 8;
00138         }
00139     } else {
00140         /* first 4 months have 117-119 days */
00141         s = 114 + s % 10;
00142         m = d * 4 / s;
00143         d -= (m * s + 3) / 4;
00144     }
00145 
00146     h.hd_day = d;
00147     h.hd_mon = m;
00148     h.hd_year = y;
00149     return(&h);
00150 }
00151 
00152 /* constants, in 1/18th of minute */
00153 static const int HOUR = 1080;
00154 static const int DAY = 24 * HOUR;
00155 static const int WEEK = 7 * DAY;
00156 #define M(h,p) ((h)*HOUR+p)
00157 #define MONTH (DAY+M(12,793))
00158 
00163 static int hebrewDaysElapsed(int y)
00164 {
00165     int m, nm, dw, s, l;
00166 
00167     l = y * 7 + 1;  // no. of leap months
00168     m = y * 12 + l / 19;  // total no. of months
00169     l %= 19;
00170     nm = m * MONTH + M(1 + 6, 779);   // molad new year 3744 (16BC) + 6 hours
00171     s = m * 28 + nm / DAY - 2;
00172 
00173     nm %= WEEK;
00174     dw = nm / DAY;
00175     nm %= DAY;
00176 
00177     // special cases of Molad Zaken
00178     if ((l < 12 && dw == 3 && nm >= M(9 + 6, 204)) ||
00179             (l < 7 && dw == 2 && nm >= M(15 + 6, 589))) {
00180         s++, dw++;
00181     }
00182 
00183     /* ADU */
00184     if (dw == 1 || dw == 4 || dw == 6) {
00185         s++;
00186     }
00187     return s;
00188 }
00189 
00194 static int long_cheshvan(int year)
00195 {
00196     QDate first, last;
00197     class h_date *gd;
00198 
00199     gd = hebrewToGregorian(year, 1, 1);
00200     first.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
00201 
00202     gd = hebrewToGregorian(year + 1, 1, 1);
00203     last.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
00204 
00205     return (first.daysTo(last) % 10 == 5);
00206 }
00207 
00212 static int short_kislev(int year)
00213 {
00214     QDate first, last;
00215     class h_date * gd;
00216 
00217     gd = hebrewToGregorian(year, 1, 1);
00218     first.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
00219 
00220     gd = hebrewToGregorian(year + 1, 1, 1);
00221     last.setYMD(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
00222 
00223     return (first.daysTo(last) % 10 == 3);
00224 }
00225 
00226 // Ok
00227 static class h_date *toHebrew(const QDate &date)
00228 {
00229     class h_date *sd;
00230 
00231     sd = gregorianToHebrew(date.year(), date.month(), date.day());
00232     ++sd->hd_mon;
00233     ++sd->hd_day;
00234 
00235     return sd;
00236 }
00237 
00238 class KCalendarSystemHebrewPrivate : public KCalendarSystemPrivate
00239 {
00240 public:
00241     explicit KCalendarSystemHebrewPrivate(KCalendarSystemHebrew *q);
00242 
00243     virtual ~KCalendarSystemHebrewPrivate();
00244 
00245     // Virtual methods each calendar system must re-implement
00246     virtual KLocale::CalendarSystem calendarSystem() const;
00247     virtual void loadDefaultEraList();
00248     virtual int monthsInYear(int year) const;
00249     virtual int daysInMonth(int year, int month) const;
00250     virtual int daysInYear(int year) const;
00251     virtual int daysInWeek() const;
00252     virtual bool isLeapYear(int year) const;
00253     virtual bool hasLeapMonths() const;
00254     virtual bool hasYearZero() const;
00255     virtual int maxDaysInWeek() const;
00256     virtual int maxMonthsInYear() const;
00257     virtual int earliestValidYear() const;
00258     virtual int latestValidYear() const;
00259     virtual QString monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const;
00260     virtual QString weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const;
00261 
00262     virtual int integerFromString(const QString &string, int maxLength, int &readLength) const;
00263     virtual QString stringFromInteger(int number, int padWidth = 0, QChar padChar = QLatin1Char('0')) const;
00264     virtual QString stringFromInteger(int number, int padWidth, QChar padChar, KLocale::DigitSet digitSet) const;
00265 
00266     virtual int monthNumberToMonthIndex(int year, int month) const;
00267 };
00268 
00269 // Shared d pointer base class definitions
00270 
00271 KCalendarSystemHebrewPrivate::KCalendarSystemHebrewPrivate(KCalendarSystemHebrew *q)
00272                             : KCalendarSystemPrivate(q)
00273 {
00274 }
00275 
00276 KCalendarSystemHebrewPrivate::~KCalendarSystemHebrewPrivate()
00277 {
00278 }
00279 
00280 KLocale::CalendarSystem KCalendarSystemHebrewPrivate::calendarSystem() const
00281 {
00282     return KLocale::HebrewCalendar;
00283 }
00284 
00285 void KCalendarSystemHebrewPrivate::loadDefaultEraList()
00286 {
00287     QString name, shortName, format;
00288     // Jewish Era, Anno Mundi, "Year of the World".
00289     name = i18nc("Calendar Era: Hebrew Era, years > 0, LongFormat", "Anno Mundi");
00290     shortName = i18nc("Calendar Era: Hebrew Era, years > 0, ShortFormat", "AM");
00291     format = i18nc("(kdedt-format) Hebrew, AM, full era year format used for %EY, e.g. 2000 AM", "%Ey %EC");
00292     addEra('+', 1, q->epoch(), 1, q->latestValidDate(), name, shortName, format);
00293 }
00294 
00295 int KCalendarSystemHebrewPrivate::monthsInYear(int year) const
00296 {
00297     if (isLeapYear(year)) {
00298         return 13;
00299     } else {
00300         return 12;
00301     }
00302 }
00303 
00304 int KCalendarSystemHebrewPrivate::daysInMonth(int year, int month) const
00305 {
00306     int mi = monthNumberToMonthIndex(year, month);
00307 
00308     if (mi == 2 && long_cheshvan(year)) {
00309         return 30;
00310     }
00311 
00312     if (mi == 3 && short_kislev(year)) {
00313         return 29;
00314     }
00315 
00316     if (mi % 2 == 0) {    // Even number months have 29 days
00317         return 29;
00318     } else {  // Odd number months have 30 days
00319         return 30;
00320     }
00321 }
00322 
00323 int KCalendarSystemHebrewPrivate::daysInYear(int year) const
00324 {
00325     int days;
00326 
00327     // Get Regular year length
00328     if (isLeapYear(year)) {      // Has 13 months
00329         days = 384;
00330     } else {  // Has 12 months
00331         days = 354;
00332     }
00333 
00334     // Check if is Deficient or Abundant year
00335     if (short_kislev(year)) {     // Deficient
00336         days = days - 1;
00337     } else if (long_cheshvan(year)) {     // Abundant
00338         days = days + 1;
00339     }
00340 
00341     return days;
00342 }
00343 
00344 int KCalendarSystemHebrewPrivate::daysInWeek() const
00345 {
00346     return 7;
00347 }
00348 
00349 bool KCalendarSystemHebrewPrivate::isLeapYear(int year) const
00350 {
00351     return ((((7 * year) + 1) % 19) < 7);
00352 }
00353 
00354 bool KCalendarSystemHebrewPrivate::hasLeapMonths() const
00355 {
00356     return true;
00357 }
00358 
00359 bool KCalendarSystemHebrewPrivate::hasYearZero() const
00360 {
00361     return false;
00362 }
00363 
00364 int KCalendarSystemHebrewPrivate::maxDaysInWeek() const
00365 {
00366     return 7;
00367 }
00368 
00369 int KCalendarSystemHebrewPrivate::maxMonthsInYear() const
00370 {
00371     return 13;
00372 }
00373 
00374 int KCalendarSystemHebrewPrivate::earliestValidYear() const
00375 {
00376     return 5344;
00377 }
00378 
00379 int KCalendarSystemHebrewPrivate::latestValidYear() const
00380 {
00381     return 8119;
00382 }
00383 
00384 int KCalendarSystemHebrewPrivate::integerFromString(const QString &inputString, int maxLength, int &readLength) const
00385 {
00386     if (locale()->language() == QLatin1String("he")) {
00387 
00388         // Hebrew numbers are composed of combinations of normal letters which have a numeric value.
00389         // This is a non-positional system, the numeric values are simply added together, however
00390         // convention is for a RTL highest to lowest value ordering. There is also a degree of
00391         // ambiguity due to the lack of a letter for 0, hence 5 and 5000 are written the same.
00392         // Hebrew numbers are only used in dates.
00393         // See http://www.i18nguy.com/unicode/hebrew-numbers.html for more explaination
00394 
00395         /*
00396         Ref table for numbers to Hebrew chars
00397 
00398         Value     1       2       3        4        5       6         7        8      9
00399 
00400         x 1    Alef א  Bet  ב  Gimel ג  Dalet ד  He   ה  Vav  ו    Zayen ז  Het  ח  Tet  ט
00401                0x05D0  0x05D1  0x05D2   0x05D3   0x05D4  0x05D5    0x05D6   0x05D7  0x05D8
00402 
00403         x 10   Yod  י  Kaf  כ  Lamed ל  Mem  מ   Nun  נ  Samekh ס  Ayin ע   Pe   פ  Tzadi צ
00404                0x05D9  0x05DB  0x05DC   0x05DE   0x05E0  0x05E1    0x05E2   0x05E4  0x05E6
00405 
00406         x 100  Qof  ק  Resh ר  Shin ש   Tav  ת
00407                0x05E7  0x05E8  0x05E9   0x05EA
00408 
00409         Note special cases 15 = 9 + 6 = 96 טו and 16 = 9 + 7 = 97 טז
00410         */
00411 
00412         int decadeValues[14] = {10, 20, 20, 30, 40, 40, 50, 50, 60, 70, 80, 80, 90, 90};
00413 
00414         QChar thisChar, nextChar;
00415         QString string = inputString;
00416 
00417         int stringLength = string.length();
00418         readLength = 0;
00419         int position = 0;
00420         int result = 0;
00421         int value = 0;
00422 
00423         for (; position < stringLength ; ++position) {
00424 
00425             thisChar = string[position];
00426 
00427             if (position + 1 < stringLength) {
00428                 nextChar = string[position + 1];
00429                 // Ignore any geresh or gershayim chars, we don't bother checking they are in the right place
00430                 if (nextChar == QLatin1Char('\'') ||  nextChar == QChar(0x05F3) ||      // geresh
00431                         nextChar == QLatin1Char('\"') ||  nextChar == QChar(0x05F4)) {     // gershayim
00432                     string.remove(position + 1, 1);
00433                     stringLength = string.length();
00434                     if (position + 1 < stringLength) {
00435                         nextChar = string[position + 1];
00436                     } else {
00437                         nextChar = QChar();
00438                     }
00439                     readLength = readLength + 1;
00440                 }
00441             } else {
00442                 nextChar = QChar();
00443             }
00444 
00445             if (thisChar >= QChar(0x05D0) && thisChar <= QChar(0x05D7)) {
00446 
00447                 // If this char Alef to Het, 1 to 8, א to ח
00448 
00449                 // If next char is any valid digit char (Alef to Tav, 1 to 400, א to ת)
00450                 // then this char is a thousands digit
00451                 // else this char is a ones digit
00452 
00453                 if (nextChar >= QChar(0x05D0) && nextChar <= QChar(0x05EA)) {
00454                     value = (thisChar.unicode() - 0x05D0 + 1) * 1000;
00455                 } else {
00456                     value = thisChar.unicode() - 0x05D0 + 1;
00457                 }
00458 
00459             } else if (thisChar == QChar(0x05D8)) {
00460 
00461                 // If this char is Tet, 9, ט
00462 
00463                 // If next char is any valid digit char (Alef to Tav, 1 to 400, א to ת)
00464                 // and next char not 6 (Special case for 96 = 15)
00465                 // and next char not 7 (Special case for 97 = 16)
00466                 // then is a thousands digit else is 9
00467 
00468                 if (nextChar >= QChar(0x05D0) && nextChar <= QChar(0x05EA) &&
00469                         nextChar != QChar(0x05D5) && nextChar != QChar(0x05D6)) {
00470                     value = 9000;
00471                 } else {
00472                     value = 9;
00473                 }
00474 
00475             } else if (thisChar >= QChar(0x05D9) && thisChar <= QChar(0x05E6)) {
00476 
00477                 // If this char Yod to Tsadi, 10 to 90, י to צ
00478 
00479                 // If next char is a tens or hundreds char then is an error
00480                 // Else is a tens digit
00481 
00482                 if (nextChar >= QChar(0x05D9)) {
00483                     return -1;
00484                 } else {
00485                     value = decadeValues[thisChar.unicode() - 0x05D9];
00486                 }
00487 
00488             } else if (thisChar >= QChar(0x05E7) && thisChar <= QChar(0x05EA)) {
00489 
00490                 // If this char Qof to Tav, 100 to 400, ק to ת, then is hundreds digit
00491 
00492                 value = (thisChar.unicode() - 0x05E7 + 1) * 100;
00493 
00494             } else {
00495 
00496                 // If this char any non-digit char including whitespace or punctuation, we're done
00497                 break;
00498 
00499             }
00500 
00501             result = result + value;
00502 
00503             value = 0;
00504         }
00505 
00506         readLength += position;
00507 
00508         return result;
00509 
00510     } else {
00511         return KCalendarSystemPrivate::integerFromString(inputString, maxLength, readLength);
00512     }
00513 }
00514 
00515 QString KCalendarSystemHebrewPrivate::stringFromInteger(int number, int padWidth, QChar padChar) const
00516 {
00517     return KCalendarSystemPrivate::stringFromInteger(number, padWidth, padChar);
00518 }
00519 
00520 QString KCalendarSystemHebrewPrivate::stringFromInteger(int number, int padWidth, QChar padChar, KLocale::DigitSet digitSet) const
00521 {
00522     if (locale()->language() == QLatin1String("he")) {
00523 
00524         // Hebrew numbers are composed of combinations of normal letters which have a numeric value.
00525         // This is a non-positional system, the numeric values are simply added together, however
00526         // convention is for a RTL highest to lowest value ordering. There is also a degree of
00527         // ambiguity due to the lack of a letter for 0, hence 5 and 5000 are written the same.
00528         // Hebrew numbers are only used in dates.
00529         // See http://www.i18nguy.com/unicode/hebrew-numbers.html for more explaination
00530 
00531         /*
00532         Ref table for numbers to Hebrew chars
00533 
00534         Value     1       2       3        4        5       6         7        8      9
00535 
00536         x 1    Alef א  Bet  ב  Gimel ג  Dalet ד  He   ה  Vav  ו    Zayen ז  Het  ח  Tet  ט
00537                0x05D0  0x05D1  0x05D2   0x05D3   0x05D4  0x05D5    0x05D6   0x05D7  0x05D8
00538 
00539         x 10   Yod  י  Kaf  כ  Lamed ל  Mem  מ   Nun  נ  Samekh ס  Ayin ע   Pe   פ  Tzadi צ
00540                0x05D9  0x05DB  0x05DC   0x05DE   0x05E0  0x05E1    0x05E2   0x05E4  0x05E6
00541 
00542         x 100  Qof  ק  Resh ר  Shin ש   Tav  ת
00543                0x05E7  0x05E8  0x05E9   0x05EA
00544 
00545         Note special cases 15 = 9 + 6 = 96 טו and 16 = 9 + 7 = 97 טז
00546         */
00547 
00548         const QChar decade[] = {
00549             //  Tet = ט,    Yod = י,    Kaf = כ,    Lamed = ל,  Mem = מ
00550             //  Nun = נ,    Samekh = ס, Ayin = ע,   Pe = פ,     Tsadi = צ
00551             0x05D8,     0x05D9,     0x05DB,     0x05DC,     0x05DE,
00552             0x05E0,     0x05E1,     0x05E2,     0x05E4,     0x05E6
00553         };
00554 
00555         QString result;
00556 
00557         // We have no rules for coping with numbers outside this range
00558         if (number < 1 || number > 9999) {
00559             return KCalendarSystemPrivate::stringFromInteger(number, padWidth, padChar, digitSet);
00560         }
00561 
00562         // Translate the thousands digit, just uses letter for number 1..9 ( א to ט, Alef to Tet )
00563         // Years 5001-5999 do not have the thousands by convention
00564         if (number >= 1000) {
00565             if (number <= 5000 || number >= 6000) {
00566                 result += QChar(0x05D0 - 1 + number / 1000);    // Alef א to Tet ט
00567             }
00568             number %= 1000;
00569         }
00570 
00571         // Translate the hundreds digit
00572         // Use traditional method where we only have letters assigned values for 100, 200, 300 and 400
00573         // so may need to repeat 400 twice to make up the required number
00574         if (number >= 100) {
00575             while (number >= 500) {
00576                 result += QChar(0x05EA);    // Tav = ת
00577                 number -= 400;
00578             }
00579             result += QChar(0x05E7 - 1 + number / 100);   // Qof = ק to xxx
00580             number %= 100;
00581         }
00582 
00583         // Translate the tens digit
00584         // The numbers 15 and 16 translate to letters that spell out the name of God which is
00585         // forbidden, so require special treatment where 15 = 9 + 6 and 1 = 9 + 7.
00586         if (number >= 10) {
00587             if (number == 15 || number == 16)
00588                 number -= 9;
00589             result += decade[number / 10];
00590             number %= 10;
00591         }
00592 
00593         // Translate the ones digit, uses letter for number 1..9 ( א to ט, Alef to Tet )
00594         if (number > 0) {
00595             result += QChar(0x05D0 - 1 + number);    // Alef = א to xxx
00596         }
00597 
00598         // When used in a string with mixed names and numbers the numbers need special chars to
00599         // distinguish them from words composed of the same letters.
00600         // Single digit numbers are followed by a geresh symbol ? (Unicode = 0x05F3), but we use
00601         // single quote for convenience.
00602         // Multiple digit numbers have a gershayim symbol ? (Unicode = 0x05F4) as second-to-last
00603         // char, but we use double quote for convenience.
00604         if (result.length() == 1) {
00605             result += QLatin1Char('\'');
00606         } else {
00607             result.insert(result.length() - 1, QLatin1Char('\"'));
00608         }
00609 
00610         return result;
00611 
00612     } else {
00613         return KCalendarSystemPrivate::stringFromInteger(number, padWidth, padChar, digitSet);
00614     }
00615 }
00616 
00617 int KCalendarSystemHebrewPrivate::monthNumberToMonthIndex(int year, int month) const
00618 {
00619     if (isLeapYear(year)) {
00620         if (month == 6) {
00621             return 13;        // Adar I
00622         } else if (month == 7) {
00623             return 14;        // Adar II
00624         } else if (month > 7) {
00625             return month - 1; // Because of Adar II
00626         }
00627     }
00628 
00629     return month;
00630 }
00631 
00632 QString KCalendarSystemHebrewPrivate::monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const
00633 {
00634     // We must map month number to month index
00635     int monthIndex = monthNumberToMonthIndex(year, month);
00636 
00637     if (format == KLocale::NarrowName) {
00638         switch (monthIndex) {
00639         case 1:
00640             return ki18nc("Hebrew month 1 - KLocale::NarrowName",  "T").toString(locale());
00641         case 2:
00642             return ki18nc("Hebrew month 2 - KLocale::NarrowName",  "H").toString(locale());
00643         case 3:
00644             return ki18nc("Hebrew month 3 - KLocale::NarrowName",  "K").toString(locale());
00645         case 4:
00646             return ki18nc("Hebrew month 4 - KLocale::NarrowName",  "T").toString(locale());
00647         case 5:
00648             return ki18nc("Hebrew month 5 - KLocale::NarrowName",  "S").toString(locale());
00649         case 6:
00650             return ki18nc("Hebrew month 6 - KLocale::NarrowName",  "A").toString(locale());
00651         case 7:
00652             return ki18nc("Hebrew month 7 - KLocale::NarrowName",  "N").toString(locale());
00653         case 8:
00654             return ki18nc("Hebrew month 8 - KLocale::NarrowName",  "I").toString(locale());
00655         case 9:
00656             return ki18nc("Hebrew month 9 - KLocale::NarrowName",  "S").toString(locale());
00657         case 10:
00658             return ki18nc("Hebrew month 10 - KLocale::NarrowName", "T").toString(locale());
00659         case 11:
00660             return ki18nc("Hebrew month 11 - KLocale::NarrowName", "A").toString(locale());
00661         case 12:
00662             return ki18nc("Hebrew month 12 - KLocale::NarrowName", "E").toString(locale());
00663         case 13:
00664             return ki18nc("Hebrew month 13 - KLocale::NarrowName", "A").toString(locale());
00665         case 14:
00666             return ki18nc("Hebrew month 14 - KLocale::NarrowName", "A").toString(locale());
00667         default:
00668             return QString();
00669         }
00670     }
00671 
00672     if (format == KLocale::ShortName && possessive) {
00673         switch (monthIndex) {
00674         case 1:
00675             return ki18nc("Hebrew month 1 - KLocale::ShortName Possessive",  "of Tis").toString(locale());
00676         case 2:
00677             return ki18nc("Hebrew month 2 - KLocale::ShortName Possessive",  "of Hes").toString(locale());
00678         case 3:
00679             return ki18nc("Hebrew month 3 - KLocale::ShortName Possessive",  "of Kis").toString(locale());
00680         case 4:
00681             return ki18nc("Hebrew month 4 - KLocale::ShortName Possessive",  "of Tev").toString(locale());
00682         case 5:
00683             return ki18nc("Hebrew month 5 - KLocale::ShortName Possessive",  "of Shv").toString(locale());
00684         case 6:
00685             return ki18nc("Hebrew month 6 - KLocale::ShortName Possessive",  "of Ada").toString(locale());
00686         case 7:
00687             return ki18nc("Hebrew month 7 - KLocale::ShortName Possessive",  "of Nis").toString(locale());
00688         case 8:
00689             return ki18nc("Hebrew month 8 - KLocale::ShortName Possessive",  "of Iya").toString(locale());
00690         case 9:
00691             return ki18nc("Hebrew month 9 - KLocale::ShortName Possessive",  "of Siv").toString(locale());
00692         case 10:
00693             return ki18nc("Hebrew month 10 - KLocale::ShortName Possessive", "of Tam").toString(locale());
00694         case 11:
00695             return ki18nc("Hebrew month 11 - KLocale::ShortName Possessive", "of Av").toString(locale());
00696         case 12:
00697             return ki18nc("Hebrew month 12 - KLocale::ShortName Possessive", "of Elu").toString(locale());
00698         case 13:
00699             return ki18nc("Hebrew month 13 - KLocale::ShortName Possessive", "of Ad1").toString(locale());
00700         case 14:
00701             return ki18nc("Hebrew month 14 - KLocale::ShortName Possessive", "of Ad2").toString(locale());
00702         default:
00703             return QString();
00704         }
00705     }
00706 
00707     if (format == KLocale::ShortName && !possessive) {
00708         switch (monthIndex) {
00709         case 1:
00710             return ki18nc("Hebrew month 1 - KLocale::ShortName",  "Tis").toString(locale());
00711         case 2:
00712             return ki18nc("Hebrew month 2 - KLocale::ShortName",  "Hes").toString(locale());
00713         case 3:
00714             return ki18nc("Hebrew month 3 - KLocale::ShortName",  "Kis").toString(locale());
00715         case 4:
00716             return ki18nc("Hebrew month 4 - KLocale::ShortName",  "Tev").toString(locale());
00717         case 5:
00718             return ki18nc("Hebrew month 5 - KLocale::ShortName",  "Shv").toString(locale());
00719         case 6:
00720             return ki18nc("Hebrew month 6 - KLocale::ShortName",  "Ada").toString(locale());
00721         case 7:
00722             return ki18nc("Hebrew month 7 - KLocale::ShortName",  "Nis").toString(locale());
00723         case 8:
00724             return ki18nc("Hebrew month 8 - KLocale::ShortName",  "Iya").toString(locale());
00725         case 9:
00726             return ki18nc("Hebrew month 9 - KLocale::ShortName",  "Siv").toString(locale());
00727         case 10:
00728             return ki18nc("Hebrew month 10 - KLocale::ShortName", "Tam").toString(locale());
00729         case 11:
00730             return ki18nc("Hebrew month 11 - KLocale::ShortName", "Av").toString(locale());
00731         case 12:
00732             return ki18nc("Hebrew month 12 - KLocale::ShortName", "Elu").toString(locale());
00733         case 13:
00734             return ki18nc("Hebrew month 13 - KLocale::ShortName", "Ad1").toString(locale());
00735         case 14:
00736             return ki18nc("Hebrew month 14 - KLocale::ShortName", "Ad2").toString(locale());
00737         default:
00738             return QString();
00739         }
00740     }
00741 
00742     if (format == KLocale::LongName && possessive) {
00743         switch (monthIndex) {
00744         case 1:
00745             return ki18nc("Hebrew month 1 - KLocale::LongName Possessive",  "of Tishrey").toString(locale());
00746         case 2:
00747             return ki18nc("Hebrew month 2 - KLocale::LongName Possessive",  "of Heshvan").toString(locale());
00748         case 3:
00749             return ki18nc("Hebrew month 3 - KLocale::LongName Possessive",  "of Kislev").toString(locale());
00750         case 4:
00751             return ki18nc("Hebrew month 4 - KLocale::LongName Possessive",  "of Tevet").toString(locale());
00752         case 5:
00753             return ki18nc("Hebrew month 5 - KLocale::LongName Possessive",  "of Shvat").toString(locale());
00754         case 6:
00755             return ki18nc("Hebrew month 6 - KLocale::LongName Possessive",  "of Adar").toString(locale());
00756         case 7:
00757             return ki18nc("Hebrew month 7 - KLocale::LongName Possessive",  "of Nisan").toString(locale());
00758         case 8:
00759             return ki18nc("Hebrew month 8 - KLocale::LongName Possessive",  "of Iyar").toString(locale());
00760         case 9:
00761             return ki18nc("Hebrew month 9 - KLocale::LongName Possessive",  "of Sivan").toString(locale());
00762         case 10:
00763             return ki18nc("Hebrew month 10 - KLocale::LongName Possessive", "of Tamuz").toString(locale());
00764         case 11:
00765             return ki18nc("Hebrew month 11 - KLocale::LongName Possessive", "of Av").toString(locale());
00766         case 12:
00767             return ki18nc("Hebrew month 12 - KLocale::LongName Possessive", "of Elul").toString(locale());
00768         case 13:
00769             return ki18nc("Hebrew month 13 - KLocale::LongName Possessive", "of Adar I").toString(locale());
00770         case 14:
00771             return ki18nc("Hebrew month 14 - KLocale::LongName Possessive", "of Adar II").toString(locale());
00772         default:
00773             return QString();
00774         }
00775     }
00776 
00777     // Default to LongName
00778     switch (monthIndex) {
00779     case 1:
00780         return ki18nc("Hebrew month 1 - KLocale::LongName",  "Tishrey").toString(locale());
00781     case 2:
00782         return ki18nc("Hebrew month 2 - KLocale::LongName",  "Heshvan").toString(locale());
00783     case 3:
00784         return ki18nc("Hebrew month 3 - KLocale::LongName",  "Kislev").toString(locale());
00785     case 4:
00786         return ki18nc("Hebrew month 4 - KLocale::LongName",  "Tevet").toString(locale());
00787     case 5:
00788         return ki18nc("Hebrew month 5 - KLocale::LongName",  "Shvat").toString(locale());
00789     case 6:
00790         return ki18nc("Hebrew month 6 - KLocale::LongName",  "Adar").toString(locale());
00791     case 7:
00792         return ki18nc("Hebrew month 7 - KLocale::LongName",  "Nisan").toString(locale());
00793     case 8:
00794         return ki18nc("Hebrew month 8 - KLocale::LongName",  "Iyar").toString(locale());
00795     case 9:
00796         return ki18nc("Hebrew month 9 - KLocale::LongName",  "Sivan").toString(locale());
00797     case 10:
00798         return ki18nc("Hebrew month 10 - KLocale::LongName", "Tamuz").toString(locale());
00799     case 11:
00800         return ki18nc("Hebrew month 11 - KLocale::LongName", "Av").toString(locale());
00801     case 12:
00802         return ki18nc("Hebrew month 12 - KLocale::LongName", "Elul").toString(locale());
00803     case 13:
00804         return ki18nc("Hebrew month 13 - KLocale::LongName", "Adar I").toString(locale());
00805     case 14:
00806         return ki18nc("Hebrew month 14 - KLocale::LongName", "Adar II").toString(locale());
00807     default:
00808         return QString();
00809     }
00810 }
00811 
00812 // Use Western day names for now as that's what the old version did,
00813 // but wouldn't it be better to use the right Hebrew names like Shabbat?
00814 // Could make it switchable by adding new enums to WeekDayFormat, e.g. ShortNameWestern?
00815 QString KCalendarSystemHebrewPrivate::weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const
00816 {
00817     if (format == KLocale::NarrowName) {
00818         switch (weekDay) {
00819         case 1:
00820             return ki18nc("Gregorian weekday 1 - KLocale::NarrowName ", "M").toString(locale());
00821         case 2:
00822             return ki18nc("Gregorian weekday 2 - KLocale::NarrowName ", "T").toString(locale());
00823         case 3:
00824             return ki18nc("Gregorian weekday 3 - KLocale::NarrowName ", "W").toString(locale());
00825         case 4:
00826             return ki18nc("Gregorian weekday 4 - KLocale::NarrowName ", "T").toString(locale());
00827         case 5:
00828             return ki18nc("Gregorian weekday 5 - KLocale::NarrowName ", "F").toString(locale());
00829         case 6:
00830             return ki18nc("Gregorian weekday 6 - KLocale::NarrowName ", "S").toString(locale());
00831         case 7:
00832             return ki18nc("Gregorian weekday 7 - KLocale::NarrowName ", "S").toString(locale());
00833         default:
00834             return QString();
00835         }
00836     }
00837 
00838     if (format == KLocale::ShortName  || format == KLocale:: ShortNumber) {
00839         switch (weekDay) {
00840         case 1:
00841             return ki18nc("Gregorian weekday 1 - KLocale::ShortName", "Mon").toString(locale());
00842         case 2:
00843             return ki18nc("Gregorian weekday 2 - KLocale::ShortName", "Tue").toString(locale());
00844         case 3:
00845             return ki18nc("Gregorian weekday 3 - KLocale::ShortName", "Wed").toString(locale());
00846         case 4:
00847             return ki18nc("Gregorian weekday 4 - KLocale::ShortName", "Thu").toString(locale());
00848         case 5:
00849             return ki18nc("Gregorian weekday 5 - KLocale::ShortName", "Fri").toString(locale());
00850         case 6:
00851             return ki18nc("Gregorian weekday 6 - KLocale::ShortName", "Sat").toString(locale());
00852         case 7:
00853             return ki18nc("Gregorian weekday 7 - KLocale::ShortName", "Sun").toString(locale());
00854         default: return QString();
00855         }
00856     }
00857 
00858     switch (weekDay) {
00859     case 1:
00860         return ki18nc("Gregorian weekday 1 - KLocale::LongName", "Monday").toString(locale());
00861     case 2:
00862         return ki18nc("Gregorian weekday 2 - KLocale::LongName", "Tuesday").toString(locale());
00863     case 3:
00864         return ki18nc("Gregorian weekday 3 - KLocale::LongName", "Wednesday").toString(locale());
00865     case 4:
00866         return ki18nc("Gregorian weekday 4 - KLocale::LongName", "Thursday").toString(locale());
00867     case 5:
00868         return ki18nc("Gregorian weekday 5 - KLocale::LongName", "Friday").toString(locale());
00869     case 6:
00870         return ki18nc("Gregorian weekday 6 - KLocale::LongName", "Saturday").toString(locale());
00871     case 7:
00872         return ki18nc("Gregorian weekday 7 - KLocale::LongName", "Sunday").toString(locale());
00873     default:
00874         return QString();
00875     }
00876 }
00877 
00878 
00879 KCalendarSystemHebrew::KCalendarSystemHebrew(const KLocale *locale)
00880                      : KCalendarSystem(*new KCalendarSystemHebrewPrivate(this), KSharedConfig::Ptr(), locale)
00881 {
00882     d_ptr->loadConfig(calendarType());
00883 }
00884 
00885 KCalendarSystemHebrew::KCalendarSystemHebrew(const KSharedConfig::Ptr config, const KLocale *locale)
00886                      : KCalendarSystem(*new KCalendarSystemHebrewPrivate(this), config, locale)
00887 {
00888     d_ptr->loadConfig(calendarType());
00889 }
00890 
00891 KCalendarSystemHebrew::KCalendarSystemHebrew(KCalendarSystemHebrewPrivate &dd,
00892                                              const KSharedConfig::Ptr config, const KLocale *locale)
00893                      : KCalendarSystem(dd, config, locale)
00894 {
00895     d_ptr->loadConfig(calendarType());
00896 }
00897 
00898 KCalendarSystemHebrew::~KCalendarSystemHebrew()
00899 {
00900 }
00901 
00902 QString KCalendarSystemHebrew::calendarType() const
00903 {
00904     return QLatin1String("hebrew");
00905 }
00906 
00907 QDate KCalendarSystemHebrew::epoch() const
00908 {
00909     // Hebrew 0001-01-01 (Gregorian -3760-09-07, Julian -3761-10-07)
00910     return QDate::fromJulianDay(347998);
00911 }
00912 
00913 QDate KCalendarSystemHebrew::earliestValidDate() const
00914 {
00915     // Current formulas using direct Gregorian <-> Hebrew conversion using Qt
00916     // will return invalid results prior to the Gregorian switchover in 1582
00917     // Next valid Hebrew year starts 5344-01-01 (Gregorian 1583-09-17)
00918     return QDate::fromJulianDay(2299498);
00919 }
00920 
00921 QDate KCalendarSystemHebrew::latestValidDate() const
00922 {
00923     // Testing shows current formulas only work up to 8119-13-29 (Gregorian 4359-10-07)
00924     return QDate::fromJulianDay(3313431);
00925 }
00926 
00927 bool KCalendarSystemHebrew::isValid(int year, int month, int day) const
00928 {
00929     return KCalendarSystem::isValid(year, month, day);
00930 }
00931 
00932 bool KCalendarSystemHebrew::isValid(const QDate &date) const
00933 {
00934     return KCalendarSystem::isValid(date);
00935 }
00936 
00937 int KCalendarSystemHebrew::dayOfWeek(const QDate &date) const
00938 {
00939     class h_date * sd = toHebrew(date);
00940     if (sd->hd_dw == 0) {
00941         return 7;
00942     } else {
00943         return (sd->hd_dw);
00944     }
00945 }
00946 
00947 bool KCalendarSystemHebrew::isLeapYear(int year) const
00948 {
00949     return KCalendarSystem::isLeapYear(year);
00950 }
00951 
00952 bool KCalendarSystemHebrew::isLeapYear(const QDate &date) const
00953 {
00954     return KCalendarSystem::isLeapYear(date);
00955 }
00956 
00957 QString KCalendarSystemHebrew::monthName(int month, int year, MonthNameFormat format) const
00958 {
00959     return KCalendarSystem::monthName(month, year, format);
00960 }
00961 
00962 QString KCalendarSystemHebrew::monthName(const QDate &date, MonthNameFormat format) const
00963 {
00964     return KCalendarSystem::monthName(date, format);
00965 }
00966 
00967 QString KCalendarSystemHebrew::weekDayName(int weekDay, WeekDayNameFormat format) const
00968 {
00969     return KCalendarSystem::weekDayName(weekDay, format);
00970 }
00971 
00972 QString KCalendarSystemHebrew::weekDayName(const QDate &date, WeekDayNameFormat format) const
00973 {
00974     return KCalendarSystem::weekDayName(date, format);
00975 }
00976 
00977 int KCalendarSystemHebrew::yearStringToInteger(const QString &string, int &readLength) const
00978 {
00979     int result = KCalendarSystem::yearStringToInteger(string, readLength);
00980 
00981     // Hebrew has no letter for 0, so 5 and 5000 are written the same
00982     // Assume if less than 10 then we are in an exact multiple of 1000
00983     if (result < 10) {
00984         result = result * 1000;
00985     }
00986 
00987     // Not good just assuming, make configurable
00988     if (result < 1000) {
00989         result += 5000; // assume we're in the 6th millenium (y6k bug)
00990     }
00991 
00992     return result;
00993 }
00994 
00995 int KCalendarSystemHebrew::weekDayOfPray() const
00996 {
00997     return 6; // Saturday
00998 }
00999 
01000 bool KCalendarSystemHebrew::isLunar() const
01001 {
01002     return false;
01003 }
01004 
01005 bool KCalendarSystemHebrew::isLunisolar() const
01006 {
01007     return true;
01008 }
01009 
01010 bool KCalendarSystemHebrew::isSolar() const
01011 {
01012     return false;
01013 }
01014 
01015 bool KCalendarSystemHebrew::isProleptic() const
01016 {
01017     return false;
01018 }
01019 
01020 bool KCalendarSystemHebrew::julianDayToDate(int jd, int &year, int &month, int &day) const
01021 {
01022     class h_date * sd = toHebrew(QDate::fromJulianDay(jd));
01023 
01024     year = sd->hd_year;
01025 
01026     month = sd->hd_mon;
01027     if (isLeapYear(sd->hd_year)) {
01028         if (month == 13 /*AdarI*/) {
01029             month = 6;
01030         } else if (month == 14 /*AdarII*/) {
01031             month = 7;
01032         } else if (month > 6 && month < 13) {
01033             ++month;
01034         }
01035     }
01036 
01037     day = sd->hd_day;
01038 
01039     return true;
01040 }
01041 
01042 bool KCalendarSystemHebrew::dateToJulianDay(int year, int month, int day, int &jd) const
01043 {
01044     class h_date * gd = hebrewToGregorian(year, month, day);
01045 
01046     QDate tempDate(gd->hd_year, gd->hd_mon + 1, gd->hd_day + 1);
01047 
01048     jd = tempDate.toJulianDay();
01049 
01050     return true;
01051 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal