summaryrefslogtreecommitdiffstats
path: root/kdecore/kcalendarsystemjalali.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdecore/kcalendarsystemjalali.cpp')
-rw-r--r--kdecore/kcalendarsystemjalali.cpp560
1 files changed, 560 insertions, 0 deletions
diff --git a/kdecore/kcalendarsystemjalali.cpp b/kdecore/kcalendarsystemjalali.cpp
new file mode 100644
index 000000000..df8b5d0fa
--- /dev/null
+++ b/kdecore/kcalendarsystemjalali.cpp
@@ -0,0 +1,560 @@
+/*
+ Copyright (C) 2002-2003 Arash Bijanzadeh and FarsiKDE Project <www.farsikde.org>
+ Contact: Arash Bijanzadeh <a.bijanzadeh@linuxiran.org>
+
+ This program is part of FarsiKDE
+
+ FarsiKDE is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ FarsiKDE is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+
+#include <qdatetime.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <math.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <stdio.h>
+
+#include "kcalendarsystemjalali.h"
+
+static const int gMonthDay[2][13]={
+ {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+ {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+};
+
+static const int jMonthDay[2][13] = {
+ {0, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29},
+ {0, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30},
+};
+
+typedef struct {
+ int day;
+ int mon;
+ int year;
+ } SDATE;
+// converting funcs from
+
+static int Ceil(float number)
+{
+ int ret;
+ if(number>0)
+ number += 0.5;
+ ret =(int) number;
+ return ret;
+}
+
+static long jalali_jdn(int year, int month, int day)
+{
+ const long PERSIAN_EPOCH = 1948321; /* The JDN of 1 Farvardin 1*/
+ int epbase;
+ long epyear;
+ long mdays;
+ long jdn;
+ epbase = year - 474;
+ epyear = 474 + (epbase % 2820);
+ if (month <= 7)
+ mdays = (month - 1) * 31;
+ else
+ mdays = (month - 1) * 30 + 6;
+ jdn = day + mdays ;
+ jdn += (((epyear * 682) - 110) / 2816) ;
+ jdn += (epyear - 1) * 365;
+ jdn += (epbase / 2820) * 1029983 ;
+ jdn += (PERSIAN_EPOCH - 1);
+ return jdn;
+}
+
+
+static SDATE jdn_jalali(long jdn)
+{
+ static SDATE ret;
+ int day, month, year;
+ int iYear, iMonth, iDay;
+ int depoch;
+ int cycle;
+ int cyear;
+ int ycycle;
+ int aux1, aux2;
+ int yday;
+ day = 1;
+ month = 1;
+ year = 475;
+ depoch = jdn - jalali_jdn(year,month, day);
+ cycle = (int) (depoch / 1029983);
+ cyear = depoch % 1029983;
+ if( cyear == 1029982)
+ ycycle = 2820;
+ else{
+ aux1 = cyear / 366;
+ aux2 = cyear % 366;
+ ycycle = (((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) + aux1 + 1;
+ }
+ iYear = ycycle + (2820 * cycle) + 474;
+ if (iYear <= 0)
+ iYear = iYear - 1;
+ year = iYear;
+ yday = (jdn - jalali_jdn(year, month, day)) + 1;
+ if(yday <= 186 )
+ iMonth = Ceil((yday-1) / 31);
+ else
+ iMonth = Ceil((yday - 7) / 30);
+ iMonth++;
+ month = iMonth;
+ iDay = (jdn - jalali_jdn(year, month, day)) + 1;
+ ret.day = iDay;
+ ret.mon = iMonth;
+ ret.year = iYear;
+ return ret;
+}
+
+
+
+static long civil_jdn(int year, int month, int day)
+{
+ long jdn = ((1461 * (year + 4800 + ((month - 14) / 12))) / 4)
+ + ((367 * (month - 2 - 12 * (((month - 14) / 12)))) / 12)
+ - ((3 * (((year + 4900 + ((month - 14) / 12)) / 100))) / 4)
+ + day - 32075;
+ return jdn;
+}
+
+static SDATE jdn_civil(long jdn)
+{
+ long l, n, i, j;
+ static SDATE ret;
+ int iday, imonth, iyear;
+ l = jdn + 68569;
+ n = ((4 * l) / 146097);
+ l = l - ((146097 * n + 3) / 4);
+ i = ((4000 * (l + 1)) / 1461001);
+ l = l - ((1461 * i) / 4) + 31;
+ j = ((80 * l) / 2447);
+ iday = l - ((2447 * j) / 80);
+ l = (j / 11);
+ imonth = j + 2 - 12 * l;
+ iyear = 100 * (n - 49) + i + l;
+ ret.day = iday;
+ ret.mon = imonth;
+ ret.year = iyear;
+ return (ret);
+}
+
+static SDATE *jalaliToGregorian(int y,int m,int d)
+{
+static SDATE sd;
+long jday = jalali_jdn(y,m,d);
+sd= jdn_civil(jday);
+return (&sd);
+}
+static SDATE *gregorianToJalali(int y,int m, int d)
+{
+ static SDATE sd;
+ long jdn = civil_jdn(y,m,d);//QDate::gregorianToJulian(y, m, d);
+ sd = jdn_jalali(jdn);
+ return(&sd);
+}
+static void gregorianToJalali(const QDate & date, int * pYear, int * pMonth,
+ int * pDay)
+{
+ SDATE *sd;
+ sd = gregorianToJalali(date.year(), date.month(), date.day());
+ if (pYear)
+ *pYear = sd->year;
+ if (pMonth)
+ *pMonth = sd->mon;
+ if (pDay)
+ *pDay = sd->day;
+
+}
+
+// End of converting functions
+
+static int isJalaliLeap(int year)
+{
+ int tmp;
+ tmp = year % 33;
+ if (tmp == 1 || tmp == 5||tmp==9||tmp==13||tmp==17||tmp==22||tmp==26||tmp==30)
+ return 1;
+else
+ return 0;
+}
+static int hndays(int m,int y)
+{
+ return jMonthDay[isJalaliLeap(y)][m];
+}
+
+
+KCalendarSystemJalali::KCalendarSystemJalali(const KLocale * locale)
+ : KCalendarSystem(locale)
+{
+}
+
+KCalendarSystemJalali::~KCalendarSystemJalali()
+{
+}
+
+int KCalendarSystemJalali::year(const QDate& date) const
+
+{
+ kdDebug(5400) << "Jalali year..." << endl;
+int y;
+ gregorianToJalali(date, &y, 0, 0);
+ return y;
+}
+
+int KCalendarSystemJalali::month (const QDate& date) const
+
+{
+ kdDebug(5400) << "Jalali month..." << endl;
+int m;
+ gregorianToJalali(date, 0 , &m, 0);
+ return m;
+}
+
+int KCalendarSystemJalali::day(const QDate& date) const
+
+{
+ kdDebug(5400) << "Jalali day..." << endl;
+int d;
+ gregorianToJalali(date, 0, 0, &d);
+ return d;
+}
+
+int KCalendarSystemJalali::dayOfWeek(const QDate& date) const
+{
+//same same I think?!
+ return date.dayOfWeek();
+
+}
+
+//NOT TESTED YET
+int KCalendarSystemJalali::dayOfYear(const QDate & date) const
+{
+ QDate first;
+ setYMD(first, year(date), 1, 1);
+
+ return first.daysTo(date) + 1;
+}
+
+//MAY BE BUGGY
+bool KCalendarSystemJalali::setYMD(QDate & date, int y, int m, int d) const
+{
+ // range checks
+ if ( y < minValidYear() || y > maxValidYear() )
+ return false;
+
+ if ( m < 1 || m > 12 )
+ return false;
+
+ if ( d < 1 || d > hndays(m, y) )
+ return false;
+
+ SDATE *gd =jalaliToGregorian( y, m, d);
+
+ return date.setYMD(gd->year, gd->mon, gd->day);
+}
+
+QDate KCalendarSystemJalali::addYears( const QDate & date, int nyears ) const
+{
+ QDate result = date;
+ int y = year(date) + nyears;
+ setYMD( result, y, month(date), day(date) );
+
+ return result;
+}
+
+QDate KCalendarSystemJalali::addMonths( const QDate & date, int nmonths ) const
+{
+ QDate result = date;
+ int m = month(date);
+ int y = year(date);
+
+ if ( nmonths < 0 )
+ {
+ m += 12;
+ y -= 1;
+ }
+
+ --m; // this only works if we start counting at zero
+ m += nmonths;
+ y += m / 12;
+ m %= 12;
+ ++m;
+
+ setYMD( result, y, m, day(date) );
+
+ return result;
+}
+
+QDate KCalendarSystemJalali::addDays( const QDate & date, int ndays ) const
+{
+ return date.addDays( ndays );
+}
+
+int KCalendarSystemJalali::monthsInYear( const QDate & date ) const
+{
+ Q_UNUSED( date )
+
+ return 12;
+}
+
+int KCalendarSystemJalali::daysInYear(const QDate & date) const
+{
+Q_UNUSED(date);
+int result;
+//SDATE *sd = gregorianToJalali(year(date),month(date),day(date));
+//if (isJalaliLeap(sd->year))
+ result=366;
+//else
+// result=365;
+return result;
+}
+
+int KCalendarSystemJalali::daysInMonth(const QDate & date) const
+{
+SDATE *sd = gregorianToJalali(date.year(),date.month(),date.day());
+return hndays(sd->mon,sd->year);
+}
+
+int KCalendarSystemJalali::weeksInYear(int year) const
+
+{
+ Q_UNUSED(year);
+// couldn't understand it!
+return 52;
+}
+
+int KCalendarSystemJalali::weekNumber(const QDate& date, int * yearNum) const
+{
+ QDate firstDayWeek1, lastDayOfYear;
+ int y = year(date);
+ int week;
+ int weekDay1, dayOfWeek1InYear;
+
+ // let's guess 1st day of 1st week
+ setYMD(firstDayWeek1, y, 1, 1);
+ weekDay1 = dayOfWeek(firstDayWeek1);
+
+ // iso 8601: week 1 is the first containing thursday and week starts on
+ // monday
+ if (weekDay1 > 4 /*Thursday*/)
+ firstDayWeek1 = addDays(firstDayWeek1 , 7 - weekDay1 + 1); // next monday
+
+ dayOfWeek1InYear = dayOfYear(firstDayWeek1);
+
+ if ( dayOfYear(date) < dayOfWeek1InYear ) // our date in prev year's week
+ {
+ if ( yearNum )
+ *yearNum = y - 1;
+ return weeksInYear(y - 1);
+ }
+ // let' check if its last week belongs to next year
+ setYMD(lastDayOfYear, y, 12, hndays(12, y));
+ if ( (dayOfYear(date) >= daysInYear(date) - dayOfWeek(lastDayOfYear) + 1)
+ // our date is in last week
+ && dayOfWeek(lastDayOfYear) < 4) // 1st week in next year has thursday
+ {
+ if ( yearNum )
+ *yearNum = y + 1;
+ week = 1;
+ }
+ else
+ week = firstDayWeek1.daysTo(date) / 7 + 1;
+
+ return week;
+}
+
+QString KCalendarSystemJalali::monthName(int month, int year, bool shortName)
+ const
+{
+ Q_UNUSED(year);
+
+ if (shortName)
+ switch ( month )
+ {
+ case 1:
+ return locale()->translate("Far");
+ case 2:
+ return locale()->translate("Ord");
+ case 3:
+ return locale()->translate("Kho");
+ case 4:
+ return locale()->translate("Tir");
+ case 5:
+ return locale()->translate("Mor");
+ case 6:
+ return locale()->translate("Sha");
+ case 7:
+ return locale()->translate("Meh");
+ case 8:
+ return locale()->translate("Aba");
+ case 9:
+ return locale()->translate("Aza");
+ case 10:
+ return locale()->translate("Dei");
+ case 11:
+ return locale()->translate("Bah");
+ case 12:
+ return locale()->translate("Esf");
+ }
+ else
+ switch ( month )
+ {
+ case 1:
+ return locale()->translate("Farvardin");
+ case 2:
+ return locale()->translate("Ordibehesht");
+ case 3:
+ return locale()->translate("Khordad");
+ case 4:
+ return locale()->translate("Tir");
+ case 5:
+ return locale()->translate("Mordad");
+ case 6:
+ return locale()->translate("Shahrivar");
+ case 7:
+ return locale()->translate("Mehr");
+ case 8:
+ return locale()->translate("Aban");
+ case 9:
+ return locale()->translate("Azar");
+ case 10:
+ return locale()->translate("Dei");
+ case 11:
+ return locale()->translate("Bahman");
+ case 12:
+ return locale()->translate("Esfand");
+ }
+
+ return QString::null;
+}
+
+QString KCalendarSystemJalali::monthName(const QDate& date, bool shortName)
+ const
+{
+ int mon;
+ gregorianToJalali(date,0,&mon,0);
+ //SDATE *sd = gregorianToJalali(date.year(),date.month(),date.day());
+ return (monthName(mon, 0, shortName));
+}
+
+QString KCalendarSystemJalali::monthNamePossessive(const QDate& date,
+ bool shortName ) const
+{
+ return monthName(date,shortName);
+}
+
+QString KCalendarSystemJalali::monthNamePossessive(int month, int year,
+ bool shortName ) const
+{
+ return monthName(month,year,shortName);
+}
+
+
+QString KCalendarSystemJalali::weekDayName(int day, bool shortName) const
+{
+ if ( shortName )
+ switch (day)
+ {
+ case 1:
+ return locale()->translate("2sh");
+ case 2:
+ return locale()->translate("3sh");
+ case 3:
+ return locale()->translate("4sh");
+ case 4:
+ return locale()->translate("5sh");
+ case 5:
+ return locale()->translate("Jom");
+ case 6:
+ return locale()->translate("shn");
+ case 7:
+ return locale()->translate("1sh");
+ }
+ else
+ switch ( day )
+ {
+ case 1:
+ return locale()->translate("Do shanbe");
+ case 2:
+ return locale()->translate("Se shanbe");
+ case 3:
+ return locale()->translate("Chahar shanbe");
+ case 4:
+ return locale()->translate("Panj shanbe");
+ case 5:
+ return locale()->translate("Jumee");
+ case 6:
+ return locale()->translate("Shanbe");
+ case 7:
+ return locale()->translate("Yek-shanbe");
+ }
+
+ return QString::null;
+}
+
+QString KCalendarSystemJalali::weekDayName(const QDate &date,bool shortName)
+ const
+{
+ return weekDayName(dayOfWeek(date), shortName);
+}
+
+// Min valid year that may be converted to QDate
+int KCalendarSystemJalali::minValidYear() const
+{
+ QDate date(1753, 1, 1);
+
+ return year(date);
+}
+
+// Max valid year that may be converted to QDate
+int KCalendarSystemJalali::maxValidYear() const
+{
+/*
+ QDate date(8000, 1, 1);
+
+ SDATE *sd = toJalali(date);
+
+ return sd->year;
+ */
+ return 10000;
+}
+int KCalendarSystemJalali::weekDayOfPray() const
+{
+ return 5; // friday
+}
+QString KCalendarSystemJalali::calendarName() const
+{
+ return QString::fromLatin1("jalali");
+}
+
+bool KCalendarSystemJalali::isLunar() const
+{
+ return false;
+}
+
+bool KCalendarSystemJalali::isLunisolar() const
+{
+ return false;
+}
+
+bool KCalendarSystemJalali::isSolar() const
+{
+ return true;
+}