spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
YYYY/MM/DD HH:mm parsing for DATEVALUE
author
Ben Vogt <[email protected]>
date
2017-03-10 04:52:18
stats
3 file(s) changed, 41 insertions(+), 106 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 4d264d7..ccffb35 100644
  3--- a/src/RawFormulas/Date.ts
  4+++ b/src/RawFormulas/Date.ts
  5@@ -3,7 +3,6 @@ import * as moment from "moment";
  6 import * as Formula from "formulajs"
  7 import {
  8   ArgsChecker,
  9-  RegExUtil,
 10   TypeCaster
 11 } from "./Utils";
 12 import {
 13@@ -92,8 +91,7 @@ var DATEVALUE = function (...values) : number {
 14       if (days > tmpMoment.daysInMonth() - 1) {
 15         throw new CellError(VALUE_ERROR, "DATEVALUE parameter '" + dateString + "' cannot be parsed to date/time.");
 16       }
 17-      tmpMoment = tmpMoment.add(days, 'days');
 18-      m = tmpMoment;
 19+      m = tmpMoment.add(days, 'days');
 20     }
 21   }
 22 
 23@@ -117,8 +115,7 @@ var DATEVALUE = function (...values) : number {
 24       if (days > tmpMoment.daysInMonth() - 1) {
 25         throw new CellError(VALUE_ERROR, "DATEVALUE parameter '" + dateString + "' cannot be parsed to date/time.");
 26       }
 27-      tmpMoment = tmpMoment.add(days, 'days');
 28-      m = tmpMoment;
 29+      m = tmpMoment.add(days, 'days');
 30     }
 31   }
 32 
 33@@ -142,14 +139,34 @@ var DATEVALUE = function (...values) : number {
 34       if (days > tmpMoment.daysInMonth() - 1) {
 35         throw new CellError(VALUE_ERROR, "DATEVALUE parameter '" + dateString + "' cannot be parsed to date/time.");
 36       }
 37-      tmpMoment = tmpMoment.add(days, 'days');
 38-      m = tmpMoment;
 39+      m = tmpMoment.add(days, 'days');
 40     }
 41   }
 42 
 43   // Check YYYY/MM/DD HH:mm
 44   if (m === undefined) {
 45-    // TODO: This.
 46+    // For reference: https://regex101.com/r/xsqttP/4
 47+    var matches = dateString.match(/^\s*(([0-9][0-9][0-9][0-9])|([1-9][0-9][0-9]))\/([1-9]|0[1-9]|1[0-2])\/([1-9]|[0-2][0-9]|3[0-1])\s*([0-9]{1,}):\s*([0-9]{2,})\s*$/);
 48+    if (matches && matches.length === 8) {
 49+      var years = parseInt(matches[1]);
 50+      var months = parseInt(matches[4]) - 1; // Months are zero indexed.
 51+      var days = parseInt(matches[5]) - 1;// Months are zero indexed.
 52+      var hours = parseInt(matches[6]);
 53+      var minutes = parseInt(matches[7]);
 54+      var actualYear = years;
 55+      if (years >= 0 && years < 30) {
 56+        actualYear = Y2K_YEAR + years;
 57+      } else if (years >= 30 && years < 100) {
 58+        actualYear = FIRST_YEAR + years;
 59+      }
 60+      var tmpMoment = moment([actualYear])
 61+        .add(months, 'months');
 62+      // If we're specifying more days than there are in this month
 63+      if (days > tmpMoment.daysInMonth() - 1) {
 64+        throw new CellError(VALUE_ERROR, "DATEVALUE parameter '" + dateString + "' cannot be parsed to date/time.");
 65+      }
 66+      m = tmpMoment.add(days, 'days').add(hours, 'hours').add(minutes, 'minutes');
 67+    }
 68   }
 69 
 70   // Check YYYY/MM/DD HH:mm(am|pm)
 71diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
 72index f206f35..975f2c6 100644
 73--- a/src/RawFormulas/Utils.ts
 74+++ b/src/RawFormulas/Utils.ts
 75@@ -363,77 +363,11 @@ class Serializer {
 76   }
 77 }
 78 
 79-/**
 80- * Static class to hold methods for parsing date-like strings.
 81- */
 82-class RegExUtil {
 83-  private static MONTH_DAY_YEAR_SLASH_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*$/;
 84-  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*$/;
 85-  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*$/;
 86-  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*$/;
 87-  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*$/;
 88-  private static MONTH_DAY_YEAR_TIMESTAMP_REGEX = /^.*$/;
 89-
 90-  /**
 91-   * Match dates in the form "mm/dd/yyyy" or "m/d/yyyy".
 92-   * @param dateString to match
 93-   * @returns {RegExpMatchArray} matches or null.
 94-   */
 95-  static matchDateStringMonthDayYearSlash(dateString : string) : RegExpMatchArray | null {
 96-    return dateString.match(this.MONTH_DAY_YEAR_SLASH_REGEX);
 97-  }
 98-
 99-  /**
100-   * Match dates in the form "dd/mm/yyyy" or "d/m/yyyy".
101-   * @param dateString to match
102-   * @returns {RegExpMatchArray} matches or null
103-   */
104-  static matchDateStringDayMonthYearSlash(dateString : string) : RegExpMatchArray | null {
105-    return dateString.match(this.DAY_MONTH_YEAR_SLASH_REGEX);
106-  }
107-
108-  /**
109-   * Match dates in the form "yyyy/mm/dd" or "yyyy/m/d".
110-   * @param dateString to match
111-   * @returns {RegExpMatchArray} matches or null
112-   */
113-  static matchDateStringYearMonthDaySlash(dateString : string) : RegExpMatchArray | null {
114-    return dateString.match(this.YEAR_MONTH_DAY_SLASH_REGEX);
115-  }
116-
117-  /**
118-   * Match dates in the form "yyyy-mm-dd" or "yyyy-m-d".
119-   * @param dateString to match
120-   * @returns {RegExpMatchArray} matches or null
121-   */
122-  static matchDateStringYearMonthDayHyphen(dateString : string) : RegExpMatchArray | null {
123-    return dateString.match(this.YEAR_MONTH_DAY_HYPHEN_REGEX);
124-  }
125-
126-  /**
127-   * Match dates in the form "mm-dd-yyyy" or "m-d-yyyy".
128-   * @param dateString to match
129-   * @returns {RegExpMatchArray} matches or null
130-   */
131-  static matchDateStringMonthDayYearHyphen(dateString : string) : RegExpMatchArray | null {
132-    return dateString.match(this.MONTH_DAY_YEAR_HYPHEN_REGEX);
133-  }
134-
135-  /**
136-   * Matches dates in the form "mm-dd-yyyy XX:XX:XX:XXX"
137-   * @param dateString
138-   * @returns {RegExpMatchArray}
139-   */
140-  static matchDateStringMonthDayYearTimeStampAll(dateString: string) : RegExpMatchArray | null {
141-    return dateString.match(this.MONTH_DAY_YEAR_TIMESTAMP_REGEX);
142-  };
143-}
144 
145 export {
146   ArgsChecker,
147   CriteriaFunctionFactory,
148   Filter,
149-  RegExUtil,
150   Serializer,
151   TypeCaster
152 }
153\ No newline at end of file
154diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
155index 91f6ac8..5f4b208 100644
156--- a/tests/FormulasTest.ts
157+++ b/tests/FormulasTest.ts
158@@ -911,40 +911,18 @@ catchAndAssertEquals(function() {
159 catchAndAssertEquals(function() {
160   DATEVALUE("2005/1/44 11am");// Out of range day for any month
161 }, ERRORS.VALUE_ERROR);
162-
163-
164-// // yyyy-m-d
165-// assertEquals(DATEVALUE("1992-6-24"), 33779);
166-// assertEquals(DATEVALUE("1992-06-24"), 33779);
167-// assertEquals(DATEVALUE("1999-1-01"), 36161);
168-// assertEquals(DATEVALUE("2222-1-01"), 117610);
169-// assertEquals(DATEVALUE("1902-9-02"), 976);
170-// assertEquals(DATEVALUE("1902-9-2"), 976);
171-// assertEquals(DATEVALUE("4243-11-3"), 856071);
172-// assertEquals(DATEVALUE("  1992-04-19  "), 33713);
173-// assertEquals(DATEVALUE("1992-5-20"), 33744);
174-// assertEquals(DATEVALUE("1992-6-21"), 33776);
175-// assertEquals(DATEVALUE("1992-9-29"), 33876);
176-// assertEquals(DATEVALUE("1992-1-24"), 33627);
177-// assertEquals(DATEVALUE("1992-12-21"), 33959);
178-// assertEquals(DATEVALUE("1992-01-31"), 33634);
179-// assertEquals(DATEVALUE("1992-1-13"), 33616);
180-// // m-d-yyyy
181-// assertEquals(DATEVALUE("6-24-1992"), 33779);
182-// assertEquals(DATEVALUE("06-24-1992"), 33779);
183-// assertEquals(DATEVALUE("1-01-1999"), 36161);
184-// assertEquals(DATEVALUE("1-01-2222"), 117610);
185-// assertEquals(DATEVALUE("9-02-1902"), 976);
186-// assertEquals(DATEVALUE("9-2-1902"), 976);
187-// assertEquals(DATEVALUE("11-3-4243"), 856071);
188-// assertEquals(DATEVALUE("  04-19-1992  "), 33713);
189-// assertEquals(DATEVALUE("5-20-1992"), 33744);
190-// assertEquals(DATEVALUE("6-21-1992"), 33776);
191-// assertEquals(DATEVALUE("9-29-1992"), 33876);
192-// assertEquals(DATEVALUE("1-24-1992"), 33627);
193-// assertEquals(DATEVALUE("12-21-1992"), 33959);
194-// assertEquals(DATEVALUE("01-31-1992"), 33634);
195-// assertEquals(DATEVALUE("1-13-1992"), 33616);
196+// YYYY/MM/DD HH:mm
197+assertEquals(DATEVALUE("1992/6/24 00:00"), 33779);
198+assertEquals(DATEVALUE("1992/6/24 0:00"), 33779);
199+assertEquals(DATEVALUE("1992/6/24 10:10"), 33779);
200+assertEquals(DATEVALUE("1992/6/24 16:22"), 33779);
201+assertEquals(DATEVALUE("1992/6/24 25:10"), 33780);
202+assertEquals(DATEVALUE("1992/6/24 23:60"), 33780);
203+assertEquals(DATEVALUE("1992/6/24 24:00"), 33780);
204+assertEquals(DATEVALUE("1992/6/24 23:59"), 33779);
205+assertEquals(DATEVALUE("1999/1/13 10:11111111"), 43889);
206+assertEquals(DATEVALUE("1999/1/13 25000:22"), 37214);
207+assertEquals(DATEVALUE("1999/1/13 25000:    22"), 37214);
208 
209 
210