[gnumeric] new plugin: fn-christian-date



commit 6d79b7e4d7ba9692a07c5764afb768f6fab0af58
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Thu Oct 22 21:17:32 2009 -0600

    new plugin: fn-christian-date
    
    2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* configure.in: add fn-christian-date plugin
    	* plugins/Makefile.am: ditto
    
    2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* Initial Implementation
    
    2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* POTFILES.in: add plugins/fn-christian-date/functions.c and
    	  plugins/fn-christian-date/plugin.xml.in
    
    2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* POTFILES.in: add plugins/fn-christian-date/functions.c
    	* POTFILES.skip: add plugins/fn-christian-date/plugin.xml.in

 ChangeLog                               |    5 +
 NEWS                                    |    1 +
 configure.in                            |    1 +
 plugins/Makefile.am                     |    3 +-
 plugins/fn-christian-date/.gitignore    |    9 +
 plugins/fn-christian-date/ChangeLog     |    3 +
 plugins/fn-christian-date/Makefile.am   |   18 ++
 plugins/fn-christian-date/functions.c   |  314 +++++++++++++++++++++++++++++++
 plugins/fn-christian-date/plugin.xml.in |   22 +++
 po-functions/ChangeLog                  |    5 +
 po-functions/POTFILES.in                |    1 +
 po-functions/POTFILES.skip              |    1 +
 po/ChangeLog                            |    5 +
 po/POTFILES.in                          |    2 +
 14 files changed, 389 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5d15cd3..66829f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* configure.in: add fn-christian-date plugin
+	* plugins/Makefile.am: ditto
+
 2009-10-20  Morten Welinder  <terra gnome org>
 
 	* src/sheet-control-gui.c (scg_context_menu): Disable slicer stuff
