[gnumeric] Number match: improve parsing of dates.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Number match: improve parsing of dates.
- Date: Wed, 19 May 2010 18:15:21 +0000 (UTC)
commit f5e42d2fd1faf7ee319ad6cfb753e42083fe378a
Author: Morten Welinder <terra gnome org>
Date: Wed May 19 14:14:46 2010 -0400
Number match: improve parsing of dates.
ChangeLog | 9 +++++++++
NEWS | 2 ++
src/number-match.c | 44 ++++++++++++++++++++++++++++++++------------
3 files changed, 43 insertions(+), 12 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ed44b2e..66cf310 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-05-19 Morten Welinder <terra gnome org>
+
+ * src/number-match.c (handle_int): Impose a length restriction
+ too. All callers changed.
+ (format_match_datetime): Accepts "Jan 2010" and "January 2010"
+ too.
+ (valid_dmy): New function.
+ (format_match_datetime): Use valid_dmy over g_date_valid_dmy.
+
2010-05-18 Morten Welinder <terra gnome org>
* src/collect.c (create_caches): Hook recalc-clear-caches.
diff --git a/NEWS b/NEWS
index e82f92b..fad847b 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ Jean:
Morten:
* Linear regression test suite.
* Fix TABLE problem. [#618829]
+ * Handle "Jan 2010" and "January 2010" better.
+ * Fix date parsing problems for invalid years.
Sameer Morar:
* Fix sheet order dialog layout. [#619056]
diff --git a/src/number-match.c b/src/number-match.c
index 44dcb22..9b068cd 100644
--- a/src/number-match.c
+++ b/src/number-match.c
@@ -200,6 +200,8 @@ datetime_locale_setup (char const *lc_time)
* "Dec/1"
* "December 1"
* "Dec-1"
+ * "Jan 2010"
+ * "January 2010"
*/
s = g_strconcat ("^(",
p_MMMM->str,
@@ -331,18 +333,20 @@ find_month (GORegmatch const *pm)
}
static int
-handle_int (char const *text, GORegmatch const *pm, int min, int max)
+handle_int (char const *text, GORegmatch const *pm, int min, int max, int maxlen)
{
int i = 0;
char const *p = text + pm->rm_so;
char const *end = text + pm->rm_eo;
+ int len = 0;
while (p != end) {
gunichar uc = g_utf8_get_char (p);
p = g_utf8_next_char (p);
i = (10 * i) + g_unichar_digit_value (uc);
+ len++;
- if (i > max)
+ if (i > max || len > maxlen)
return -1;
}
@@ -355,13 +359,13 @@ handle_int (char const *text, GORegmatch const *pm, int min, int max)
static int
handle_day (char const *text, GORegmatch const *pm)
{
- return handle_int (text, pm, 1, 31);
+ return handle_int (text, pm, 1, 31, 2);
}
static int
handle_month (char const *text, GORegmatch const *pm)
{
- return handle_int (text, pm, 1, 12);
+ return handle_int (text, pm, 1, 12, 2);
}
static int
@@ -380,7 +384,7 @@ handle_year (char const *text, GORegmatch const *pm)
if (pm->rm_so == pm->rm_eo)
return current_year ();
- y = handle_int (text, pm, 0, 9999);
+ y = handle_int (text, pm, 0, 9999, 4);
if (y < 0)
return -1;
@@ -578,6 +582,14 @@ format_match_time (char const *text, gboolean allow_elapsed,
return v;
}
+static gboolean
+valid_dmy (int d, int m, int y)
+{
+ /* Avoid sign-induced problem. d and m are capped. */
+ return y >= 0 && g_date_valid_dmy (d, m, y);
+}
+
+
static GnmValue *
format_match_datetime (char const *text,
GODateConventions const *date_conv,
@@ -616,8 +628,16 @@ format_match_datetime (char const *text,
month = find_month (&match[2]);
if (month == -1) month = find_month (&match[2 + 12]);
day = handle_day (text, match + 27);
- year = handle_year (text, match + 30);
- if (g_date_valid_dmy (day, month, year)) {
+ if (day == -1 &&
+ match[27].rm_eo - match[27].rm_so >= 4 &&
+ match[28].rm_so == match[28].rm_eo) {
+ /* Only one number with 4+ digits -- might be a year. */
+ year = handle_year (text, match + 27);
+ day = 1;
+ } else {
+ year = handle_year (text, match + 30);
+ }
+ if (valid_dmy (day, month, year)) {
date_format = gnm_format_frob_slashes ("mmm/dd/yyyy");
text += match[0].rm_eo;
goto got_date;
@@ -633,7 +653,7 @@ format_match_datetime (char const *text,
month = find_month (&match[4]);
if (month == -1) month = find_month (&match[4 + 12]);
year = handle_year (text, match + 30);
- if (g_date_valid_dmy (day, month, year)) {
+ if (valid_dmy (day, month, year)) {
date_format = g_strdup ("d-mmm-yyyy");
text += match[0].rm_eo;
goto got_date;
@@ -647,7 +667,7 @@ format_match_datetime (char const *text,
year = handle_year (text, match + 1);
month = handle_month (text, match + 2);
day = handle_day (text, match + 3);
- if (g_date_valid_dmy (day, month, year)) {
+ if (valid_dmy (day, month, year)) {
date_format = g_strdup ("yyyy-mmm-dd");
text += match[3].rm_eo;
if (*text == ':')
@@ -663,7 +683,7 @@ format_match_datetime (char const *text,
year = handle_year (text, match + 1);
month = handle_month (text, match + 2);
day = handle_day (text, match + 3);
- if (g_date_valid_dmy (day, month, year)) {
+ if (valid_dmy (day, month, year)) {
date_format = g_strdup ("yyyy-mmm-dd");
text += match[0].rm_eo;
goto got_date;
@@ -682,7 +702,7 @@ format_match_datetime (char const *text,
day = handle_day (text, match + 1);
}
year = handle_year (text, match + 3);
- if (g_date_valid_dmy (day, month, year)) {
+ if (valid_dmy (day, month, year)) {
date_format = gnm_format_frob_slashes (month_before_day
? "m/d/yyyy"
: "d/m/yyyy");
@@ -724,7 +744,7 @@ format_match_datetime (char const *text,
date_format = gnm_format_frob_slashes ("d/m/yyyy");
} else
year = month = day = -1;
- if (g_date_valid_dmy (day, month, year)) {
+ if (valid_dmy (day, month, year)) {
text += match[0].rm_eo;
goto got_date;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]