1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * fn-christian-date.c: Christian date functions.
6 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <https://www.gnu.org/licenses/>.
21 #include <gnumeric-config.h>
27 #include <parse-util.h>
35 #include <gnm-datetime.h>
38 #include <goffice/goffice.h>
39 #include <gnm-plugin.h>
41 GNM_PLUGIN_MODULE_HEADER
;
43 #define DATE_CONV(ep) workbook_date_conv ((ep)->sheet->workbook)
46 eastersunday_calc_for_year (int year
, GDate
*date
)
50 int century
, n
, k
, i
, j
, l
;
53 n
= year
- 19 * (year
/ 19);
54 k
= (century
- 17) / 25;
55 i
= century
- century
/ 4 - (century
- k
) / 3 + 19 * n
+ 15;
57 i
= i
- (i
/ 28) * (1 - (i
/ 28) * (29 / (i
+1)) * ((21 - n
) / 11 ));
58 j
= year
+ year
/ 4 + i
+ 2 - century
+ century
/ 4;
61 month
= 3 + (l
+ 40) / 44;
62 day
= l
+ 28 - 31 * (month
/ 4);
64 g_date_clear (date
, 1);
65 g_date_set_dmy (date
, day
, month
, year
);
69 eastersunday_calc_no_year (GDate
*date
, GODateConventions
const *conv
, int diff
)
72 int today
= go_date_timet_to_serial (time (NULL
), conv
);
74 go_date_serial_to_g (date
, today
, conv
);
75 year
= g_date_get_year (date
);
76 eastersunday_calc_for_year (year
, date
);
77 serial
= go_date_g_to_serial (date
, conv
) + diff
;
79 eastersunday_calc_for_year (year
+ 1, date
);
83 adjust_year (int year
, GODateConventions
const *conv
)
91 else if (year
< (gnm_datetime_allow_negative () ? 1582
92 : go_date_convention_base (conv
)))
101 eastersunday_calc (GnmValue
const *val
, GnmFuncEvalInfo
*ei
, int diff
)
103 GODateConventions
const *conv
= DATE_CONV (ei
->pos
);
108 int year
= adjust_year (value_get_as_int (val
), conv
);
111 return value_new_error_NUM (ei
->pos
);
113 eastersunday_calc_for_year (year
, &date
);
115 eastersunday_calc_no_year (&date
, conv
, diff
);
117 serial
= go_date_g_to_serial (&date
, conv
) + diff
;
120 serial
> 0 && serial
<= 60 &&
121 go_date_convention_base (conv
) == 1900) {
122 /* We crossed the 29-Feb-1900 hole in the 1900 method. */
126 return value_new_int (serial
);
129 /***************************************************************************/
131 static GnmFuncHelp
const help_eastersunday
[] = {
132 { GNM_FUNC_HELP_NAME
, F_("EASTERSUNDAY:Easter Sunday in the Gregorian calendar "
133 "according to the Roman rite of the Christian Church") },
134 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Easter Sunday")},
135 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
136 { GNM_FUNC_HELP_EXAMPLES
, "=EASTERSUNDAY(2001)" },
137 { GNM_FUNC_HELP_EXAMPLES
, "=EASTERSUNDAY()" },
138 { GNM_FUNC_HELP_ODF
, F_("The 1-argument version of EASTERSUNDAY is compatible with OpenOffice "
139 "for years after 1904. "
140 "This function is not specified in ODF/OpenFormula.")},
141 { GNM_FUNC_HELP_SEEALSO
, "ASHWEDNESDAY"},
142 { GNM_FUNC_HELP_END
}
146 gnumeric_eastersunday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
148 return eastersunday_calc (argv
[0], ei
, 0);
152 /***************************************************************************/
154 static GnmFuncHelp
const help_ashwednesday
[] = {
155 { GNM_FUNC_HELP_NAME
, F_("ASHWEDNESDAY:Ash Wednesday in the Gregorian calendar "
156 "according to the Roman rite of the Christian Church") },
157 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Ash Wednesday")},
158 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
159 { GNM_FUNC_HELP_EXAMPLES
, "=ASHWEDNESDAY(2001)" },
160 { GNM_FUNC_HELP_EXAMPLES
, "=ASHWEDNESDAY()" },
161 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
162 { GNM_FUNC_HELP_END
}
166 gnumeric_ashwednesday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
168 return eastersunday_calc (argv
[0], ei
, -46);
172 /***************************************************************************/
174 static GnmFuncHelp
const help_pentecostsunday
[] = {
175 { GNM_FUNC_HELP_NAME
, F_("PENTECOSTSUNDAY:Pentecost Sunday in the Gregorian calendar "
176 "according to the Roman rite of the Christian Church") },
177 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Pentecost Sunday")},
178 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
179 { GNM_FUNC_HELP_EXAMPLES
, "=PENTECOSTSUNDAY(2001)" },
180 { GNM_FUNC_HELP_EXAMPLES
, "=PENTECOSTSUNDAY()" },
181 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
182 { GNM_FUNC_HELP_END
}
186 gnumeric_pentecostsunday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
188 return eastersunday_calc (argv
[0], ei
, +49);
191 /***************************************************************************/
193 static GnmFuncHelp
const help_goodfriday
[] = {
194 { GNM_FUNC_HELP_NAME
, F_("GOODFRIDAY:Good Friday in the Gregorian calendar "
195 "according to the Roman rite of the Christian Church") },
196 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Good Friday")},
197 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
198 { GNM_FUNC_HELP_EXAMPLES
, "=GOODFRIDAY(2001)" },
199 { GNM_FUNC_HELP_EXAMPLES
, "=GOODFRIDAY()" },
200 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
201 { GNM_FUNC_HELP_END
}
205 gnumeric_goodfriday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
207 return eastersunday_calc (argv
[0], ei
, -2);
210 /***************************************************************************/
212 static GnmFuncHelp
const help_ascensionthursday
[] = {
213 { GNM_FUNC_HELP_NAME
, F_("ASCENSIONTHURSDAY:Ascension Thursday in the Gregorian calendar "
214 "according to the Roman rite of the Christian Church") },
215 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Ascension Thursday")},
216 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
217 { GNM_FUNC_HELP_EXAMPLES
, "=ASCENSIONTHURSDAY(2001)" },
218 { GNM_FUNC_HELP_EXAMPLES
, "=ASCENSIONTHURSDAY()" },
219 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
220 { GNM_FUNC_HELP_END
}
224 gnumeric_ascensionthursday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
226 return eastersunday_calc (argv
[0], ei
, +39);
229 /***************************************************************************/
231 GnmFuncDescriptor
const christian_datetime_functions
[] = {
232 {"ascensionthursday", "|f", help_ascensionthursday
,
233 gnumeric_ascensionthursday
, NULL
, NULL
, NULL
,
234 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
235 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
236 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
237 {"ashwednesday", "|f", help_ashwednesday
,
238 gnumeric_ashwednesday
, NULL
, NULL
, NULL
,
239 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
240 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
241 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
242 {"eastersunday", "|f", help_eastersunday
,
243 gnumeric_eastersunday
, NULL
, NULL
, NULL
,
244 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
245 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
246 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
247 {"goodfriday", "|f", help_goodfriday
,
248 gnumeric_goodfriday
, NULL
, NULL
, NULL
,
249 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
250 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
251 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
252 {"pentecostsunday", "|f", help_pentecostsunday
,
253 gnumeric_pentecostsunday
, NULL
, NULL
, NULL
,
254 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
255 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
256 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},