From d8cd62ed215bb6acd9d92bfd0e124879b2de0a53 Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Thu, 26 Jul 2018 16:59:50 -0400 Subject: [PATCH] Parse date into ISO 8601 format instead of seconds since UTC epoch Fix #14 by not converting to local or UTC date, instead slightly modifying DateTime strings into easy-to-parse ISO 8601 format. When a DateTime string follows the EXIF spec, we map some colons to dashes to conform to ISO 8601. The other supported format was ISO 8601, so we don't do anything in this case. --- lib/date.js | 86 ++++++---------------------------------------------- package.json | 3 +- 2 files changed, 12 insertions(+), 77 deletions(-) diff --git a/lib/date.js b/lib/date.js index fb72673..96b6366 100644 --- a/lib/date.js +++ b/lib/date.js @@ -1,84 +1,18 @@ -function parseNumber(s) { - return parseInt(s, 10); -} - -//in seconds -var hours = 3600; -var minutes = 60; - -//take date (year, month, day) and time (hour, minutes, seconds) digits in UTC -//and return a timestamp in seconds -function parseDateTimeParts(dateParts, timeParts) { - dateParts = dateParts.map(parseNumber); - timeParts = timeParts.map(parseNumber); - var year = dateParts[0]; - var month = dateParts[1] - 1; - var day = dateParts[2]; - var hours = timeParts[0]; - var minutes = timeParts[1]; - var seconds = timeParts[2]; - var date = Date.UTC(year, month, day, hours, minutes, seconds, 0); - var timestamp = date / 1000; - return timestamp; -} - -//parse date with "2004-09-04T23:39:06-08:00" format, -//one of the formats supported by ISO 8601, and -//convert to utc timestamp in seconds -function parseDateWithTimezoneFormat(dateTimeStr) { - - var dateParts = dateTimeStr.substr(0, 10).split('-'); - var timeParts = dateTimeStr.substr(11, 8).split(':'); - var timezoneStr = dateTimeStr.substr(19, 6); - var timezoneParts = timezoneStr.split(':').map(parseNumber); - var timezoneOffset = (timezoneParts[0] * hours) + - (timezoneParts[1] * minutes); - - var timestamp = parseDateTimeParts(dateParts, timeParts); - //minus because the timezoneOffset describes - //how much the described time is ahead of UTC - timestamp -= timezoneOffset; - - if(typeof timestamp === 'number' && !isNaN(timestamp)) { - return timestamp; - } -} - -//parse date with "YYYY:MM:DD hh:mm:ss" format, convert to utc timestamp in seconds -function parseDateWithSpecFormat(dateTimeStr) { - var parts = dateTimeStr.split(' '), - dateParts = parts[0].split(':'), - timeParts = parts[1].split(':'); - - var timestamp = parseDateTimeParts(dateParts, timeParts); - - if(typeof timestamp === 'number' && !isNaN(timestamp)) { - return timestamp; - } -} - function parseExifDate(dateTimeStr) { - //some easy checks to determine two common date formats + //some easy checks to determine common date formats //is the date in the standard "YYYY:MM:DD hh:mm:ss" format? - var isSpecFormat = dateTimeStr.length === 19 && - dateTimeStr.charAt(4) === ':'; - //is the date in the non-standard format, - //"2004-09-04T23:39:06-08:00" to include a timezone? - var isTimezoneFormat = dateTimeStr.length === 25 && - dateTimeStr.charAt(10) === 'T'; - var timestamp; - - if(isTimezoneFormat) { - return parseDateWithTimezoneFormat(dateTimeStr); - } - else if(isSpecFormat) { - return parseDateWithSpecFormat(dateTimeStr); - } + //if so, convert to ISO 8601 by replacing first two ':'s with '-'s + if (dateTimeStr.length === 19 && + dateTimeStr.charAt(4) === ':' && + dateTimeStr.charAt(7) === ':') { + dateTimeStr = dateTimeStr.slice(0, 4) + '-' + + dateTimeStr.slice(5, 7) + '-' + dateTimeStr.slice(8); + } + + return dateTimeStr; } module.exports = { - parseDateWithSpecFormat: parseDateWithSpecFormat, - parseDateWithTimezoneFormat: parseDateWithTimezoneFormat, parseExifDate: parseExifDate }; diff --git a/package.json b/package.json index 11dfcd0..9558f75 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "devDependencies": { "browserify": "^7.0.0", - "uglify-js": "^2.4.15" + "uglify-js": "^2.4.15", + "nodeunit": "^0.11.3" } }