spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
MM/DD/YYYY parsing for DATEVALUE
author
Ben Vogt <[email protected]>
date
2017-03-06 00:16:16
stats
2 file(s) changed, 70 insertions(+), 3 deletions(-)
files
src/RawFormulas/Date.ts
tests/FormulasTest.ts
  1diff --git a/src/RawFormulas/Date.ts b/src/RawFormulas/Date.ts
  2index c86f1c1..fbfd05b 100644
  3--- a/src/RawFormulas/Date.ts
  4+++ b/src/RawFormulas/Date.ts
  5@@ -48,9 +48,8 @@ var DATE = function (...values) {
  6  * @param values[0] date_string - The string representing the date. Understood formats include any date format which is
  7  * normally auto-converted when entered, without quotation marks, directly into a cell. Understood formats may depend on
  8  * region and language settings. Examples include:
  9- * "1999/1/13"
 10- * "12/13/1999"
 11- * "30/12/1999"
 12+ * "1999/1/13"              DONE
 13+ * "1/13/1999"              DONE
 14  * "1999/1/13 10am"
 15  * "1999/1/13 10:22"
 16  * "1999/1/13 10:10am"
 17@@ -98,6 +97,31 @@ var DATEVALUE = function (...values) : number {
 18     }
 19   }
 20 
 21+  // Check MM/DD/YYYY
 22+  if (m === undefined) {
 23+    // For reference: https://regex101.com/r/yHraci/5
 24+    var matches = dateString.match(/^\s*([1-9]|0[1-9]|1[0-2])\/([1-9]|[0-2][0-9]|3[0-1])\/(([0-9][0-9][0-9][0-9])|([1-9][0-9][0-9])|[0-9]{0,3})\s*$/);
 25+    if (matches && matches.length === 6) {
 26+      var years = parseInt(matches[3]);
 27+      var months = parseInt(matches[1]) - 1;
 28+      var days = parseInt(matches[2]) - 1;
 29+      var actualYear = years;
 30+      if (years >= 0 && years < 30) {
 31+        actualYear = Y2K_YEAR + years;
 32+      } else if (years >= 30 && years < 100) {
 33+        actualYear = FIRST_YEAR + years;
 34+      }
 35+      var tmpMoment = moment([actualYear])
 36+        .add(months, 'months');
 37+      // If we're specifying more days than there are in this month
 38+      if (days > tmpMoment.daysInMonth() - 1) {
 39+        throw new CellError(VALUE_ERROR, "DATEVALUE parameter '" + dateString + "' cannot be parsed to date/time.");
 40+      }
 41+      tmpMoment = tmpMoment.add(days, 'days');
 42+      m = tmpMoment;
 43+    }
 44+  }
 45+
 46   // If we've not been able to parse the date by now, then we cannot parse it at all.
 47   if (m === undefined || !m.isValid()) {
 48     throw new CellError(VALUE_ERROR, "DATEVALUE parameter '" + dateString + "' cannot be parsed to date/time.");
 49diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
 50index fe18ed7..28691d0 100644
 51--- a/tests/FormulasTest.ts
 52+++ b/tests/FormulasTest.ts
 53@@ -783,10 +783,47 @@ assertEquals(DATE(-1900, 1, 1).toNumber(), 2);
 54 
 55 
 56 // Test DATEVALUE
 57-// // m/d/yyyy
 58-// assertEquals(DATEVALUE("6/24/1992"), 33779);
 59-// assertEquals(DATEVALUE("06/24/1992"), 33779);
 60-// yyyy/m/d
 61+// MM/DD/YYYY
 62+assertEquals(DATEVALUE("6/24/92"), 33779);
 63+assertEquals(DATEVALUE("6/24/1992"), 33779);
 64+assertEquals(DATEVALUE("06/24/1992"), 33779);
 65+assertEquals(DATEVALUE("1/01/1999"), 36161);
 66+assertEquals(DATEVALUE("1/01/99"), 36161);
 67+assertEquals(DATEVALUE("1/01/2222"), 117610);
 68+assertEquals(DATEVALUE("9/02/1902"), 976);
 69+assertEquals(DATEVALUE("9/2/1902"), 976);
 70+assertEquals(DATEVALUE("11/3/4243"), 856071);
 71+assertEquals(DATEVALUE("  04/19/1992  "), 33713);
 72+assertEquals(DATEVALUE("5/20/1992"), 33744);
 73+assertEquals(DATEVALUE("6/21/1992"), 33776);
 74+assertEquals(DATEVALUE("9/29/1992"), 33876);
 75+assertEquals(DATEVALUE("1/24/1992"), 33627);
 76+assertEquals(DATEVALUE("12/21/1992"), 33959);
 77+assertEquals(DATEVALUE("01/31/1992"), 33634);
 78+assertEquals(DATEVALUE("1/13/1992"), 33616);
 79+assertEquals(DATEVALUE("2/29/2004"), 38046);
 80+assertEquals(DATEVALUE("2/28/2004"), 38045);
 81+assertEquals(DATEVALUE("2/28/004"), 38045);
 82+assertEquals(DATEVALUE("2/28/04"), 38045);
 83+assertEquals(DATEVALUE("2/28/4"), 38045);
 84+assertEquals(DATEVALUE("1/13/1999"), 36173);
 85+assertEquals(DATEVALUE("01/13/1999"), 36173);
 86+assertEquals(DATEVALUE("01/13/0999"), -329069);
 87+assertEquals(DATEVALUE("01/13/1200"), -255656);
 88+assertEquals(DATEVALUE("01/13/0029"), 47131);
 89+assertEquals(DATEVALUE("01/13/0030"), 10971);
 90+assertEquals(DATEVALUE("01/13/0044"), 16084);
 91+assertEquals(DATEVALUE("01/13/0050"), 18276);
 92+assertEquals(DATEVALUE("01/13/0097"), 35443);
 93+assertEquals(DATEVALUE("01/13/0099"), 36173);
 94+assertEquals(DATEVALUE("01/13/0000"), 36538);
 95+assertEquals(DATEVALUE("01/13/0101"), -657057);
 96+assertEquals(DATEVALUE("01/13/0100"), -657422);
 97+assertEquals(DATEVALUE("12/31/100"), -657070);
 98+assertEquals(DATEVALUE("11/10/122"), -649086);
 99+assertEquals(DATEVALUE("1/22/2222"), 117631);
100+assertEquals(DATEVALUE("1/22/222"), -612854);
101+// YYYY/MM/DD
102 assertEquals(DATEVALUE("1992/6/24"), 33779);
103 assertEquals(DATEVALUE("1992/06/24"), 33779);
104 assertEquals(DATEVALUE("1999/1/01"), 36161);