/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: calendar_jewish.cxx,v $ * * $Revision: 1.11 $ * * last change: $Author: obo $ $Date: 2006/09/17 09:15:38 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_i18npool.hxx" #include #include #include "calendar_persian.hxx" using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::i18n; using namespace ::rtl; #define ERROR RuntimeException() /* prototypes */ void gregorian_to_jalali(/* output */ int *j_y, int *j_m, int *j_d, /* input */ int g_y, int g_m, int g_d); void jalali_to_gregorian(/* output */ int *g_y, int *g_m, int *g_d, /* input */ int j_y, int j_m, int j_d); /* implementation */ #include int g_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int j_days_in_month[12] = {31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29}; /*const char *j_month_name[13] = {"", "Farvardin", "Ordibehesht", "Khordad", "Tir", "Mordad", "Shahrivar", "Mehr", "Aban", "Azar", "Dey", "Bahman", "Esfand"}; */ void gregorian_to_jalali(int *j_y, int *j_m, int *j_d, int g_y, int g_m, int g_d) { int gy, gm, gd; int jy, jm, jd; long g_day_no, j_day_no; int j_np; int i; gy = g_y-1600; gm = g_m-1; gd = g_d-1; g_day_no = 365*gy+(gy+3)/4-(gy+99)/100+(gy+399)/400; for (i=0;i1 && ((gy%4==0 && gy%100!=0) || (gy%400==0))) /* leap and after Feb */ ++g_day_no; g_day_no += gd; j_day_no = g_day_no-79; j_np = j_day_no / 12053; j_day_no %= 12053; jy = 979+33*j_np+4*(j_day_no/1461); j_day_no %= 1461; if (j_day_no >= 366) { jy += (j_day_no-1)/365; j_day_no = (j_day_no-1)%365; } for (i = 0; i < 11 && j_day_no >= j_days_in_month[i]; ++i) { j_day_no -= j_days_in_month[i]; } jm = i+1; jd = j_day_no+1; *j_y = jy; *j_m = jm; *j_d = jd; } void jalali_to_gregorian(int *g_y, int *g_m, int *g_d, int j_y, int j_m, int j_d) { int gy, gm, gd; int jy, jm, jd; long g_day_no, j_day_no; int leap; int i; jy = j_y-979; jm = j_m-1; jd = j_d-1; j_day_no = 365*jy + (jy/33)*8 + (jy%33+3)/4; for (i=0; i < jm; ++i) j_day_no += j_days_in_month[i]; j_day_no += jd; g_day_no = j_day_no+79; gy = 1600 + 400*(g_day_no/146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */ g_day_no = g_day_no % 146097; leap = 1; if (g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */ { g_day_no--; gy += 100*(g_day_no/36524); /* 36524 = 365*100 + 100/4 - 100/100 */ g_day_no = g_day_no % 36524; if (g_day_no >= 365) g_day_no++; else leap = 0; } gy += 4*(g_day_no/1461); /* 1461 = 365*4 + 4/4 */ g_day_no %= 1461; if (g_day_no >= 366) { leap = 0; g_day_no--; gy += g_day_no/365; g_day_no = g_day_no % 365; } for (i = 0; g_day_no >= g_days_in_month[i] + (i == 1 && leap); i++) g_day_no -= g_days_in_month[i] + (i == 1 && leap); gm = i+1; gd = g_day_no+1; *g_y = gy; *g_m = gm; *g_d = gd; } // not used //static UErrorCode status; // status is shared in all calls to Calendar, it has to be reset for each call. Calendar_Persian::Calendar_Persian() { cCalendar = "com.sun.star.i18n.Calendar_Persian"; } // map field value from gregorian calendar to other calendar, it can be overwritten by derived class. void SAL_CALL Calendar_Persian::mapFromGregorian() throw(RuntimeException) { int y = fieldValue[CalendarFieldIndex::YEAR]; if (fieldValue[CalendarFieldIndex::ERA] == 0) y = 1 - y; int j_y = 0, j_m = 0, j_d = 0; gregorian_to_jalali(&j_y, &j_m, &j_d, y, fieldValue[CalendarFieldIndex::MONTH] + 1, fieldValue[CalendarFieldIndex::DAY_OF_MONTH]); fieldValue[CalendarFieldIndex::ERA] = j_y <= 0 ? 0 : 1; fieldValue[CalendarFieldIndex::MONTH] = j_m - 1; fieldValue[CalendarFieldIndex::DAY_OF_MONTH] = j_d; fieldValue[CalendarFieldIndex::YEAR] = (j_y <= 0 ? 1 - j_y : j_y); } #define FIELDS ((1 << CalendarFieldIndex::ERA) | (1 << CalendarFieldIndex::YEAR) | (1 << CalendarFieldIndex::MONTH) | (1 << CalendarFieldIndex::DAY_OF_MONTH)) // map field value from other calendar to gregorian calendar, it should be implemented. void SAL_CALL Calendar_Persian::mapToGregorian() throw(RuntimeException) { int g_y, g_m, g_d; if (fieldSet & FIELDS) { sal_Int32 day = (sal_Int32)fieldSetValue[CalendarFieldIndex::DAY_OF_MONTH]; sal_Int32 month = (sal_Int32)fieldSetValue[CalendarFieldIndex::MONTH] + 1; sal_Int32 year = (sal_Int32)fieldSetValue[CalendarFieldIndex::YEAR]; if (fieldSetValue[CalendarFieldIndex::ERA] == 0) year *= -1; jalali_to_gregorian(&g_y, &g_m, &g_d, year, month, day); fieldSetValue[CalendarFieldIndex::ERA] = g_y <= 0 ? 0 : 1; fieldSetValue[CalendarFieldIndex::MONTH] = sal::static_int_cast(g_m - 1); fieldSetValue[CalendarFieldIndex::DAY_OF_MONTH] = (sal_Int16) g_d; fieldSetValue[CalendarFieldIndex::YEAR] = (sal_Int16) abs(g_y); fieldSet |= FIELDS; } } /* // Methods in XExtendedCalendar OUString SAL_CALL Calendar_Persian::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode ) throw (RuntimeException) { nNativeNumberMode = NativeNumberMode::NATNUM2; // make Hebrew number for Jewish calendar if (nCalendarDisplayCode == CalendarDisplayCode::SHORT_YEAR) { sal_Int32 value = getValue(CalendarFieldIndex::YEAR) % 1000; // take last 3 digits return aNatNum.getNativeNumberString(OUString::valueOf(value), aLocale, nNativeNumberMode ); } else return Calendar_gregorian::getDisplayString(nCalendarDisplayCode, nNativeNumberMode ); } */