Commit daf4200f authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

New function. (datetime_value_to_serial_raw): Err on negative date numbers

2008-12-15  Morten Welinder  <terra@gnome.org>

	* src/gnm-datetime.c (gnm_datetime_allow_negative): New function.
	(datetime_value_to_serial_raw): Err on negative date numbers
	unless goffice supports them.

2008-12-15  Morten Welinder  <terra@gnome.org>

	* functions.c (gnumeric_unix2date): check for overflow.
	(float_to_secs): Handle negative values.  Range check arguments.


svn path=/trunk/; revision=17024
parent df190e55
2008-12-15 Morten Welinder <terra@gnome.org>
* src/gnm-datetime.c (gnm_datetime_allow_negative): New function.
(datetime_value_to_serial_raw): Err on negative date numbers
unless goffice supports them.
2008-12-14 Morten Welinder <terra@gnome.org>
* src/gnm-datetime.c (datetime_value_to_serial): Handle overflow.
......
2008-12-15 Morten Welinder <terra@gnome.org>
* functions.c (gnumeric_unix2date): check for overflow.
(float_to_secs): Handle negative values. Range check arguments.
2008-10-18 Jody Goldberg <jody@gnome.org>
......
......@@ -70,12 +70,15 @@ value_get_basis (const GnmValue *v, int defalt)
}
static int
float_to_secs (gnm_float d)
float_to_secs (GnmValue const *v, GODateConventions const *conv)
{
int secs;
gnm_float d = datetime_value_to_serial_raw (v, conv);
if (d == G_MAXINT)
return -1;
/* Ok, we have a positive number. Add epsilon before we scale
and translate because otherwise it will not be enough. */
/* Add epsilon before we scale and translate because otherwise it
will not be enough. */
d = gnm_add_epsilon (d);
/* Get the number down between 0 and 1 before we scale. */
......@@ -611,14 +614,12 @@ static GnmFuncHelp const help_hour[] = {
static GnmValue *
gnumeric_hour (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
{
gnm_float d = value_get_as_float (argv[0]);
int secs = float_to_secs (argv[0], DATE_CONV (ei->pos));
if (d < 0)
if (secs < 0)
return value_new_error_NUM (ei->pos);
else {
int secs = float_to_secs (d);
else
return value_new_int (secs / 3600);
}
}
/***************************************************************************/
......@@ -648,14 +649,12 @@ static GnmFuncHelp const help_minute[] = {
static GnmValue *
gnumeric_minute (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
{
gnm_float d = value_get_as_float (argv[0]);
int secs = float_to_secs (argv[0], DATE_CONV (ei->pos));
if (d < 0)
if (secs < 0)
return value_new_error_NUM (ei->pos);
else {
int secs = float_to_secs (d);
else
return value_new_int (secs / 60 % 60);
}
}
/***************************************************************************/
......@@ -685,14 +684,12 @@ static GnmFuncHelp const help_second[] = {
static GnmValue *
gnumeric_second (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
{
gnm_float d = value_get_as_float (argv[0]);
int secs = float_to_secs (argv[0], DATE_CONV (ei->pos));
if (d < 0)
if (secs < 0)
return value_new_error_NUM (ei->pos);
else {
int secs = float_to_secs (d);
else
return value_new_int (secs % 60);
}
}
/***************************************************************************/
......
......@@ -26,9 +26,37 @@
#include <gnumeric-config.h>
#include <goffice/utils/go-format.h>
#include "value.h"
#include <string.h>
#include "gnm-datetime.h"
#include "gnm-format.h"
#include "number-match.h"
/*
* Figure out whether the format engine in goffice allows negative values
* or (as XL) considers them errors.
*/
gboolean
gnm_datetime_allow_negative (void)
{
static int allow = -1;
if (allow == -1) {
GOFormat *fmt = go_format_new_from_XL ("yyyy-mm-dd");
GnmValue *v = value_new_int (-42);
GODateConventions const *conv =
go_date_conv_from_str ("Lotus:1900");
char *text = format_value (fmt, v, NULL, -1, conv);
allow = (strcmp (text, "1899-11-19") == 0);
value_release (v);
go_format_unref (fmt);
g_free (text);
}
return (gboolean)allow;
}
gnm_float
datetime_value_to_serial_raw (GnmValue const *v, GODateConventions const *conv)
{
......@@ -46,6 +74,10 @@ datetime_value_to_serial_raw (GnmValue const *v, GODateConventions const *conv)
} else
serial = G_MAXINT;
}
if (serial < 0 && !gnm_datetime_allow_negative ())
serial = G_MAXINT;
return serial;
}
......
......@@ -8,6 +8,8 @@
G_BEGIN_DECLS
gboolean gnm_datetime_allow_negative (void);
gnm_float datetime_value_to_serial_raw (GnmValue const *v, GODateConventions const *conv);
/* These are date-only, no time. */
......
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