From d8eeba251c7743a003d900ab8baa07ba275938a8 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 9 Jan 2023 11:59:43 +0100 Subject: [PATCH 1/6] Add option to keep timezone info in dates --- src/index.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 95ddbe3..3df328b 100644 --- a/src/index.js +++ b/src/index.js @@ -39,6 +39,23 @@ function isFile(value, isReactNative) { ); } +function toTzIsoString(date) { + var tzo = -date.getTimezoneOffset(), + dif = tzo >= 0 ? '+' : '-', + pad = function(num) { + return (num < 10 ? '0' : '') + num; + }; + + return date.getFullYear() + + '-' + pad(date.getMonth() + 1) + + '-' + pad(date.getDate()) + + 'T' + pad(date.getHours()) + + ':' + pad(date.getMinutes()) + + ':' + pad(date.getSeconds()) + + dif + pad(Math.floor(Math.abs(tzo) / 60)) + + ':' + pad(Math.abs(tzo) % 60); +} + function initCfg(value) { return isUndefined(value) ? false : value; } @@ -53,6 +70,7 @@ function serialize(obj, cfg, fd, pre) { cfg.allowEmptyArrays = initCfg(cfg.allowEmptyArrays); cfg.noFilesWithArrayNotation = initCfg(cfg.noFilesWithArrayNotation); cfg.dotsForObjectNotation = initCfg(cfg.dotsForObjectNotation); + cfg.dateWithTimezone = initCfg(cfg.dateWithTimezone); const isReactNative = typeof fd.getParts === 'function'; @@ -83,7 +101,11 @@ function serialize(obj, cfg, fd, pre) { fd.append(pre + '[]', ''); } } else if (isDate(obj)) { - fd.append(pre, obj.toISOString()); + if (cfg.dateWithTimezone) { + fd.append(pre, toTzIsoString(obj)); + } else { + fd.append(pre, obj.toISOString()); + } } else if (isObject(obj) && !isBlob(obj, isReactNative)) { Object.keys(obj).forEach((prop) => { const value = obj[prop]; From 90e7992edaaf90dd94689e4ec030ecda199f39e0 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 9 Jan 2023 12:08:22 +0100 Subject: [PATCH 2/6] Fixed toTzIsoString to keep ms data --- src/index.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/index.js b/src/index.js index 3df328b..c34f705 100644 --- a/src/index.js +++ b/src/index.js @@ -40,20 +40,12 @@ function isFile(value, isReactNative) { } function toTzIsoString(date) { - var tzo = -date.getTimezoneOffset(), - dif = tzo >= 0 ? '+' : '-', - pad = function(num) { - return (num < 10 ? '0' : '') + num; - }; - - return date.getFullYear() + - '-' + pad(date.getMonth() + 1) + - '-' + pad(date.getDate()) + - 'T' + pad(date.getHours()) + - ':' + pad(date.getMinutes()) + - ':' + pad(date.getSeconds()) + - dif + pad(Math.floor(Math.abs(tzo) / 60)) + - ':' + pad(Math.abs(tzo) % 60); + const off = date.getTimezoneOffset(); + const absoff = Math.abs(off); + return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) + + (off > 0 ? '-' : '+') + + Math.floor(absoff / 60).toFixed(0).padStart(2,'0') + ':' + + (absoff % 60).toString().padStart(2,'0')) } function initCfg(value) { From 24aff42f0dbd954f7c373d3770ce935112b61544 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 9 Jan 2023 12:09:56 +0100 Subject: [PATCH 3/6] Test dateWithTimezone option --- src/index.test.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/index.test.js b/src/index.test.js index 1304593..0ecce9c 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -291,6 +291,28 @@ test('Date', () => { expect(formData.get('foo')).toBe(foo.toISOString()); }); +test('Date with timezone', () => { + const toTzIsoString = (date) => { + const off = date.getTimezoneOffset(); + const absoff = Math.abs(off); + return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) + + (off > 0 ? '-' : '+') + + Math.floor(absoff / 60).toFixed(0).padStart(2,'0') + ':' + + (absoff % 60).toString().padStart(2,'0')) + } + const foo = new Date(2000, 0, 1, 1, 1, 1); + const formData = serialize({ + foo, + }, + { + dateWithTimezone: true, + }); + + expect(formData.append).toHaveBeenCalledTimes(1); + expect(formData.append).toHaveBeenCalledWith('foo', toTzIsoString(foo)); + expect(formData.get('foo')).toBe(toTzIsoString(foo)); +}); + test('File', () => { const foo = new File([], ''); const formData = serialize({ From 4c00be9626e64653e0e2fdfbefca99b3fb3de511 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 9 Jan 2023 12:15:34 +0100 Subject: [PATCH 4/6] Update types.d.ts --- types.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types.d.ts b/types.d.ts index 88746cb..38e3102 100644 --- a/types.d.ts +++ b/types.d.ts @@ -5,6 +5,7 @@ export type Options = { allowEmptyArrays?: boolean; noFilesWithArrayNotation?: boolean; dotsForObjectNotation?: boolean; + dateWithTimezone?: boolean; }; export function serialize( From 13962b9f59212f6df75a014118b1d2d802162b40 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 9 Jan 2023 14:00:48 +0100 Subject: [PATCH 5/6] Updated documentation --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d223435..5c79a0c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,12 @@ const options = { * defaults to false */ dotsForObjectNotation: false, + + /** + * display dates in local timezone, with the timezone offset dsplayed. + * otherwise, all dates will be converted to the UTC timezone + */ + dateWithTimezone: false, }; const formData = serialize( From e0ec8f59c4e9e32ed4df8e0fc03b8706c5502e06 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 9 Jan 2023 14:01:15 +0100 Subject: [PATCH 6/6] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c79a0c..81c5fb9 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ const options = { dotsForObjectNotation: false, /** - * display dates in local timezone, with the timezone offset dsplayed. + * display dates in local timezone, with the timezone offset displayed. * otherwise, all dates will be converted to the UTC timezone */ dateWithTimezone: false,