2 * fn-christian-date.c: Christian date functions.
5 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
20 #include <gnumeric-config.h>
26 #include <parse-util.h>
34 #include <gnm-datetime.h>
37 #include <goffice/goffice.h>
38 #include <gnm-plugin.h>
40 GNM_PLUGIN_MODULE_HEADER
;
42 #define DATE_CONV(ep) sheet_date_conv ((ep)->sheet)
45 eastersunday_calc_for_year (int year
, GDate
*date
)
49 int century
, n
, k
, i
, j
, l
;
52 n
= year
- 19 * (year
/ 19);
53 k
= (century
- 17) / 25;
54 i
= century
- century
/ 4 - (century
- k
) / 3 + 19 * n
+ 15;
56 i
= i
- (i
/ 28) * (1 - (i
/ 28) * (29 / (i
+1)) * ((21 - n
) / 11 ));
57 j
= year
+ year
/ 4 + i
+ 2 - century
+ century
/ 4;
60 month
= 3 + (l
+ 40) / 44;
61 day
= l
+ 28 - 31 * (month
/ 4);
63 g_date_clear (date
, 1);
64 g_date_set_dmy (date
, day
, month
, year
);
68 eastersunday_calc_no_year (GDate
*date
, GODateConventions
const *conv
, int diff
)
71 int today
= go_date_timet_to_serial (time (NULL
), conv
);
73 go_date_serial_to_g (date
, today
, conv
);
74 year
= g_date_get_year (date
);
75 eastersunday_calc_for_year (year
, date
);
76 serial
= go_date_g_to_serial (date
, conv
) + diff
;
78 eastersunday_calc_for_year (year
+ 1, date
);
82 adjust_year (int year
, GODateConventions
const *conv
)
90 else if (year
< (gnm_datetime_allow_negative () ? 1582
91 : go_date_convention_base (conv
)))
100 eastersunday_calc (GnmValue
const *val
, GnmFuncEvalInfo
*ei
, int diff
)
102 GODateConventions
const *conv
= DATE_CONV (ei
->pos
);
107 int year
= adjust_year (value_get_as_int (val
), conv
);
110 return value_new_error_NUM (ei
->pos
);
112 eastersunday_calc_for_year (year
, &date
);
114 eastersunday_calc_no_year (&date
, conv
, diff
);
116 serial
= go_date_g_to_serial (&date
, conv
) + diff
;
119 serial
> 0 && serial
<= 60 &&
120 go_date_convention_base (conv
) == 1900) {
121 /* We crossed the 29-Feb-1900 hole in the 1900 method. */
125 return value_new_int (serial
);
128 /***************************************************************************/
130 static GnmFuncHelp
const help_eastersunday
[] = {
131 { GNM_FUNC_HELP_NAME
, F_("EASTERSUNDAY:Easter Sunday in the Gregorian calendar "
132 "according to the Roman rite of the Christian Church") },
133 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Easter Sunday")},
134 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
135 { GNM_FUNC_HELP_EXAMPLES
, "=EASTERSUNDAY(2001)" },
136 { GNM_FUNC_HELP_EXAMPLES
, "=EASTERSUNDAY()" },
137 { GNM_FUNC_HELP_ODF
, F_("The 1-argument version of EASTERSUNDAY is compatible with OpenOffice "
138 "for years after 1904. "
139 "This function is not specified in ODF/OpenFormula.")},
140 { GNM_FUNC_HELP_SEEALSO
, "ASHWEDNESDAY"},
141 { GNM_FUNC_HELP_END
}
145 gnumeric_eastersunday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
147 return eastersunday_calc (argv
[0], ei
, 0);
151 /***************************************************************************/
153 static GnmFuncHelp
const help_ashwednesday
[] = {
154 { GNM_FUNC_HELP_NAME
, F_("ASHWEDNESDAY:Ash Wednesday in the Gregorian calendar "
155 "according to the Roman rite of the Christian Church") },
156 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Ash Wednesday")},
157 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
158 { GNM_FUNC_HELP_EXAMPLES
, "=ASHWEDNESDAY(2001)" },
159 { GNM_FUNC_HELP_EXAMPLES
, "=ASHWEDNESDAY()" },
160 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
161 { GNM_FUNC_HELP_END
}
165 gnumeric_ashwednesday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
167 return eastersunday_calc (argv
[0], ei
, -46);
171 /***************************************************************************/
173 static GnmFuncHelp
const help_pentecostsunday
[] = {
174 { GNM_FUNC_HELP_NAME
, F_("PENTECOSTSUNDAY:Pentecost Sunday in the Gregorian calendar "
175 "according to the Roman rite of the Christian Church") },
176 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Pentecost Sunday")},
177 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
178 { GNM_FUNC_HELP_EXAMPLES
, "=PENTECOSTSUNDAY(2001)" },
179 { GNM_FUNC_HELP_EXAMPLES
, "=PENTECOSTSUNDAY()" },
180 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
181 { GNM_FUNC_HELP_END
}
185 gnumeric_pentecostsunday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
187 return eastersunday_calc (argv
[0], ei
, +49);
190 /***************************************************************************/
192 static GnmFuncHelp
const help_goodfriday
[] = {
193 { GNM_FUNC_HELP_NAME
, F_("GOODFRIDAY:Good Friday in the Gregorian calendar "
194 "according to the Roman rite of the Christian Church") },
195 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Good Friday")},
196 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
197 { GNM_FUNC_HELP_EXAMPLES
, "=GOODFRIDAY(2001)" },
198 { GNM_FUNC_HELP_EXAMPLES
, "=GOODFRIDAY()" },
199 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
200 { GNM_FUNC_HELP_END
}
204 gnumeric_goodfriday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
206 return eastersunday_calc (argv
[0], ei
, -2);
209 /***************************************************************************/
211 static GnmFuncHelp
const help_ascensionthursday
[] = {
212 { GNM_FUNC_HELP_NAME
, F_("ASCENSIONTHURSDAY:Ascension Thursday in the Gregorian calendar "
213 "according to the Roman rite of the Christian Church") },
214 { GNM_FUNC_HELP_ARG
, F_("year:year between 1582 and 9956, defaults to the year of the next Ascension Thursday")},
215 { GNM_FUNC_HELP_NOTE
, F_("Two digit years are adjusted as elsewhere in Gnumeric. Dates before 1904 may also be prohibited.")},
216 { GNM_FUNC_HELP_EXAMPLES
, "=ASCENSIONTHURSDAY(2001)" },
217 { GNM_FUNC_HELP_EXAMPLES
, "=ASCENSIONTHURSDAY()" },
218 { GNM_FUNC_HELP_SEEALSO
, "EASTERSUNDAY"},
219 { GNM_FUNC_HELP_END
}
223 gnumeric_ascensionthursday (GnmFuncEvalInfo
* ei
, GnmValue
const * const *argv
)
225 return eastersunday_calc (argv
[0], ei
, +39);
228 /***************************************************************************/
230 GnmFuncDescriptor
const christian_datetime_functions
[] = {
231 {"ascensionthursday", "|f", help_ascensionthursday
,
232 gnumeric_ascensionthursday
, NULL
, NULL
, NULL
,
233 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
234 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
235 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
236 {"ashwednesday", "|f", help_ashwednesday
,
237 gnumeric_ashwednesday
, NULL
, NULL
, NULL
,
238 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
239 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
240 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
241 {"eastersunday", "|f", help_eastersunday
,
242 gnumeric_eastersunday
, NULL
, NULL
, NULL
,
243 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
244 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
245 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
246 {"goodfriday", "|f", help_goodfriday
,
247 gnumeric_goodfriday
, NULL
, NULL
, NULL
,
248 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
249 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
250 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},
251 {"pentecostsunday", "|f", help_pentecostsunday
,
252 gnumeric_pentecostsunday
, NULL
, NULL
, NULL
,
253 GNM_FUNC_VOLATILE
+ GNM_FUNC_AUTO_DATE
,
254 GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
,
255 GNM_FUNC_TEST_STATUS_NO_TESTSUITE
},