Line 0
Link Here
|
|
|
1 |
/************************************************************************* |
2 |
* |
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
5 |
* Copyright 2008 by Sun Microsystems, Inc. |
6 |
* |
7 |
* OpenOffice.org - a multi-platform office productivity suite |
8 |
* |
9 |
* $RCSfile: calendar_persian.cxx,v $ |
10 |
* $Revision: 0.0 $ |
11 |
* |
12 |
* This file is part of OpenOffice.org. |
13 |
* |
14 |
* OpenOffice.org is free software: you can redistribute it and/or modify |
15 |
* it under the terms of the GNU Lesser General Public License version 3 |
16 |
* only, as published by the Free Software Foundation. |
17 |
* |
18 |
* OpenOffice.org is distributed in the hope that it will be useful, |
19 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 |
* GNU Lesser General Public License version 3 for more details |
22 |
* (a copy is included in the LICENSE file that accompanied this code). |
23 |
* |
24 |
* You should have received a copy of the GNU Lesser General Public License |
25 |
* version 3 along with OpenOffice.org. If not, see |
26 |
* <http://www.openoffice.org/license.html> |
27 |
* for a copy of the LGPLv3 License. |
28 |
* |
29 |
************************************************************************/ |
30 |
// MARKER(update_precomp.py): autogen include statement, do not remove |
31 |
#include "precompiled_i18npool.hxx" |
32 |
|
33 |
#include <math.h> |
34 |
#include <stdio.h> |
35 |
|
36 |
#include "calendar_persian.hxx" |
37 |
|
38 |
using namespace ::com::sun::star::uno; |
39 |
using namespace ::com::sun::star::lang; |
40 |
using namespace ::com::sun::star::i18n; |
41 |
using namespace ::rtl; |
42 |
|
43 |
#define ERROR RuntimeException() |
44 |
|
45 |
/* |
46 |
* The conversion routines used here, are from http://www.farsiweb.info/jalali/jalali.c |
47 |
*/ |
48 |
/* prototypes */ |
49 |
|
50 |
void gregorian_to_jalali(/* output */ sal_Int32 *j_y, sal_Int32 *j_m, sal_Int32 *j_d, |
51 |
/* input */ sal_Int32 g_y, sal_Int32 g_m, sal_Int32 g_d); |
52 |
void jalali_to_gregorian(/* output */ sal_Int32 *g_y, sal_Int32 *g_m, sal_Int32 *g_d, |
53 |
/* input */ sal_Int32 j_y, sal_Int32 j_m, sal_Int32 j_d); |
54 |
|
55 |
/* implementation */ |
56 |
|
57 |
#include <stdlib.h> |
58 |
|
59 |
sal_Int32 g_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
60 |
sal_Int32 j_days_in_month[12] = {31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29}; |
61 |
|
62 |
void gregorian_to_jalali(sal_Int32 *j_y, sal_Int32 *j_m, sal_Int32 *j_d, |
63 |
sal_Int32 g_y, sal_Int32 g_m, sal_Int32 g_d) |
64 |
{ |
65 |
sal_Int32 gy, gm, gd; |
66 |
sal_Int32 jy, jm, jd; |
67 |
long g_day_no, j_day_no; |
68 |
sal_Int32 j_np; |
69 |
|
70 |
sal_Int32 i; |
71 |
|
72 |
gy = g_y-1600; |
73 |
gm = g_m-1; |
74 |
gd = g_d-1; |
75 |
|
76 |
g_day_no = 365*gy+(gy+3)/4-(gy+99)/100+(gy+399)/400; |
77 |
for (i=0;i<gm;++i) |
78 |
g_day_no += g_days_in_month[i]; |
79 |
if (gm>1 && ((gy%4==0 && gy%100!=0) || (gy%400==0))) |
80 |
/* leap and after Feb */ |
81 |
++g_day_no; |
82 |
g_day_no += gd; |
83 |
|
84 |
j_day_no = g_day_no-79; |
85 |
|
86 |
j_np = j_day_no / 12053; |
87 |
j_day_no %= 12053; |
88 |
|
89 |
jy = 979+33*j_np+4*(j_day_no/1461); |
90 |
j_day_no %= 1461; |
91 |
|
92 |
if (j_day_no >= 366) { |
93 |
jy += (j_day_no-1)/365; |
94 |
j_day_no = (j_day_no-1)%365; |
95 |
} |
96 |
|
97 |
for (i = 0; i < 11 && j_day_no >= j_days_in_month[i]; ++i) { |
98 |
j_day_no -= j_days_in_month[i]; |
99 |
} |
100 |
jm = i+1; |
101 |
jd = j_day_no+1; |
102 |
*j_y = jy; |
103 |
*j_m = jm; |
104 |
*j_d = jd; |
105 |
} |
106 |
|
107 |
void jalali_to_gregorian(sal_Int32 *g_y, sal_Int32 *g_m, sal_Int32 *g_d, |
108 |
sal_Int32 j_y, sal_Int32 j_m, sal_Int32 j_d) |
109 |
{ |
110 |
sal_Int32 gy, gm, gd; |
111 |
sal_Int32 jy, jm, jd; |
112 |
long g_day_no, j_day_no; |
113 |
sal_Int32 leap; |
114 |
|
115 |
sal_Int32 i; |
116 |
|
117 |
jy = j_y-979; |
118 |
jm = j_m-1; |
119 |
jd = j_d-1; |
120 |
|
121 |
j_day_no = 365*jy + (jy/33)*8 + (jy%33+3)/4; |
122 |
for (i=0; i < jm; ++i) |
123 |
j_day_no += j_days_in_month[i]; |
124 |
|
125 |
j_day_no += jd; |
126 |
|
127 |
g_day_no = j_day_no+79; |
128 |
|
129 |
gy = 1600 + 400*(g_day_no/146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */ |
130 |
g_day_no = g_day_no % 146097; |
131 |
|
132 |
leap = 1; |
133 |
if (g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */ |
134 |
{ |
135 |
g_day_no--; |
136 |
gy += 100*(g_day_no/36524); /* 36524 = 365*100 + 100/4 - 100/100 */ |
137 |
g_day_no = g_day_no % 36524; |
138 |
|
139 |
if (g_day_no >= 365) |
140 |
g_day_no++; |
141 |
else |
142 |
leap = 0; |
143 |
} |
144 |
|
145 |
gy += 4*(g_day_no/1461); /* 1461 = 365*4 + 4/4 */ |
146 |
g_day_no %= 1461; |
147 |
|
148 |
if (g_day_no >= 366) { |
149 |
leap = 0; |
150 |
|
151 |
g_day_no--; |
152 |
gy += g_day_no/365; |
153 |
g_day_no = g_day_no % 365; |
154 |
} |
155 |
|
156 |
for (i = 0; g_day_no >= g_days_in_month[i] + (i == 1 && leap); i++) |
157 |
g_day_no -= g_days_in_month[i] + (i == 1 && leap); |
158 |
gm = i+1; |
159 |
gd = g_day_no+1; |
160 |
|
161 |
*g_y = gy; |
162 |
*g_m = gm; |
163 |
*g_d = gd; |
164 |
} |
165 |
|
166 |
|
167 |
// not used |
168 |
//static UErrorCode status; // status is shared in all calls to Calendar, it has to be reset for each call. |
169 |
|
170 |
Calendar_persian::Calendar_persian() |
171 |
{ |
172 |
cCalendar = "com.sun.star.i18n.Calendar_persian"; |
173 |
} |
174 |
|
175 |
|
176 |
|
177 |
|
178 |
// map field value from gregorian calendar to other calendar, it can be overwritten by derived class. |
179 |
void SAL_CALL Calendar_persian::mapFromGregorian() throw(RuntimeException) |
180 |
{ |
181 |
sal_Int32 month, day, year; |
182 |
|
183 |
day = fieldValue[CalendarFieldIndex::DAY_OF_MONTH]; |
184 |
month = fieldValue[CalendarFieldIndex::MONTH] + 1; |
185 |
year = fieldValue[CalendarFieldIndex::YEAR]; |
186 |
if (fieldValue[CalendarFieldIndex::ERA] == 0) |
187 |
year *= -1; |
188 |
|
189 |
sal_Int32 j_y = 0, j_m = 0, j_d = 0; |
190 |
gregorian_to_jalali(&j_y, &j_m, &j_d, year, month, day); |
191 |
|
192 |
fieldValue[CalendarFieldIndex::ERA] = (sal_Int16) j_y <= 0 ? 0 : 1; |
193 |
fieldValue[CalendarFieldIndex::MONTH] = sal::static_int_cast<sal_Int16> (j_m - 1); |
194 |
fieldValue[CalendarFieldIndex::DAY_OF_MONTH] = (sal_Int16) j_d; |
195 |
fieldValue[CalendarFieldIndex::YEAR] = (sal_Int16) abs(j_y); |
196 |
} |
197 |
|
198 |
#define FIELDS ((1 << CalendarFieldIndex::ERA) | (1 << CalendarFieldIndex::YEAR) | (1 << CalendarFieldIndex::MONTH) | (1 << CalendarFieldIndex::DAY_OF_MONTH)) |
199 |
// map field value from other calendar to gregorian calendar, it should be implemented. |
200 |
void SAL_CALL Calendar_persian::mapToGregorian() throw(RuntimeException) |
201 |
{ |
202 |
sal_Int32 g_y, g_m, g_d; |
203 |
if (fieldSet & FIELDS) { |
204 |
sal_Int32 day = fieldSetValue[CalendarFieldIndex::DAY_OF_MONTH]; |
205 |
sal_Int32 month = fieldSetValue[CalendarFieldIndex::MONTH] + 1; |
206 |
sal_Int32 year = fieldSetValue[CalendarFieldIndex::YEAR]; |
207 |
if (fieldSetValue[CalendarFieldIndex::ERA] == 0) |
208 |
year *= -1; |
209 |
|
210 |
jalali_to_gregorian(&g_y, &g_m, &g_d, year, month, day); |
211 |
|
212 |
fieldSetValue[CalendarFieldIndex::ERA] = g_y <= 0 ? 0 : 1; |
213 |
fieldSetValue[CalendarFieldIndex::MONTH] = sal::static_int_cast<sal_Int16>(g_m - 1); |
214 |
fieldSetValue[CalendarFieldIndex::DAY_OF_MONTH] = (sal_Int16) g_d; |
215 |
fieldSetValue[CalendarFieldIndex::YEAR] = (sal_Int16) abs(g_y); |
216 |
fieldSet |= FIELDS; |
217 |
} |
218 |
} |
219 |
/* |
220 |
// Methods in XExtendedCalendar |
221 |
OUString SAL_CALL |
222 |
Calendar_persian::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode ) |
223 |
throw (RuntimeException) |
224 |
{ |
225 |
nNativeNumberMode = NativeNumberMode::NATNUM2; // make Hebrew number for Jewish calendar |
226 |
|
227 |
if (nCalendarDisplayCode == CalendarDisplayCode::SHORT_YEAR) { |
228 |
sal_Int32 value = getValue(CalendarFieldIndex::YEAR) % 1000; // take last 3 digits |
229 |
return aNatNum.getNativeNumberString(OUString::valueOf(value), aLocale, nNativeNumberMode ); |
230 |
} |
231 |
else |
232 |
return Calendar_gregorian::getDisplayString(nCalendarDisplayCode, nNativeNumberMode ); |
233 |
} |
234 |
*/ |
235 |
|
236 |
|
237 |
|