All pastes #1330608 Raw Edit

calendar_persian

public text v1 · immutable
#1330608 ·published 2009-02-08 08:51 UTC
rendered paste body
/*************************************************************************
 *
 *  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 <math.h>
#include <stdio.h>

#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 <stdlib.h>
 
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;i<gm;++i)
      g_day_no += g_days_in_month[i];
   if (gm>1 && ((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<sal_Int16>(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 );
}
*/