forked from bwindels/exif-parser
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Parse date into ISO 8601 format instead of seconds since UTC epoch
Fix bwindels#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.
- Loading branch information
Showing
1 changed file
with
10 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
}; |