commit
message
Checking for '1-23-2012' style date formats in DATEVAUE
author
Ben Vogt <[email protected]>
date
2017-02-26 21:44:21
stats
3 file(s) changed,
53 insertions(+),
14 deletions(-)
files
src/RawFormulas/Date.ts
src/RawFormulas/Utils.ts
tests/FormulasTest.ts
1diff --git a/src/RawFormulas/Date.ts b/src/RawFormulas/Date.ts
2index 6369a7e..83a57a9 100644
3--- a/src/RawFormulas/Date.ts
4+++ b/src/RawFormulas/Date.ts
5@@ -8,6 +8,7 @@ import {
6 } from "./Utils";
7 import {
8 NUM_ERROR,
9+ VALUE_ERROR,
10 CellError
11 } from "../Errors";
12 import {
13@@ -40,30 +41,31 @@ var DATE = function (...values) {
14 /**
15 * Converts a provided date string in a known format to a date value.
16 * @param values[0] date_string - The string representing the date. Understood formats include any date format which is
17- * normally autoconverted when entered, without quotation marks, directly into a cell. Understood formats may depend on
18- * region and language settings. Examples include: "1/23/2012", "1/23/2012 8:10:30", "2012/1/23", "2012-1-23"
19- * @returns {number}
20+ * normally auto-converted when entered, without quotation marks, directly into a cell. Understood formats may depend on
21+ * region and language settings. Examples include: "1/23/2012", "2012/1/23", "2012-1-23", "1-23-2012", "1/23/2012 8PM",
22+ * "1/23/2012 8:10:30", "1/23/2012 8:10", "1/23/2012 8:10:300000000"
23+ * @returns {number} of days since 1900/1/1
24 * @constructor
25 */
26 var DATEVALUE = function (...values) : number {
27 ArgsChecker.checkLength(values, 1);
28 var dateString = TypeCaster.firstValueAsString(values[0]);
29- var dateNumber;
30+ var m;
31 if (RegExUtil.matchDateStringYearMonthDaySlash(dateString)) { // Check "2012/1/23"
32- dateNumber = new ExcelDate(moment(dateString, "Y/M/D")).toNumber();
33+ m = moment(dateString, "Y/M/D");
34 } else if (RegExUtil.matchDateStringYearMonthDayHyphen(dateString)) { // Check "2012-1-23"
35- dateNumber = new ExcelDate(moment(dateString, "Y-M-D")).toNumber();
36+ m = moment(dateString, "Y-M-D");
37 } else if (RegExUtil.matchDateStringMonthDayYearSlash(dateString)) { // Check "1/23/2012"
38- dateNumber = new ExcelDate(moment(dateString, "M/D/Y")).toNumber();
39- }
40- if (dateNumber === undefined) {
41- // TODO: Throw error that we couldn't parse the dateString.
42+ m = moment(dateString, "M/D/Y");
43+ } else if (RegExUtil.matchDateStringMonthDayYearHyphen(dateString)) { // Check "1-23-2012"
44+ m = moment(dateString, "M-D-Y");
45+ } else if (RegExUtil.matchDateStringMonthDayYearTimeStampAll(dateString)) { // Check "1/23/2012 8:10", "1-23-2012 8:10", "1/23/2012 8PM", etc.
46+
47 }
48- if (dateNumber < 0) {
49- throw new CellError(NUM_ERROR, "DATEVALUE evaluates to an out of range value " + dateNumber
50- + ". It should be greater than or equal to 0.");
51+ if (m === undefined || !m.isValid()) {
52+ throw new CellError(VALUE_ERROR, "DATEVALUE parameter '" + dateString + "' cannot be parsed to date/time.");
53 }
54- return dateNumber;
55+ return new ExcelDate(m).toNumber();
56 };
57
58
59diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
60index b98d7eb..f206f35 100644
61--- a/src/RawFormulas/Utils.ts
62+++ b/src/RawFormulas/Utils.ts
63@@ -371,6 +371,8 @@ class RegExUtil {
64 private static DAY_MONTH_YEAR_SLASH_REGEX = /^\s*([1-9]|[0-2][0-9]|3[0-1])\/([1-9]|0[1-9]|1[0-2])\/([1-9][0-9][0-9][0-9])\s*$/;
65 private static YEAR_MONTH_DAY_SLASH_REGEX = /^\s*([1-9][0-9][0-9][0-9])\/([1-9]|0[1-9]|1[0-2])\/([1-9]|[0-2][0-9]|3[0-1])\s*$/;
66 private static YEAR_MONTH_DAY_HYPHEN_REGEX = /^\s*([1-9][0-9][0-9][0-9])-([1-9]|0[1-9]|1[0-2])-([1-9]|[0-2][0-9]|3[0-1])\s*$/;
67+ private static MONTH_DAY_YEAR_HYPHEN_REGEX = /^\s*([1-9]|0[1-9]|1[0-2])-([1-9]|[0-2][0-9]|3[0-1])-([1-9][0-9][0-9][0-9])\s*$/;
68+ private static MONTH_DAY_YEAR_TIMESTAMP_REGEX = /^.*$/;
69
70 /**
71 * Match dates in the form "mm/dd/yyyy" or "m/d/yyyy".
72@@ -408,6 +410,23 @@ class RegExUtil {
73 return dateString.match(this.YEAR_MONTH_DAY_HYPHEN_REGEX);
74 }
75
76+ /**
77+ * Match dates in the form "mm-dd-yyyy" or "m-d-yyyy".
78+ * @param dateString to match
79+ * @returns {RegExpMatchArray} matches or null
80+ */
81+ static matchDateStringMonthDayYearHyphen(dateString : string) : RegExpMatchArray | null {
82+ return dateString.match(this.MONTH_DAY_YEAR_HYPHEN_REGEX);
83+ }
84+
85+ /**
86+ * Matches dates in the form "mm-dd-yyyy XX:XX:XX:XXX"
87+ * @param dateString
88+ * @returns {RegExpMatchArray}
89+ */
90+ static matchDateStringMonthDayYearTimeStampAll(dateString: string) : RegExpMatchArray | null {
91+ return dateString.match(this.MONTH_DAY_YEAR_TIMESTAMP_REGEX);
92+ };
93 }
94
95 export {
96diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
97index a0586a8..7a81e27 100644
98--- a/tests/FormulasTest.ts
99+++ b/tests/FormulasTest.ts
100@@ -812,6 +812,22 @@ assertEquals(DATEVALUE("1992-1-24"), 33627);
101 assertEquals(DATEVALUE("1992-12-21"), 33959);
102 assertEquals(DATEVALUE("1992-01-31"), 33634);
103 assertEquals(DATEVALUE("1992-1-13"), 33616);
104+// m-d-yyyy
105+assertEquals(DATEVALUE("6-24-1992"), 33779);
106+assertEquals(DATEVALUE("06-24-1992"), 33779);
107+assertEquals(DATEVALUE("1-01-1999"), 36161);
108+assertEquals(DATEVALUE("1-01-2222"), 117610);
109+assertEquals(DATEVALUE("9-02-1902"), 976);
110+assertEquals(DATEVALUE("9-2-1902"), 976);
111+assertEquals(DATEVALUE("11-3-4243"), 856071);
112+assertEquals(DATEVALUE(" 04-19-1992 "), 33713);
113+assertEquals(DATEVALUE("5-20-1992"), 33744);
114+assertEquals(DATEVALUE("6-21-1992"), 33776);
115+assertEquals(DATEVALUE("9-29-1992"), 33876);
116+assertEquals(DATEVALUE("1-24-1992"), 33627);
117+assertEquals(DATEVALUE("12-21-1992"), 33959);
118+assertEquals(DATEVALUE("01-31-1992"), 33634);
119+assertEquals(DATEVALUE("1-13-1992"), 33616);
120
121
122