Skip to content

Instantly share code, notes, and snippets.

@etoxin
Created October 27, 2016 01:05
Show Gist options
  • Save etoxin/e0c48ea08fd456ade1187c2f50677589 to your computer and use it in GitHub Desktop.
Save etoxin/e0c48ea08fd456ade1187c2f50677589 to your computer and use it in GitHub Desktop.
parseISOString.js
/**
* Parse an ISO string with or without an offset
* e.g. '2014-04-02T20:00:00-0600'
* '2014-04-02T20:00:00Z'
* '2014-02'
*
* Allows decimal seconds if supplied
* e.g. '2014-04-02T20:00:00.123-0600'
*
* If no offset is supplied (or it's Z), treat as UTC (per ECMA-262)
*
* If date only, e.g. '2014-04-02' or '2014-02', treat as UTC date (per ECMA-262)
* All parts after year are optional
* Don't allow two digit years to be converted to 20th century years
* @param {string} s - ISO 860 date string
*/
function parseISOString(s) {
var invalidDate = new Date(NaN);
var t = s.split(/\D+/g);
var hasOffset = /[-+]\d{4}$/.test(s);
// Whether decimal seconds are present changes the offset field and ms value
var hasDecimalSeconds = /[T ]\d{2}:\d{2}:\d{2}\.\d+/i.test(s);
var offset = hasDecimalSeconds? t[7] : t[6];
var offSign;
var yr = +t[0],
mo = t[1]? --t[1] : 0,
da = +t[2] || 1,
hr = +t[3] || 0,
min = +t[4] || 0,
sec = +t[5] || 0,
ms = hasDecimalSeconds? +t[6] : 0,
offSign = hasOffset? /-\d{4}$/.test(s)? 1 : -1 : 0,
offHr = hasOffset? offset/100 | 0 : 0,
offMin = hasOffset? offset%100 : 0;
// Ensure time values are in range, otherwise invalid date.
// Values can't be -ve as splitting on non-digit character
if (hr > 24 || min > 59 || sec > 59 || ms > 1000 || offHr > 24 || offMin > 59){
return invalidDate;
}
// Create a date object from date parts, check for validity
// Avoid two digit years being converted to 20th century
var d = new Date();
d.setUTCFullYear(yr, mo, da);
// Check that date values are valid
if (d.getUTCFullYear() != yr || d.getUTCDate() != da) {
return invalidDate;
}
// If there's an offset, apply it to minutes to get a UTC time value
min = hasOffset? +min + offSign * (offHr * 60 + offMin) : min;
// Set UTC time values of d
d.setUTCHours(hr, min, sec, ms);
return d;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment