Created
October 27, 2016 01:05
-
-
Save etoxin/e0c48ea08fd456ade1187c2f50677589 to your computer and use it in GitHub Desktop.
parseISOString.js
This file contains hidden or 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
/** | |
* 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