Commit 5a6e864a authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

Handle new basis BASIS_MSRB_30_360_SYM.

2003-07-08  Morten Welinder  <terra@gnome.org>

	* src/datetime.c (days_between_basis): Handle new basis
	BASIS_MSRB_30_360_SYM.
	(days_between_BASIS_MSRB_30_360_SYM): New function.
	(days_between_BASIS_MSRB_30_360): Handle end-of-February
	correctly.

2003-07-08  Morten Welinder  <terra@gnome.org>

	* functions.c (gnumeric_days360): Simplify greatly using
	days_between_basis.
parent b832b295
2003-07-08 Morten Welinder <terra@gnome.org>
* src/datetime.c (days_between_basis): Handle new basis
BASIS_MSRB_30_360_SYM.
(days_between_BASIS_MSRB_30_360_SYM): New function.
(days_between_BASIS_MSRB_30_360): Handle end-of-February
correctly.
2003-07-07 Morten Welinder <terra@gnome.org>
* src/datetime.c (yearfrac): Even get February 29 right.
......
2003-07-08 Morten Welinder <terra@gnome.org>
* src/datetime.c (days_between_basis): Handle new basis
BASIS_MSRB_30_360_SYM.
(days_between_BASIS_MSRB_30_360_SYM): New function.
(days_between_BASIS_MSRB_30_360): Handle end-of-February
correctly.
2003-07-07 Morten Welinder <terra@gnome.org>
* src/datetime.c (yearfrac): Even get February 29 right.
......
2003-07-08 Morten Welinder <terra@gnome.org>
* src/datetime.c (days_between_basis): Handle new basis
BASIS_MSRB_30_360_SYM.
(days_between_BASIS_MSRB_30_360_SYM): New function.
(days_between_BASIS_MSRB_30_360): Handle end-of-February
correctly.
2003-07-07 Morten Welinder <terra@gnome.org>
* src/datetime.c (yearfrac): Even get February 29 right.
......
2003-07-08 Morten Welinder <terra@gnome.org>
* functions.c (gnumeric_days360): Simplify greatly using
days_between_basis.
2003-07-01 Morten Welinder <terra@gnome.org>
* functions.c (gnumeric_yearfrac): Use yearfrac.
......
......@@ -790,67 +790,23 @@ static char const *help_days360 = {
static Value *
gnumeric_days360 (FunctionEvalInfo *ei, Value **argv)
{
enum Method { METHOD_US_XL = 0, METHOD_EUROPE = 1, METHOD_US_SANE = 2 } method;
basis_t basis;
GDate date1, date2;
int day1, day2, month1, month2, year1, year2, result;
gboolean flipped;
GnmDateConventions const *conv = DATE_CONV (ei->pos);
gnm_float serial1 = datetime_value_to_serial (argv[0], conv);
gnm_float serial2 = datetime_value_to_serial (argv[1], conv);
int imethod = argv[2] ? value_get_as_int (argv[2]) : 0;
method = (imethod >= 0 && imethod <= METHOD_US_SANE)
? (enum Method)imethod
: METHOD_EUROPE;
if ((flipped = (serial1 > serial2))) {
gnm_float tmp = serial1;
serial1 = serial2;
serial2 = tmp;
}
datetime_serial_to_g (&date1, serial1, conv);
datetime_serial_to_g (&date2, serial2, conv);
day1 = g_date_get_day (&date1);
day2 = g_date_get_day (&date2);
month1 = g_date_get_month (&date1);
month2 = g_date_get_month (&date2);
year1 = g_date_get_year (&date1);
year2 = g_date_get_year (&date2);
GnmDateConventions const *date_conv = DATE_CONV (ei->pos);
gnm_float serial1 = datetime_value_to_serial (argv[0], date_conv);
gnm_float serial2 = datetime_value_to_serial (argv[1], date_conv);
int method = argv[2] ? value_get_as_int (argv[2]) : 0;
switch (method) {
case METHOD_US_SANE:
if (month1 == 2 && month2 == 2 &&
g_date_is_last_of_month (&date1) &&
g_date_is_last_of_month (&date2))
day2 = 30;
/* Fall through. */
case METHOD_US_XL:
if (month1 == 2 && g_date_is_last_of_month (&date1))
day1 = 30;
if (day2 == 31 && day1 >= 30)
day2 = 30;
if (day1 == 31)
day1 = 30;
break;
case METHOD_EUROPE:
if (day1 == 31)
day1 = 30;
if (day2 == 31)
day2 = 30;
break;
default:
return value_new_error_VALUE (ei->pos);
default:
case 0: basis = BASIS_MSRB_30_360; break;
case 1: basis = BASIS_30E_360; break;
case 2: basis = BASIS_MSRB_30_360_SYM; break;
}
result = ((year2 - year1) * 12 + (month2 - month1)) * 30 +
(day2 - day1);
return value_new_int (flipped ? -result : result);
datetime_serial_to_g (&date1, serial1, date_conv);
datetime_serial_to_g (&date2, serial2, date_conv);
return value_new_int (days_between_basis (&date1, &date2, basis));
}
/***************************************************************************/
......
......@@ -339,11 +339,36 @@ days_between_BASIS_MSRB_30_360 (GDate const *from, GDate const *to)
m2 = g_date_get_month (to);
d2 = g_date_get_day (to);
if (d1 >= 30) {
if (m1 == 2 && g_date_is_last_of_month (from))
d1 = 30;
if (d2 == 31 && d1 >= 30)
d2 = 30;
if (d1 == 31)
d1 = 30;
return (y2 - y1) * 360 + (m2 - m1) * 30 + (d2 - d1);
}
static gint32
days_between_BASIS_MSRB_30_360_SYM (GDate const *from, GDate const *to)
{
int y1, m1, d1, y2, m2, d2;
y1 = g_date_get_year (from);
m1 = g_date_get_month (from);
d1 = g_date_get_day (from);
y2 = g_date_get_year (to);
m2 = g_date_get_month (to);
d2 = g_date_get_day (to);
if (m1 == 2 && g_date_is_last_of_month (from))
d1 = 30;
if (m2 == 2 && g_date_is_last_of_month (to))
d2 = 30;
if (d2 == 31 && d1 >= 30)
d2 = 30;
if (d1 == 31)
d1 = 30;
if (d2 == 31)
d2 = 30;
}
return (y2 - y1) * 360 + (m2 - m1) * 30 + (d2 - d1);
}
......@@ -426,6 +451,8 @@ days_between_basis (GDate const *from, GDate const *to, basis_t basis)
return sign * days_between_BASIS_30E_360 (from, to);
case BASIS_30Ep_360:
return sign * days_between_BASIS_30Ep_360 (from, to);
case BASIS_MSRB_30_360_SYM:
return sign * days_between_BASIS_MSRB_30_360_SYM (from, to);
case BASIS_MSRB_30_360:
default:
return sign * days_between_BASIS_MSRB_30_360 (from, to);
......
......@@ -63,13 +63,13 @@ int datetime_g_years_between (GDate const *date1, GDate const *date2);
int datetime_weeknum (GDate const *date, int method);
typedef enum { /* see doc/fn-financial-basis.txt for details */
BASIS_MSRB_30_360 = 0,
BASIS_ACT_ACT = 1,
BASIS_ACT_360 = 2,
BASIS_ACT_365 = 3,
BASIS_30E_360 = 4,
BASIS_30Ep_360 = 5,
BASIS_LAST = 6
BASIS_MSRB_30_360 = 0,
BASIS_ACT_ACT = 1,
BASIS_ACT_360 = 2,
BASIS_ACT_365 = 3,
BASIS_30E_360 = 4,
BASIS_30Ep_360 = 5,
BASIS_MSRB_30_360_SYM = 6 /* Gnumeric extension. */
} basis_t;
gint32 days_between_basis (GDate const *from, GDate const *to, basis_t basis);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment