diff --git a/index.js b/index.js index 5baa894..06d99e5 100644 --- a/index.js +++ b/index.js @@ -18,7 +18,23 @@ module.exports.getJsDateFromExcel = (excelDate) => { const missingLeapYearDay = secondsInDay * 1000; const delta = excelDate - (25567 + 2); const parsed = delta * missingLeapYearDay; - const date = new Date(parsed) + const parsedDate = new Date(parsed); + + const fractionalDay = excelDate - Math.floor(excelDate) + 0.0000001; + let totalSeconds = Math.floor(secondsInDay * fractionalDay); + const seconds = totalSeconds % 60; + totalSeconds -= seconds; + const hours = Math.floor(totalSeconds / (60 * 60)); + const minutes = Math.floor(totalSeconds / 60) % 60; + + const date = new Date( + parsedDate.getFullYear(), + parsedDate.getMonth(), + parsedDate.getDate(), + hours, + minutes, + seconds + ); if (Object.prototype.toString.call(date) === "[object Date]" ) { if (isNaN(date.getTime())) { diff --git a/package-lock.json b/package-lock.json index 06ca56c..3d9c2c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1953,6 +1953,12 @@ "is-plain-obj": "^1.1.0" } }, + "mockdate": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.2.tgz", + "integrity": "sha512-ldfYSUW1ocqSHGTK6rrODUiqAFPGAg0xaHqYJ5tvj1hQyFsjuHpuWgWFTZWwDVlzougN/s2/mhDr8r5nY5xDpA==", + "dev": true + }, "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", diff --git a/package.json b/package.json index 7a4f503..1b34701 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ }, "homepage": "https://github.com/oleg-koval/excel-date-to-js#readme", "devDependencies": { + "mockdate": "^3.0.2", "semantic-release": "^15.13.24", "semantic-release-npm-github-publish": "^1.1.10", "tape": "^4.8.0" diff --git a/test/index.js b/test/index.js index 39375d5..90597f8 100644 --- a/test/index.js +++ b/test/index.js @@ -1,27 +1,63 @@ const test = require('tape'); +const mockDate = require('mockdate'); + const { getJsDateFromExcel } = require('../index'); test('should convert Excel date to JS date', function (t) { + mockDate.set('2020-05-19T22:00:00.000Z'); + const actual = getJsDateFromExcel(42510).toISOString(); - const expected = new Date('2016-05-20T00:00:00.000Z').toISOString(); + const expected = new Date('2016-05-19T22:00:00.000Z').toISOString(); + t.equal(actual, expected); + t.end() + + mockDate.reset(); +}); + +test('should convert Excel date to JS date', function (t) { + mockDate.set('2020-05-19T22:00:00.000Z'); + + const actual = getJsDateFromExcel(43078.416666666664).toISOString(); + const expected = new Date('2017-12-09T09:00:00.000Z').toISOString(); + t.equal(actual, expected); + t.end() + + mockDate.reset() +}); + +test('should convert Excel date to JS date (5/19/2013 21:29, from https://goo.gl/Ejbext)', function (t) { + mockDate.set('2020-05-19T22:00:00.000Z'); + + const actual = getJsDateFromExcel(41413.895150462966).toISOString(); + const expected = new Date('2013-05-19T19:29:01.000Z').toISOString(); t.equal(actual, expected); t.end() + + mockDate.reset() }); test('should convert return an error on wrong input', function (t) { + mockDate.set('2020-05-19T22:00:00.000Z'); + try { - const actual = getJsDateFromExcel('text'); + getJsDateFromExcel('text'); } catch ({ message }) { t.equal(message, 'wrong input format') } t.end() + + mockDate.reset() }); test('should convert return an error on wrong excel date', function (t) { + mockDate.set('2020-05-19T22:00:00.000Z'); + try { - const actual = getJsDateFromExcel(7312873827); + getJsDateFromExcel(7312873827); } catch ({ message }) { t.equal(message, 'wrong excel date input') } t.end() + + mockDate.reset() });