diff --git a/NEWS b/NEWS
index 9b77b14..2946703 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Andreas:
 	* Add RANDSNORM and RANDSTDIST. [#144717]
 	* Add R.PSNORM, R.DSNORM and R.DST.
 	* Fix small sort dialog problem. [#599091]
+	* A few functions from the christian liturgical calendar.
 
 Jody:
 	* First steps towards a turnkey win32 build.
diff --git a/configure.in b/configure.in
index 35b703e..d994f63 100644
--- a/configure.in
+++ b/configure.in
@@ -1040,6 +1040,7 @@ doc/C/figures/Makefile
 doc/C/figures/icons/Makefile
 doc/developer/Makefile
 plugins/Makefile
+plugins/fn-christian-date/Makefile
 plugins/fn-complex/Makefile
 plugins/fn-database/Makefile
 plugins/fn-date/Makefile
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 8ae35e9..a7e86dc 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -11,7 +11,8 @@ if WITH_PARADOX
   SUBDIRS_FILE_FORMATS += paradox
 endif
 
-SUBDIRS_FUNCTIONS = fn-numtheory fn-database fn-date fn-eng fn-erlang \
+SUBDIRS_FUNCTIONS = fn-numtheory fn-christian-date fn-database fn-date \
+	fn-eng fn-erlang \
 	fn-financial fn-hebrew-date fn-info fn-logical fn-complex fn-lookup \
 	fn-math fn-r fn-stat fn-string fn-random fn-tsa fn-derivatives
 
diff --git a/plugins/fn-christian-date/.gitignore b/plugins/fn-christian-date/.gitignore
new file mode 100644
index 0000000..e64b392
--- /dev/null
+++ b/plugins/fn-christian-date/.gitignore
@@ -0,0 +1,9 @@
+Makefile.in
+Makefile
+.deps
+.libs
+*.lo
+*.la
+plugin.xml
+*.loT
+*.sw*
diff --git a/plugins/fn-christian-date/ChangeLog b/plugins/fn-christian-date/ChangeLog
new file mode 100644
index 0000000..d865b41
--- /dev/null
+++ b/plugins/fn-christian-date/ChangeLog
@@ -0,0 +1,3 @@
+2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* Initial Implementation
diff --git a/plugins/fn-christian-date/Makefile.am b/plugins/fn-christian-date/Makefile.am
new file mode 100644
index 0000000..ae64fee
--- /dev/null
+++ b/plugins/fn-christian-date/Makefile.am
@@ -0,0 +1,18 @@
+AM_CPPFLAGS = \
+    -DGNOMELOCALEDIR=\""$(datadir)/locale"\" 	\
+    -I$(top_srcdir)/src	-I$(top_builddir)/src	\
+    $(GNUMERIC_CFLAGS)
+
+gnumeric_plugin_fndatedir = $(gnumeric_plugindir)/fn-christian-date
+xmldir = $(gnumeric_plugin_fndatedir)
+gnumeric_plugin_fndate_LTLIBRARIES = plugin.la
+plugin_la_LDFLAGS = -module $(GNUMERIC_PLUGIN_LDFLAGS)
+plugin_la_SOURCES = functions.c
+
+xml_in_files = plugin.xml.in
+xml_DATA = $(xml_in_files:.xml.in=.xml)
+
+ INTLTOOL_XML_RULE@
+
+EXTRA_DIST = $(xml_in_files)
+DISTCLEANFILES = $(xml_DATA)
diff --git a/plugins/fn-christian-date/functions.c b/plugins/fn-christian-date/functions.c
new file mode 100644
index 0000000..c1edeb3
--- /dev/null
+++ b/plugins/fn-christian-date/functions.c
@@ -0,0 +1,314 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * fn-christian-date.c: Christian date functions.
+ *
+ * Author:
+ *   Andreas J. Guelzow <aguelzow pyrshep ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <gnumeric-config.h>
+#include <gnumeric.h>
+#include <gnm-i18n.h>
+#include <func.h>
+#include <value.h>
+
+#include <parse-util.h>
+#include <cell.h>
+#include <value.h>
+#include <mathfunc.h>
+#include <workbook.h>
+#include <sheet.h>
+
+#include <math.h>
+#include <gnm-datetime.h>
+
+#include <glib.h>
+#include <goffice/goffice.h>
+#include <gnm-plugin.h>
+
+GNM_PLUGIN_MODULE_HEADER;
+
+#define DATE_CONV(ep)		workbook_date_conv ((ep)->sheet->workbook)
+
+static GnmValue *
+make_date (GnmValue *res)
+{
+	value_set_fmt (res, go_format_default_date ());
+	return res;
+}
+
+static void
+eastersunday_calc (int year, GDate *date)
+{
+	int month;
+	int day;
+	int century, n, k, i, j, l;
+
+	century = year/100;
+	n = year - 19 * (year / 19);
+	k = (century - 17) / 25;
+	i = century - century / 4 - (century - k) / 3 + 19 * n + 15;
+	i %= 30;
+	i = i - (i / 28) * (1 - (i / 28) * (29 / (i+1)) * ((21 - n) / 11 ));
+	j = year + year / 4 + i + 2 - century + century / 4;
+	j %= 7;
+	l = i - j;
+	month = 3 + (l + 40) / 44;
+	day = l + 28 - 31 * (month / 4);
+
+	g_date_set_dmy (date, 1, 1, (int)year);
+	gnm_date_add_months (date, (int)month - 1);
+	gnm_date_add_days (date, (int)day - 1);
+}
+
+static void
+eastersunday_calc_no_year (GDate *date, GODateConventions const *conv, int diff)
+{
+	int year, serial;
+	int today = go_date_timet_to_serial (time (NULL), conv);
+
+	go_date_serial_to_g (date, today, conv);
+	year = g_date_get_year (date);
+	g_date_clear (date, 1);
+	eastersunday_calc (year, date);
+	serial = go_date_g_to_serial (date, conv) + diff;
+	if (serial < today) {
+		g_date_clear (date, 1);
+		eastersunday_calc (year + 1, date);
+	}
+}
+
+static int
+adjust_year (int year)
+{
+		if (year < 0 || year >= 9956)
+			return 0;
+		if (year < 31)
+			year += 2000;
+		else if (year < 100) {
+			year += 1900;
+		} else if (year < 1700)
+			return 0;
+		return year;
+}
+
+/***************************************************************************/
+
+static GnmFuncHelp const help_eastersunday[] = {
+	{ GNM_FUNC_HELP_NAME, F_("EASTERSUNDAY:Easter Sunday in the Gregorian calendar "
+				 "according to the Roman rite of the Christian Church") },
+        { GNM_FUNC_HELP_ARG, F_("year:year between 1700 and 9956, defaults to the year of the next Easter Sunday")},
+        { GNM_FUNC_HELP_NOTE, F_("If a year between 0 and 30 is given, the year is adjusted through addition of 2000; if a year between 31 and 99 is given, the year is adjusted through addition of 1900.")},
+        { GNM_FUNC_HELP_EXAMPLES, "=EASTERSUNDAY(2001)" },
+        { GNM_FUNC_HELP_EXAMPLES, "=EASTERSUNDAY()" },
+	{ GNM_FUNC_HELP_ODF, F_("The 1-argument version of EASTERSUNDAY is compatible with OpenOffice "
+				"for years ater 1700. "
+				"This function is not specified in ODF/OpenFormula.")},
+        { GNM_FUNC_HELP_SEEALSO, "ASHWEDNESDAY"},
+	{ GNM_FUNC_HELP_END }
+};
+
+static GnmValue *
+gnumeric_eastersunday (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
+{
+	int year;
+	GDate date;
+	GODateConventions const *conv = DATE_CONV (ei->pos);
+
+	g_date_clear (&date, 1);
+		
+	if (argv [0]) {
+		year  = adjust_year (value_get_as_int (argv [0]));
+		
+		if (year == 0)
+			return value_new_error_NUM (ei->pos);
+		
+		eastersunday_calc (year, &date);
+	} else
+		eastersunday_calc_no_year (&date, conv, 0);
+	
+	return make_date (value_new_int (go_date_g_to_serial (&date, conv)));
+}
+
+
+/***************************************************************************/
+
+static GnmFuncHelp const help_ashwednesday[] = {
+	{ GNM_FUNC_HELP_NAME, F_("ASHWEDNESDAY:Ash Wednesday in the Gregorian calendar "
+				 "according to the Roman rite of the Christian Church") },
+        { GNM_FUNC_HELP_ARG, F_("year:year between 1700 and 9956, defaults to the year of the next Ash Wednesday")},
+        { GNM_FUNC_HELP_NOTE, F_("If a year between 0 and 30 is given, the year is adjusted through addition of 2000; if a year between 31 and 99 is given, the year is adjusted through addition of 1900.")},
+        { GNM_FUNC_HELP_EXAMPLES, "=ASHWEDNESDAY(2001)" },
+        { GNM_FUNC_HELP_EXAMPLES, "=ASHWEDNESDAY()" },
+        { GNM_FUNC_HELP_SEEALSO, "EASTERSUNDAY"},
+	{ GNM_FUNC_HELP_END }
+};
+
+static GnmValue *
+gnumeric_ashwednesday (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
+{
+	int year;
+	GDate date;
+	GODateConventions const *conv = DATE_CONV (ei->pos);
+
+	g_date_clear (&date, 1);
+		
+	if (argv [0]) {
+		year  = adjust_year (value_get_as_int (argv [0]));
+		
+		if (year == 0)
+			return value_new_error_NUM (ei->pos);
+		
+		eastersunday_calc (year, &date);
+	} else
+		eastersunday_calc_no_year (&date, conv, -46);
+	return make_date (value_new_int (go_date_g_to_serial (&date, conv) - 46 
+					 - ((year == 1900)? 1 : 0)));
+}
+
+
+/***************************************************************************/
+
+static GnmFuncHelp const help_pentecostsunday[] = {
+	{ GNM_FUNC_HELP_NAME, F_("PENTECOSTSUNDAY:Pentecost Sunday in the Gregorian calendar "
+				 "according to the Roman rite of the Christian Church") },
+        { GNM_FUNC_HELP_ARG, F_("year:year between 1700 and 9956, defaults to the year of the next Pentecost Sunday")},
+        { GNM_FUNC_HELP_NOTE, F_("If a year between 0 and 30 is given, the year is adjusted through addition of 2000; if a year between 31 and 99 is given, the year is adjusted through addition of 1900.")},
+        { GNM_FUNC_HELP_EXAMPLES, "=PENTECOSTSUNDAY(2001)" },
+        { GNM_FUNC_HELP_EXAMPLES, "=PENTECOSTSUNDAY()" },
+        { GNM_FUNC_HELP_SEEALSO, "EASTERSUNDAY"},
+	{ GNM_FUNC_HELP_END }
+};
+
+static GnmValue *
+gnumeric_pentecostsunday (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
+{
+	int year;
+	GDate date;
+	GODateConventions const *conv = DATE_CONV (ei->pos);
+
+	g_date_clear (&date, 1);
+		
+	if (argv [0]) {
+		year  = adjust_year (value_get_as_int (argv [0]));
+		
+		if (year == 0)
+			return value_new_error_NUM (ei->pos);
+		
+		eastersunday_calc (year, &date);
+	} else
+		eastersunday_calc_no_year (&date, conv, 49);
+	return make_date (value_new_int (go_date_g_to_serial (&date, conv) + 49));
+}
+
+/***************************************************************************/
+
+static GnmFuncHelp const help_goodfriday[] = {
+	{ GNM_FUNC_HELP_NAME, F_("GOODFRIDAY:Good Friday in the Gregorian calendar "
+				 "according to the Roman rite of the Christian Church") },
+        { GNM_FUNC_HELP_ARG, F_("year:year between 1700 and 9956, defaults to the year of the next Good Friday")},
+        { GNM_FUNC_HELP_NOTE, F_("If a year between 0 and 30 is given, the year is adjusted through addition of 2000; if a year between 31 and 99 is given, the year is adjusted through addition of 1900.")},
+        { GNM_FUNC_HELP_EXAMPLES, "=GOODFRIDAY(2001)" },
+        { GNM_FUNC_HELP_EXAMPLES, "=GOODFRIDAY()" },
+        { GNM_FUNC_HELP_SEEALSO, "EASTERSUNDAY"},
+	{ GNM_FUNC_HELP_END }
+};
+
+static GnmValue *
+gnumeric_goodfriday (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
+{
+	int year;
+	GDate date;
+	GODateConventions const *conv = DATE_CONV (ei->pos);
+
+	g_date_clear (&date, 1);
+		
+	if (argv [0]) {
+		year  = adjust_year (value_get_as_int (argv [0]));
+		
+		if (year == 0)
+			return value_new_error_NUM (ei->pos);
+		
+		eastersunday_calc (year, &date);
+	} else
+		eastersunday_calc_no_year (&date, conv, -2);
+	return make_date (value_new_int (go_date_g_to_serial (&date, conv) - 2));
+}
+
+/***************************************************************************/
+
+static GnmFuncHelp const help_ascensionthursday[] = {
+	{ GNM_FUNC_HELP_NAME, F_("ASCENSIONTHURSDAY:Ascension Thursday in the Gregorian calendar "
+				 "according to the Roman rite of the Christian Church") },
+        { GNM_FUNC_HELP_ARG, F_("year:year between 1700 and 9956, defaults to the year of the next Ascension Thursday")},
+        { GNM_FUNC_HELP_NOTE, F_("If a year between 0 and 30 is given, the year is adjusted through addition of 2000; if a year between 31 and 99 is given, the year is adjusted through addition of 1900.")},
+        { GNM_FUNC_HELP_EXAMPLES, "=ASCENSIONTHURSDAY(2001)" },
+        { GNM_FUNC_HELP_EXAMPLES, "=ASCENSIONTHURSDAY()" },
+        { GNM_FUNC_HELP_SEEALSO, "EASTERSUNDAY"},
+	{ GNM_FUNC_HELP_END }
+};
+
+static GnmValue *
+gnumeric_ascensionthursday (GnmFuncEvalInfo * ei, GnmValue const * const *argv)
+{
+	int year;
+	GDate date;
+	GODateConventions const *conv = DATE_CONV (ei->pos);
+
+	g_date_clear (&date, 1);
+		
+	if (argv [0]) {
+		year  = adjust_year (value_get_as_int (argv [0]));
+		
+		if (year == 0)
+			return value_new_error_NUM (ei->pos);
+		
+		eastersunday_calc (year, &date);
+	} else
+		eastersunday_calc_no_year (&date, conv, 39);
+	return make_date (value_new_int (go_date_g_to_serial (&date, conv) + 39));
+}
+
+/***************************************************************************/
+
+GnmFuncDescriptor const datetime_functions[] = {
+	{"ascensionthursday", "|f", help_ascensionthursday,
+	 gnumeric_ascensionthursday, NULL, NULL, NULL, NULL,
+	 GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_DATE,
+	 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
+	 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
+	{"ashwednesday", "|f", help_ashwednesday,
+	 gnumeric_ashwednesday, NULL, NULL, NULL, NULL,
+	 GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_DATE,
+	 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
+	 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
+	{"eastersunday", "|f", help_eastersunday,
+	 gnumeric_eastersunday, NULL, NULL, NULL, NULL,
+	 GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_DATE,
+	 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
+	 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
+	{"goodfriday", "|f", help_goodfriday,
+	 gnumeric_goodfriday, NULL, NULL, NULL, NULL,
+	 GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_DATE,
+	 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
+	 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
+	{"pentecostsunday", "|f", help_pentecostsunday,
+	 gnumeric_pentecostsunday, NULL, NULL, NULL, NULL,
+	 GNM_FUNC_VOLATILE + GNM_FUNC_AUTO_DATE,
+	 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
+	 GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
+	{NULL}
+};
diff --git a/plugins/fn-christian-date/plugin.xml.in b/plugins/fn-christian-date/plugin.xml.in
new file mode 100644
index 0000000..9139f96
--- /dev/null
+++ b/plugins/fn-christian-date/plugin.xml.in
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin id="Gnumeric_fnchristiandate">
+	<information>
+		<_name>Christian Date Functions</_name>
+		<_description>Functions manipulating dates of the Christian liturgical calendar</_description>
+	</information>
+	<loader type="Gnumeric_Builtin:module">
+		<attribute name="module_file" value="plugin"/>
+	</loader>
+	<services>
+		<service type="function_group" id="datetime">
+			<_category>Date/Time</_category>
+			<functions textdomain="gnumeric-functions">
+				<function name="eastersunday"/>
+				<function name="ascensionthursday"/>
+				<function name="ashwednesday"/>
+				<function name="pentecostsunday"/>
+				<function name="goodfriday"/>
+			</functions>
+		</service>
+	</services>
+</plugin>
diff --git a/po-functions/ChangeLog b/po-functions/ChangeLog
index 1d2a8ef..9809786 100644
--- a/po-functions/ChangeLog
+++ b/po-functions/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* POTFILES.in: add plugins/fn-christian-date/functions.c
+	* POTFILES.skip: add plugins/fn-christian-date/plugin.xml.in
+
 2009-10-11  Morten Welinder <terra gnome org>
 
 	* Release 1.9.14
diff --git a/po-functions/POTFILES.in b/po-functions/POTFILES.in
index d0cb583..61fc66e 100644
--- a/po-functions/POTFILES.in
+++ b/po-functions/POTFILES.in
@@ -10,6 +10,7 @@ plugins/excel/ms-formula-read.c
 plugins/excel/ms-formula-write.c
 plugins/excel/xlsx-read.c
 plugins/excel/xlsx-read-pivot.c
+plugins/fn-christian-date/functions.c
 plugins/fn-complex/functions.c
 plugins/fn-database/functions.c
 plugins/fn-date/functions.c
diff --git a/po-functions/POTFILES.skip b/po-functions/POTFILES.skip
index 7aac1f4..8db9fd9 100644
--- a/po-functions/POTFILES.skip
+++ b/po-functions/POTFILES.skip
@@ -16,6 +16,7 @@ plugins/applix/plugin.xml.in
 plugins/corba/plugin.xml.in
 plugins/dif/plugin.xml.in
 plugins/excel/plugin.xml.in
+plugins/fn-christian-date/plugin.xml.in
 plugins/fn-complex/plugin.xml.in
 plugins/fn-database/plugin.xml.in
 plugins/fn-date/plugin.xml.in
diff --git a/po/ChangeLog b/po/ChangeLog
index 66b396f..685af16 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-22  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* POTFILES.in: add plugins/fn-christian-date/functions.c and
+	  plugins/fn-christian-date/plugin.xml.in
+
 2009-10-11  Morten Welinder <terra gnome org>
 
 	* Release 1.9.14
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0190e33..6768cd6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -18,6 +18,8 @@ plugins/excel/ms-formula-write.c
 plugins/excel/plugin.xml.in
 plugins/excel/xlsx-read.c
 plugins/excel/xlsx-read-pivot.c
+plugins/fn-christian-date/functions.c
+plugins/fn-christian-date/plugin.xml.in
 plugins/fn-complex/functions.c
 plugins/fn-complex/plugin.xml.in
 plugins/fn-database/functions.c



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]