GnmFunc: make this a GObject.
[gnumeric.git] / plugins / fn-hebrew-date / functions.c
blob13e75a22253279aecf82c387fb4b6b60fb96bbb2
1 /*
2 * fn-hebrew-date.c: Built in hebrew date functions.
4 * Author:
5 * Yaacov Zamir <kzamir@walla.co.il>
7 * Based on Date functions by:
8 * Miguel de Icaza (miguel@gnu.org)
9 * Jukka-Pekka Iivonen (iivonen@iki.fi)
10 * Morten Welinder <terra@diku.dk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses/>.
25 #include <gnumeric-config.h>
26 #include <gnumeric.h>
27 #include <gnm-i18n.h>
28 #include <func.h>
29 #include <value.h>
31 #include <parse-util.h>
32 #include <cell.h>
33 #include <value.h>
34 #include <mathfunc.h>
35 #include <workbook.h>
36 #include <sheet.h>
37 #include <gnm-datetime.h>
39 #include <math.h>
41 #include <glib.h>
42 #include "hdate.h"
43 #include <goffice/goffice.h>
44 #include <gnm-plugin.h>
46 GNM_PLUGIN_MODULE_HEADER;
48 #define DATE_CONV(ep) sheet_date_conv ((ep)->sheet)
49 #define UNICODE_MONTH_PREFIX "\xd7\x91\xd6\xbc\xd6\xb0"
51 static void
52 gnumeric_hdate_get_date (GnmValue const * const *arg, int *year, int *month, int *day)
54 GDate date;
56 if (arg[0] == NULL || arg[1] == NULL || arg[2] == NULL)
57 g_date_set_time_t (&date, time (NULL));
59 *year = (arg[0]) ? value_get_as_int (arg[0])
60 : g_date_get_year (&date);
61 *month = (arg[1]) ? value_get_as_int (arg[1]) :
62 (int)g_date_get_month (&date);
63 *day = (arg[2]) ? value_get_as_int (arg[2]) :
64 g_date_get_day (&date);
66 return;
69 static GnmValue *
70 gnumeric_date_get_date (GnmFuncEvalInfo * ei, GnmValue const * const val,
71 int *year, int *month, int *day)
73 GDate date;
75 if (val == NULL)
76 g_date_set_time_t (&date, time (NULL));
77 else if (!datetime_value_to_g (&date, val, DATE_CONV (ei->pos)))
78 return value_new_error_NUM (ei->pos);
80 *year = g_date_get_year (&date);
81 *month = g_date_get_month (&date);
82 *day = g_date_get_day (&date);
84 return NULL;
87 /***************************************************************************/
89 static GnmFuncHelp const help_hdate[] = {
90 { GNM_FUNC_HELP_NAME, F_("HDATE:Hebrew date") },
91 { GNM_FUNC_HELP_ARG, F_("year:Gregorian year of date, defaults to the current year")},
92 { GNM_FUNC_HELP_ARG, F_("month:Gregorian month of year, defaults to the current month")},
93 { GNM_FUNC_HELP_ARG, F_("day:Gregorian day of month, defaults to the current day")},
94 { GNM_FUNC_HELP_EXAMPLES, "=HDATE(2001,3,30)" },
95 { GNM_FUNC_HELP_EXAMPLES, "=HDATE()" },
96 { GNM_FUNC_HELP_SEEALSO, "HDATE_HEB,DATE"},
97 { GNM_FUNC_HELP_END }
100 static GnmValue *
101 gnumeric_hdate (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
103 int year, month, day;
104 int hyear, hmonth, hday;
105 char *res;
107 gnumeric_hdate_get_date (argv, &year, &month, &day);
109 if (0 != hdate_gdate_to_hdate (day, month, year, &hday, &hmonth, &hyear))
110 return value_new_error_VALUE (ei->pos);
112 res = g_strdup_printf ("%d %s %d",
113 hday + 1,
114 hdate_get_hebrew_month_name (hmonth),
115 hyear);
117 return value_new_string_nocopy (res);
120 /***************************************************************************/
124 static GnmFuncHelp const help_date2hdate[] = {
125 { GNM_FUNC_HELP_NAME, F_("DATE2HDATE:Hebrew date") },
126 { GNM_FUNC_HELP_ARG, F_("date:Gregorian date, defaults to today")},
127 { GNM_FUNC_HELP_EXAMPLES, "=DATE2HDATE(DATE(2001,3,30))" },
128 { GNM_FUNC_HELP_EXAMPLES, "=DATE2HDATE()" },
129 { GNM_FUNC_HELP_SEEALSO, "HDATE,DATE2HDATE_HEB"},
130 { GNM_FUNC_HELP_END }
133 static GnmValue *
134 gnumeric_date2hdate (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
136 int year, month, day;
137 int hyear, hmonth, hday;
138 char *res;
139 GnmValue *val;
141 val = gnumeric_date_get_date (ei,argv[0], &year, &month, &day);
142 if (val != NULL)
143 return val;
145 if (0 != hdate_gdate_to_hdate (day, month, year, &hday, &hmonth, &hyear))
146 return value_new_error_VALUE (ei->pos);
148 res = g_strdup_printf ("%d %s %d",
149 hday + 1,
150 hdate_get_hebrew_month_name (hmonth),
151 hyear);
153 return value_new_string_nocopy (res);
156 /***************************************************************************/
158 static GnmFuncHelp const help_hdate_heb[] = {
159 { GNM_FUNC_HELP_NAME, F_("HDATE_HEB:Hebrew date in Hebrew") },
160 { GNM_FUNC_HELP_ARG, F_("year:Gregorian year of date, defaults to the current year")},
161 { GNM_FUNC_HELP_ARG, F_("month:Gregorian month of year, defaults to the current month")},
162 { GNM_FUNC_HELP_ARG, F_("day:Gregorian day of month, defaults to the current day")},
163 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_HEB(2001,3,30)" },
164 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_HEB()" },
165 { GNM_FUNC_HELP_SEEALSO, "HDATE,DATE"},
166 { GNM_FUNC_HELP_END }
169 static void
170 build_hdate (GString *res, int hyear, int hmonth, int hday)
172 hdate_int_to_hebrew (res, hday + 1);
173 g_string_append (res, " " UNICODE_MONTH_PREFIX);
174 g_string_append (res, hdate_get_hebrew_month_name_heb (hmonth));
175 g_string_append_c (res, ' ');
176 hdate_int_to_hebrew (res, hyear);
179 static GnmValue *
180 gnumeric_hdate_heb (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
182 int year, month, day;
183 int hyear, hmonth, hday;
184 GString *res;
186 gnumeric_hdate_get_date (argv, &year, &month, &day);
188 if (0 != hdate_gdate_to_hdate (day, month, year, &hday, &hmonth, &hyear))
189 return value_new_error_VALUE (ei->pos);
191 res = g_string_new (NULL);
192 build_hdate (res, hyear, hmonth, hday);
194 return value_new_string_nocopy (g_string_free (res, FALSE));
197 /***************************************************************************/
199 static GnmFuncHelp const help_date2hdate_heb[] = {
200 { GNM_FUNC_HELP_NAME, F_("DATE2HDATE_HEB:Hebrew date in Hebrew") },
201 { GNM_FUNC_HELP_ARG, F_("date:Gregorian date, defaults to today")},
202 { GNM_FUNC_HELP_EXAMPLES, "=DATE2HDATE_HEB(DATE(2001,3,30))" },
203 { GNM_FUNC_HELP_EXAMPLES, "=DATE2HDATE_HEB()" },
204 { GNM_FUNC_HELP_SEEALSO, "DATE2HDATE,HDATE_HEB"},
205 { GNM_FUNC_HELP_END }
208 static GnmValue *
209 gnumeric_date2hdate_heb (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
211 int year, month, day;
212 int hyear, hmonth, hday;
213 GString *res;
214 GnmValue *val;
216 val = gnumeric_date_get_date (ei,argv[0], &year, &month, &day);
217 if (val != NULL)
218 return val;
220 if (0 != hdate_gdate_to_hdate (day, month, year, &hday, &hmonth, &hyear))
221 return value_new_error_VALUE (ei->pos);
223 res = g_string_new (NULL);
224 build_hdate (res, hyear, hmonth, hday);
226 return value_new_string_nocopy (g_string_free (res, FALSE));
229 /***************************************************************************/
231 static GnmFuncHelp const help_hdate_month[] = {
232 { GNM_FUNC_HELP_NAME, F_("HDATE_MONTH:Hebrew month of Gregorian date") },
233 { GNM_FUNC_HELP_ARG, F_("year:Gregorian year of date, defaults to the current year")},
234 { GNM_FUNC_HELP_ARG, F_("month:Gregorian month of year, defaults to the current month")},
235 { GNM_FUNC_HELP_ARG, F_("day:Gregorian day of month, defaults to the current day")},
236 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_MONTH(2001,3,30)" },
237 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_MONTH()" },
238 { GNM_FUNC_HELP_SEEALSO, "HDATE_JULIAN"},
239 { GNM_FUNC_HELP_END }
242 static GnmValue *
243 gnumeric_hdate_month (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
245 int year, month, day;
246 int hyear, hmonth, hday;
248 gnumeric_hdate_get_date (argv, &year, &month, &day);
250 if (0 != hdate_gdate_to_hdate (day, month, year, &hday, &hmonth, &hyear))
251 return value_new_error_VALUE (ei->pos);
253 return value_new_int (hmonth);
256 /***************************************************************************/
258 static GnmFuncHelp const help_hdate_day[] = {
259 { GNM_FUNC_HELP_NAME, F_("HDATE_DAY:Hebrew day of Gregorian date") },
260 { GNM_FUNC_HELP_ARG, F_("year:Gregorian year of date, defaults to the current year")},
261 { GNM_FUNC_HELP_ARG, F_("month:Gregorian month of year, defaults to the current month")},
262 { GNM_FUNC_HELP_ARG, F_("day:Gregorian day of month, defaults to the current day")},
263 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_DAY(2001,3,30)" },
264 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_DAY()" },
265 { GNM_FUNC_HELP_SEEALSO, "HDATE_JULIAN"},
266 { GNM_FUNC_HELP_END }
269 static GnmValue *
270 gnumeric_hdate_day (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
272 int year, month, day;
273 int hyear, hmonth, hday;
275 gnumeric_hdate_get_date (argv, &year, &month, &day);
277 if (0 != hdate_gdate_to_hdate (day, month, year, &hday, &hmonth, &hyear))
278 return value_new_error_VALUE (ei->pos);
280 return value_new_int (hday + 1);
283 /***************************************************************************/
285 static GnmFuncHelp const help_hdate_year[] = {
286 { GNM_FUNC_HELP_NAME, F_("HDATE_YEAR:Hebrew year of Gregorian date") },
287 { GNM_FUNC_HELP_ARG, F_("year:Gregorian year of date, defaults to the current year")},
288 { GNM_FUNC_HELP_ARG, F_("month:Gregorian month of year, defaults to the current month")},
289 { GNM_FUNC_HELP_ARG, F_("day:Gregorian day of month, defaults to the current day")},
290 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_YEAR(2001,3,30)" },
291 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_YEAR()" },
292 { GNM_FUNC_HELP_SEEALSO, "HDATE_JULIAN"},
293 { GNM_FUNC_HELP_END }
296 static GnmValue *
297 gnumeric_hdate_year (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
299 int year, month, day;
300 int hyear, hmonth, hday;
302 gnumeric_hdate_get_date (argv, &year, &month, &day);
304 if (0 != hdate_gdate_to_hdate (day, month, year, &hday, &hmonth, &hyear))
305 return value_new_error_VALUE (ei->pos);
307 return value_new_int (hyear);
310 /***************************************************************************/
312 static GnmFuncHelp const help_hdate_julian[] = {
313 { GNM_FUNC_HELP_NAME, F_("HDATE_JULIAN:Julian day number for given Gregorian date") },
314 { GNM_FUNC_HELP_ARG, F_("year:Gregorian year of date, defaults to the current year")},
315 { GNM_FUNC_HELP_ARG, F_("month:Gregorian month of year, defaults to the current month")},
316 { GNM_FUNC_HELP_ARG, F_("day:Gregorian day of month, defaults to the current day")},
317 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_JULIAN(2001,3,30)" },
318 { GNM_FUNC_HELP_EXAMPLES, "=HDATE_JULIAN()" },
319 { GNM_FUNC_HELP_SEEALSO, "HDATE"},
320 { GNM_FUNC_HELP_END }
323 static GnmValue *
324 gnumeric_hdate_julian (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
326 int year, month, day;
327 int julian;
329 gnumeric_hdate_get_date (argv, &year, &month, &day);
331 julian = hdate_gdate_to_jd (day, month, year);
333 return value_new_int (julian);
336 /***************************************************************************/
338 static GnmFuncHelp const help_date2julian[] = {
339 { GNM_FUNC_HELP_NAME, F_("DATE2JULIAN:Julian day number for given Gregorian date") },
340 { GNM_FUNC_HELP_ARG, F_("date:Gregorian date, defaults to today")},
341 { GNM_FUNC_HELP_EXAMPLES, "=DATE2JULIAN(DATE(2001,3,30))" },
342 { GNM_FUNC_HELP_EXAMPLES, "=DATE2JULIAN()" },
343 { GNM_FUNC_HELP_SEEALSO, "HDATE_JULIAN"},
344 { GNM_FUNC_HELP_END }
347 static GnmValue *
348 gnumeric_date2julian (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
350 int year, month, day;
351 int julian;
352 GnmValue *val;
354 val = gnumeric_date_get_date (ei, argv[0], &year, &month, &day);
355 if (val != NULL)
356 return val;
358 julian = hdate_gdate_to_jd (day, month, year);
360 return value_new_int (julian);
363 /***************************************************************************/
365 GnmFuncDescriptor const hebrew_datetime_functions[] = {
366 {"hdate", "|fff", help_hdate,
367 gnumeric_hdate, NULL,
368 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE,
369 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
370 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
371 {"hdate_heb", "|fff", help_hdate_heb,
372 gnumeric_hdate_heb, NULL,
373 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE,
374 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
375 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
376 {"hdate_day", "|fff", help_hdate_day,
377 gnumeric_hdate_day, NULL,
378 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_UNITLESS,
379 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
380 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
381 {"hdate_month", "|fff", help_hdate_month,
382 gnumeric_hdate_month, NULL,
383 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_UNITLESS,
384 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
385 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
386 {"hdate_year", "|fff", help_hdate_year,
387 gnumeric_hdate_year, NULL,
388 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_UNITLESS,
389 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
390 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
391 {"hdate_julian", "|fff", help_hdate_julian,
392 gnumeric_hdate_julian, NULL,
393 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_UNITLESS,
394 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
395 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
396 {"date2hdate", "|f", help_date2hdate,
397 gnumeric_date2hdate, NULL,
398 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE,
399 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
400 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
401 {"date2hdate_heb", "|f", help_date2hdate_heb,
402 gnumeric_date2hdate_heb, NULL,
403 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE,
404 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
405 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
406 {"date2julian", "|f", help_date2julian,
407 gnumeric_date2julian, NULL,
408 GNM_FUNC_SIMPLE + GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_UNITLESS,
409 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
410 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
411 {NULL}