gnumeric r17024 - in trunk: . plugins/fn-date src



Author: mortenw
Date: Mon Dec 15 21:41:48 2008
New Revision: 17024
URL: http://svn.gnome.org/viewvc/gnumeric?rev=17024&view=rev

Log:
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.



Modified:
   trunk/ChangeLog
   trunk/plugins/fn-date/ChangeLog
   trunk/plugins/fn-date/functions.c
   trunk/src/gnm-datetime.c
   trunk/src/gnm-datetime.h

Modified: trunk/plugins/fn-date/functions.c
==============================================================================
--- trunk/plugins/fn-date/functions.c	(original)
+++ trunk/plugins/fn-date/functions.c	Mon Dec 15 21:41:48 2008
@@ -70,12 +70,15 @@
 }
 
 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 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 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 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);
-	}
 }
 
 /***************************************************************************/

Modified: trunk/src/gnm-datetime.c
==============================================================================
--- trunk/src/gnm-datetime.c	(original)
+++ trunk/src/gnm-datetime.c	Mon Dec 15 21:41:48 2008
@@ -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 @@
 		} else
 			serial = G_MAXINT;
 	}
+
+	if (serial < 0 && !gnm_datetime_allow_negative ())
+		serial = G_MAXINT;
+
 	return serial;
 }
 

Modified: trunk/src/gnm-datetime.h
==============================================================================
--- trunk/src/gnm-datetime.h	(original)
+++ trunk/src/gnm-datetime.h	Mon Dec 15 21:41:48 2008
@@ -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.  */



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