From 42e6dbc60337b692d75a39bbda95de05a82c1944 Mon Sep 17 00:00:00 2001 From: jeff Date: Tue, 8 May 2018 08:50:33 -0700 Subject: [PATCH 1/2] Dates serialize to ISO format. ISO date string deserialize to Dates when `dynamicTyping` is true. --- papaparse.js | 12 ++++++++---- tests/test-cases.js | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/papaparse.js b/papaparse.js index eb1a6ed..41dc1ba 100755 --- a/papaparse.js +++ b/papaparse.js @@ -408,6 +408,9 @@ if (typeof str === 'undefined' || str === null) return ''; + if (str.constructor === Date) + return JSON.stringify(str).slice(1, 25); + str = str.toString().replace(quoteCharRegex, _quoteChar + _quoteChar); var needsQuotes = (typeof _quotes === 'boolean' && _quotes) @@ -954,6 +957,7 @@ { // One goal is to minimize the use of regular expressions... var FLOAT = /^\s*-?(\d*\.?\d+|\d+\.?\d*)(e[-+]?\d+)?\s*$/i; + var ISO_DATE = /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/; var self = this; var _stepCounter = 0; // Number of times step was called (number of rows parsed) @@ -1128,12 +1132,12 @@ return true; else if (value === 'false' || value === 'FALSE') return false; - else if(FLOAT.test(value)) { + else if (FLOAT.test(value)) return parseFloat(value); - } - else { + else if (ISO_DATE.test(value)) + return new Date(value); + else return (value === '' ? null : value); - } } return value; } diff --git a/tests/test-cases.js b/tests/test-cases.js index b10c386..a00a56d 100644 --- a/tests/test-cases.js +++ b/tests/test-cases.js @@ -872,6 +872,15 @@ var PARSE_TESTS = [ errors: [] } }, + { + description: "Dynamic typing converts ISO date strings to Dates", + input: 'ISO date,long date\r\n2018-05-04T21:08:03.269Z,Fri May 04 2018 14:08:03 GMT-0700 (PDT)\r\n2018-05-08T15:20:22.642Z,Tue May 08 2018 08:20:22 GMT-0700 (PDT)', + config: { dynamicTyping: true }, + expected: { + data: [["ISO date", "long date"], [new Date("2018-05-04T21:08:03.269Z"), "Fri May 04 2018 14:08:03 GMT-0700 (PDT)"], [new Date("2018-05-08T15:20:22.642Z"), "Tue May 08 2018 08:20:22 GMT-0700 (PDT)"]], + errors: [] + } + }, { description: "Blank line at beginning", input: '\r\na,b,c\r\nd,e,f', @@ -1422,6 +1431,11 @@ var UNPARSE_TESTS = [ input: [{"Col1": "a", "Col2": "b", "Col3": "c"}, {"Col1": "d", "Col2": "e", "Col3": "f"}], config: {header: false}, expected: 'a,b,c\r\nd,e,f' + }, + { + description: "Date handling", + input: [{date: new Date("2018-05-04T21:08:03.269Z"), "not a date": 16}, {date: new Date("Tue May 08 2018 08:20:22 GMT-0700 (PDT)"), "not a date": 32}], + expected: 'date,not a date\r\n2018-05-04T21:08:03.269Z,16\r\n2018-05-08T15:20:22.000Z,32' } ]; From 074ada79e4130f9ceb68c7800b6ac93af8d999dd Mon Sep 17 00:00:00 2001 From: jeff Date: Fri, 1 Jun 2018 09:35:32 -0700 Subject: [PATCH 2/2] Test for Dates with `instanceof`. --- papaparse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/papaparse.js b/papaparse.js index 41dc1ba..94e9532 100755 --- a/papaparse.js +++ b/papaparse.js @@ -408,7 +408,7 @@ if (typeof str === 'undefined' || str === null) return ''; - if (str.constructor === Date) + if (str instanceof Date) return JSON.stringify(str).slice(1, 25); str = str.toString().replace(quoteCharRegex, _quoteChar + _quoteChar);