| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kcalendarsystemjalali.cpp

    00001 /*
    00002    Copyright (C) 2002-2003 Arash Bijanzadeh  and FarsiKDE Project <www.farsikde.org>
    00003    Contact: Arash Bijanzadeh <a.bijanzadeh@linuxiran.org>
    00004
    00005    This program is part of FarsiKDE
    00006
    00007    FarsiKDE 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    FarsiKDE 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., 59 Temple Place - Suite 330,
    00020    Boston, MA 02111-1307, USA.
    00021  */
    00022
    00023
    00024 #include <qdatetime.h>
    00025 #include <qstring.h>
    00026 #include <qstringlist.h>
    00027 #include <math.h>
    00028
    00029 #include <kglobal.h>
    00030 #include <klocale.h>
    00031 #include <kdebug.h>
    00032 #include <stdio.h>
    00033
    00034 #include "kcalendarsystemjalali.h"
    00035
    00036 static const int  gMonthDay[2][13]={
    00037         {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    00038         {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    00039 };
    00040
    00041 static const    int     jMonthDay[2][13] = {
    00042         {0, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29},
    00043         {0, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30},
    00044 };
    00045
    00046 typedef struct {
    00047         int day;
    00048         int mon;
    00049         int year;
    00050         } SDATE;
    00051 // converting funcs from
    00052
    00053 static int Ceil(float number)
    00054 {
    00055     int ret;
    00056     if(number>0)
    00057     number += 0.5;
    00058     ret =(int) number;
    00059     return ret;
    00060 }
    00061
    00062 static long jalali_jdn(int year, int month, int day)
    00063 {
    00064     const long PERSIAN_EPOCH = 1948321; /* The JDN of 1 Farvardin 1*/
    00065     int epbase;
    00066     long epyear;
    00067     long mdays;
    00068     long jdn;
    00069     epbase = year - 474;
    00070     epyear = 474 + (epbase % 2820);
    00071     if (month <= 7)
    00072         mdays = (month - 1) * 31;
    00073     else
    00074         mdays = (month - 1) * 30 + 6;
    00075     jdn = day + mdays ;
    00076     jdn += (((epyear * 682) - 110) / 2816) ;
    00077     jdn += (epyear - 1) * 365;
    00078     jdn += (epbase / 2820) * 1029983 ;
    00079     jdn += (PERSIAN_EPOCH - 1);
    00080     return jdn;
    00081 }
    00082
    00083
    00084 static SDATE jdn_jalali(long jdn)
    00085 {
    00086     static SDATE ret;
    00087     int day, month, year;
    00088     int iYear, iMonth, iDay;
    00089     int depoch;
    00090     int cycle;
    00091     int cyear;
    00092     int ycycle;
    00093     int aux1, aux2;
    00094     int yday;
    00095     day = 1;
    00096     month = 1;
    00097     year = 475;
    00098     depoch = jdn - jalali_jdn(year,month, day);
    00099     cycle = (int) (depoch / 1029983);
    00100     cyear = depoch % 1029983;
    00101     if( cyear == 1029982)
    00102         ycycle = 2820;
    00103     else{
    00104         aux1 = cyear / 366;
    00105         aux2 = cyear % 366;
    00106         ycycle = (((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) + aux1 + 1;
    00107     }
    00108     iYear = ycycle + (2820 * cycle) + 474;
    00109     if (iYear <= 0)
    00110         iYear = iYear - 1;
    00111     year = iYear;
    00112     yday = (jdn - jalali_jdn(year, month, day)) + 1;
    00113     if(yday <= 186 )
    00114         iMonth = Ceil((yday-1) / 31);
    00115     else
    00116         iMonth = Ceil((yday - 7) / 30);
    00117     iMonth++;
    00118     month = iMonth;
    00119     iDay = (jdn - jalali_jdn(year, month, day)) + 1;
    00120     ret.day = iDay;
    00121     ret.mon = iMonth;
    00122     ret.year = iYear;
    00123     return ret;
    00124 }
    00125
    00126
    00127
    00128 static long civil_jdn(int year, int month, int day)
    00129 {
    00130     long jdn = ((1461 * (year + 4800 + ((month - 14) / 12))) / 4)
    00131     + ((367 * (month - 2 - 12 * (((month - 14) / 12)))) / 12)
    00132     - ((3 * (((year + 4900 + ((month - 14) / 12)) / 100))) / 4)
    00133     + day - 32075;
    00134     return jdn;
    00135 }
    00136
    00137 static SDATE jdn_civil(long jdn)
    00138 {
    00139     long l, n, i, j;
    00140     static SDATE ret;
    00141     int iday, imonth, iyear;
    00142     l = jdn + 68569;
    00143     n = ((4 * l) / 146097);
    00144     l = l - ((146097 * n + 3) / 4);
    00145     i = ((4000 * (l + 1)) / 1461001);
    00146     l = l - ((1461 * i) / 4) + 31;
    00147     j = ((80 * l) / 2447);
    00148     iday = l - ((2447 * j) / 80);
    00149     l = (j / 11);
    00150     imonth = j + 2 - 12 * l;
    00151     iyear = 100 * (n - 49) + i + l;
    00152     ret.day = iday;
    00153     ret.mon = imonth;
    00154     ret.year = iyear;
    00155     return (ret);
    00156 }
    00157
    00158 static SDATE *jalaliToGregorian(int y,int m,int d)
    00159 {
    00160 static SDATE sd;
    00161 long jday = jalali_jdn(y,m,d);
    00162 sd= jdn_civil(jday);
    00163 return (&sd);
    00164 }
    00165 static SDATE *gregorianToJalali(int y,int m, int d)
    00166 {
    00167     static SDATE sd;
    00168     long   jdn = civil_jdn(y,m,d);//QDate::gregorianToJulian(y, m, d);
    00169     sd = jdn_jalali(jdn);
    00170     return(&sd);
    00171 }
    00172 static void gregorianToJalali(const QDate & date, int * pYear, int * pMonth,
    00173                                int * pDay)
    00174 {
    00175   SDATE *sd;
    00176   sd = gregorianToJalali(date.year(), date.month(), date.day());
    00177   if (pYear)
    00178     *pYear = sd->year;
    00179   if (pMonth)
    00180     *pMonth = sd->mon;
    00181   if (pDay)
    00182     *pDay = sd->day;
    00183
    00184 }
    00185
    00186 // End of converting functions
    00187
    00188 static int isJalaliLeap(int year)
    00189 {
    00190  int     tmp;
    00191  tmp = year % 33;
    00192  if (tmp == 1 || tmp == 5||tmp==9||tmp==13||tmp==17||tmp==22||tmp==26||tmp==30)
    00193      return 1;
    00194 else
    00195      return 0;
    00196 }
    00197 static int hndays(int m,int y)
    00198 {
    00199   return jMonthDay[isJalaliLeap(y)][m];
    00200 }
    00201
    00202
    00203 KCalendarSystemJalali::KCalendarSystemJalali(const KLocale * locale)
    00204   : KCalendarSystem(locale)
    00205 {
    00206 }
    00207
    00208 KCalendarSystemJalali::~KCalendarSystemJalali()
    00209 {
    00210 }
    00211
    00212 int KCalendarSystemJalali::year(const QDate& date) const
    00213
    00214 {
    00215   kdDebug(5400) << "Jalali year..." <<  endl;
    00216 int y;
    00217   gregorianToJalali(date, &y, 0, 0);
    00218   return y;
    00219 }
    00220
    00221 int KCalendarSystemJalali::month (const QDate& date) const
    00222
    00223 {
    00224   kdDebug(5400) << "Jalali month..." <<  endl;
    00225 int m;
    00226   gregorianToJalali(date, 0 , &m, 0);
    00227   return m;
    00228 }
    00229
    00230 int KCalendarSystemJalali::day(const QDate& date) const
    00231
    00232 {
    00233   kdDebug(5400) << "Jalali day..." <<  endl;
    00234 int d;
    00235   gregorianToJalali(date, 0, 0, &d);
    00236   return d;
    00237 }
    00238
    00239 int KCalendarSystemJalali::dayOfWeek(const QDate& date) const
    00240 {
    00241 //same same I think?!
    00242   return date.dayOfWeek();
    00243
    00244 }
    00245
    00246 //NOT TESTED YET
    00247 int KCalendarSystemJalali::dayOfYear(const QDate & date) const
    00248 {
    00249   QDate first;
    00250   setYMD(first, year(date), 1, 1);
    00251
    00252   return first.daysTo(date) + 1;
    00253 }
    00254
    00255 //MAY BE BUGGY
    00256 bool KCalendarSystemJalali::setYMD(QDate & date, int y, int m, int d) const
    00257 {
    00258   // range checks
    00259   if ( y < minValidYear() || y > maxValidYear() )
    00260     return false;
    00261
    00262   if ( m < 1 || m > 12 )
    00263     return false;
    00264
    00265   if ( d < 1 || d > hndays(m, y) )
    00266     return false;
    00267
    00268   SDATE  *gd =jalaliToGregorian( y, m, d);
    00269
    00270   return date.setYMD(gd->year, gd->mon, gd->day);
    00271 }
    00272
    00273 QDate KCalendarSystemJalali::addYears( const QDate & date, int nyears ) const
    00274 {
    00275   QDate result = date;
    00276   int y = year(date) + nyears;
    00277   setYMD( result, y, month(date), day(date) );
    00278
    00279   return result;
    00280 }
    00281
    00282 QDate KCalendarSystemJalali::addMonths( const QDate & date, int nmonths ) const
    00283 {
    00284   QDate result = date;
    00285   int m = month(date);
    00286   int y = year(date);
    00287
    00288   if ( nmonths < 0 )
    00289   {
    00290     m += 12;
    00291     y -= 1;
    00292   }
    00293
    00294   --m; // this only works if we start counting at zero
    00295   m += nmonths;
    00296   y += m / 12;
    00297   m %= 12;
    00298   ++m;
    00299
    00300   setYMD( result, y, m, day(date) );
    00301
    00302   return result;
    00303 }
    00304
    00305 QDate KCalendarSystemJalali::addDays( const QDate & date, int ndays ) const
    00306 {
    00307   return date.addDays( ndays );
    00308 }
    00309
    00310 int KCalendarSystemJalali::monthsInYear( const QDate & date ) const
    00311 {
    00312   Q_UNUSED( date )
    00313
    00314   return 12;
    00315 }
    00316
    00317 int KCalendarSystemJalali::daysInYear(const QDate & date) const
    00318 {
    00319 Q_UNUSED(date);
    00320 int result;
    00321 //SDATE *sd = gregorianToJalali(year(date),month(date),day(date));
    00322 //if (isJalaliLeap(sd->year))
    00323     result=366;
    00324 //else
    00325 //  result=365;
    00326 return result;
    00327 }
    00328
    00329 int KCalendarSystemJalali::daysInMonth(const QDate & date) const
    00330 {
    00331 SDATE *sd = gregorianToJalali(date.year(),date.month(),date.day());
    00332 return hndays(sd->mon,sd->year);
    00333 }
    00334
    00335 int KCalendarSystemJalali::weeksInYear(int year) const
    00336
    00337 {
    00338   Q_UNUSED(year);
    00339 // couldn't understand it!
    00340 return 52;
    00341 }
    00342
    00343 int KCalendarSystemJalali::weekNumber(const QDate& date, int * yearNum) const
    00344 {
    00345   QDate firstDayWeek1, lastDayOfYear;
    00346   int y = year(date);
    00347   int week;
    00348   int weekDay1, dayOfWeek1InYear;
    00349
    00350   // let's guess 1st day of 1st week
    00351   setYMD(firstDayWeek1, y, 1, 1);
    00352   weekDay1 = dayOfWeek(firstDayWeek1);
    00353
    00354   // iso 8601: week 1  is the first containing thursday and week starts on
    00355   // monday
    00356   if (weekDay1 > 4 /*Thursday*/)
    00357     firstDayWeek1 = addDays(firstDayWeek1 , 7 - weekDay1 + 1); // next monday
    00358
    00359   dayOfWeek1InYear = dayOfYear(firstDayWeek1);
    00360
    00361   if ( dayOfYear(date) < dayOfWeek1InYear ) // our date in prev year's week
    00362   {
    00363     if ( yearNum )
    00364       *yearNum = y - 1;
    00365     return weeksInYear(y - 1);
    00366   }
    00367  // let' check if its last week belongs to next year
    00368   setYMD(lastDayOfYear, y, 12, hndays(12, y));
    00369   if ( (dayOfYear(date) >= daysInYear(date) - dayOfWeek(lastDayOfYear) + 1)
    00370        // our date is in last week
    00371        && dayOfWeek(lastDayOfYear) < 4) // 1st week in next year has thursday
    00372     {
    00373       if ( yearNum )
    00374         *yearNum = y + 1;
    00375       week = 1;
    00376     }
    00377   else
    00378     week = firstDayWeek1.daysTo(date) / 7 + 1;
    00379
    00380   return week;
    00381 }
    00382
    00383 QString KCalendarSystemJalali::monthName(int month, int year, bool shortName)
    00384   const
    00385 {
    00386   Q_UNUSED(year);
    00387
    00388   if (shortName)
    00389     switch ( month )
    00390       {
    00391       case 1:
    00392         return locale()->translate("Far");
    00393       case 2:
    00394         return locale()->translate("Ord");
    00395       case 3:
    00396         return locale()->translate("Kho");
    00397       case 4:
    00398         return locale()->translate("Tir");
    00399       case 5:
    00400         return locale()->translate("Mor");
    00401       case 6:
    00402         return locale()->translate("Sha");
    00403       case 7:
    00404         return locale()->translate("Meh");
    00405       case 8:
    00406         return locale()->translate("Aba");
    00407       case 9:
    00408         return locale()->translate("Aza");
    00409       case 10:
    00410         return locale()->translate("Dei");
    00411       case 11:
    00412         return locale()->translate("Bah");
    00413       case 12:
    00414         return locale()->translate("Esf");
    00415     }
    00416   else
    00417     switch ( month )
    00418       {
    00419       case 1:
    00420         return locale()->translate("Farvardin");
    00421       case 2:
    00422         return locale()->translate("Ordibehesht");
    00423       case 3:
    00424         return locale()->translate("Khordad");
    00425       case 4:
    00426         return locale()->translate("Tir");
    00427       case 5:
    00428         return locale()->translate("Mordad");
    00429       case 6:
    00430         return locale()->translate("Shahrivar");
    00431       case 7:
    00432         return locale()->translate("Mehr");
    00433       case 8:
    00434         return locale()->translate("Aban");
    00435       case 9:
    00436         return locale()->translate("Azar");
    00437       case 10:
    00438         return locale()->translate("Dei");
    00439       case 11:
    00440         return locale()->translate("Bahman");
    00441       case 12:
    00442         return locale()->translate("Esfand");
    00443       }
    00444
    00445   return QString::null;
    00446 }
    00447
    00448 QString KCalendarSystemJalali::monthName(const QDate& date, bool shortName)
    00449   const
    00450 {
    00451   int mon;
    00452   gregorianToJalali(date,0,&mon,0);
    00453   //SDATE *sd = gregorianToJalali(date.year(),date.month(),date.day());
    00454   return (monthName(mon, 0, shortName));
    00455 }
    00456
    00457 QString KCalendarSystemJalali::monthNamePossessive(const QDate& date,
    00458                                                      bool shortName  ) const
    00459 {
    00460   return monthName(date,shortName);
    00461 }
    00462
    00463 QString KCalendarSystemJalali::monthNamePossessive(int month, int year,
    00464                                                      bool shortName ) const
    00465 {
    00466   return monthName(month,year,shortName);
    00467 }
    00468
    00469
    00470 QString KCalendarSystemJalali::weekDayName(int day, bool shortName) const
    00471 {
    00472   if ( shortName )
    00473     switch (day)
    00474       {
    00475       case 1:
    00476         return locale()->translate("2sh");
    00477       case 2:
    00478         return locale()->translate("3sh");
    00479       case 3:
    00480         return locale()->translate("4sh");
    00481       case 4:
    00482         return locale()->translate("5sh");
    00483       case 5:
    00484         return locale()->translate("Jom");
    00485       case 6:
    00486         return locale()->translate("shn");
    00487       case 7:
    00488         return locale()->translate("1sh");
    00489       }
    00490   else
    00491     switch ( day )
    00492       {
    00493       case 1:
    00494         return locale()->translate("Do shanbe");
    00495       case 2:
    00496         return locale()->translate("Se shanbe");
    00497       case 3:
    00498         return locale()->translate("Chahar shanbe");
    00499       case 4:
    00500         return locale()->translate("Panj shanbe");
    00501       case 5:
    00502         return locale()->translate("Jumee");
    00503       case 6:
    00504         return locale()->translate("Shanbe");
    00505       case 7:
    00506         return locale()->translate("Yek-shanbe");
    00507       }
    00508
    00509   return QString::null;
    00510 }
    00511
    00512 QString KCalendarSystemJalali::weekDayName(const QDate &date,bool shortName)
    00513   const
    00514 {
    00515  return weekDayName(dayOfWeek(date), shortName);
    00516 }
    00517
    00518 // Min valid year that may be converted to QDate
    00519 int KCalendarSystemJalali::minValidYear() const
    00520 {
    00521   QDate date(1753, 1, 1);
    00522
    00523   return year(date);
    00524 }
    00525
    00526 // Max valid year that may be converted to QDate
    00527 int KCalendarSystemJalali::maxValidYear() const
    00528 {
    00529 /*
    00530   QDate date(8000, 1, 1);
    00531
    00532   SDATE *sd = toJalali(date);
    00533
    00534   return sd->year;
    00535   */
    00536   return 10000;
    00537 }
    00538 int KCalendarSystemJalali::weekDayOfPray() const
    00539 {
    00540   return 5; // friday
    00541 }
    00542 QString KCalendarSystemJalali::calendarName() const
    00543 {
    00544   return QString::fromLatin1("jalali");
    00545 }
    00546
    00547 bool KCalendarSystemJalali::isLunar() const
    00548 {
    00549   return false;
    00550 }
    00551
    00552 bool KCalendarSystemJalali::isLunisolar() const
    00553 {
    00554   return false;
    00555 }
    00556
    00557 bool KCalendarSystemJalali::isSolar() const
    00558 {
    00559   return true;
    00560 }

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:01 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003