| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 | var some = require('../array/some');    var datePatterns = [        /^([0-9]{4})$/,                        // YYYY        /^([0-9]{4})-([0-9]{2})$/,             // YYYY-MM (YYYYMM not allowed)        /^([0-9]{4})-?([0-9]{2})-?([0-9]{2})$/ // YYYY-MM-DD or YYYYMMDD    ];    var ORD_DATE = /^([0-9]{4})-?([0-9]{3})$/; // YYYY-DDD    var timePatterns = [        /^([0-9]{2}(?:\.[0-9]*)?)$/,                      // HH.hh        /^([0-9]{2}):?([0-9]{2}(?:\.[0-9]*)?)$/,          // HH:MM.mm        /^([0-9]{2}):?([0-9]{2}):?([0-9]{2}(\.[0-9]*)?)$/ // HH:MM:SS.ss    ];    var DATE_TIME = /^(.+)T(.+)$/;    var TIME_ZONE = /^(.+)([+\-])([0-9]{2}):?([0-9]{2})$/;    function matchAll(str, patterns) {        var match;        var found = some(patterns, function(pattern) {            return !!(match = pattern.exec(str));        });        return found ? match : null;    }    function getDate(year, month, day) {        var date = new Date(Date.UTC(year, month, day));        // Explicitly set year to avoid Date.UTC making dates < 100 relative to        // 1900        date.setUTCFullYear(year);        var valid =            date.getUTCFullYear() === year &&            date.getUTCMonth() === month &&            date.getUTCDate() === day;        return valid ? +date : NaN;    }    function parseOrdinalDate(str) {        var match = ORD_DATE.exec(str);        if (match ) {            var year = +match[1],                day = +match[2],                date = new Date(Date.UTC(year, 0, day));            if (date.getUTCFullYear() === year) {                return +date;            }        }        return NaN;    }    function parseDate(str) {        var match, year, month, day;        match = matchAll(str, datePatterns);        if (match === null) {            // Ordinal dates are verified differently.            return parseOrdinalDate(str);        }        year = (match[1] === void 0) ? 0 : +match[1];        month = (match[2] === void 0) ? 0 : +match[2] - 1;        day = (match[3] === void 0) ? 1 : +match[3];        return getDate(year, month, day);    }    function getTime(hr, min, sec) {        var valid =            (hr < 24 && hr >= 0 &&             min < 60 && min >= 0 &&             sec < 60 && min >= 0) ||            (hr === 24 && min === 0 && sec === 0);        if (!valid) {            return NaN;        }        return ((hr * 60 + min) * 60 + sec) * 1000;    }    function parseOffset(str) {        var match;        if (str.charAt(str.length - 1) === 'Z') {            str = str.substring(0, str.length - 1);        } else {            match = TIME_ZONE.exec(str);            if (match) {                var hours = +match[3],                    minutes = (match[4] === void 0) ? 0 : +match[4],                    offset = getTime(hours, minutes, 0);                if (match[2] === '-') {                    offset *= -1;                }                return { offset: offset, time: match[1] };            }        }        // No time zone specified, assume UTC        return { offset: 0, time: str };    }    function parseTime(str) {        var match;        var offset = parseOffset(str);        str = offset.time;        offset = offset.offset;        if (isNaN(offset)) {            return NaN;        }        match = matchAll(str, timePatterns);        if (match === null) {            return NaN;        }        var hours = (match[1] === void 0) ? 0 : +match[1],            minutes = (match[2] === void 0) ? 0 : +match[2],            seconds = (match[3] === void 0) ? 0 : +match[3];        return getTime(hours, minutes, seconds) - offset;    }    /**     * Parse an ISO8601 formatted date string, and return a Date object.     */    function parseISO8601(str){        var match = DATE_TIME.exec(str);        if (!match) {            // No time specified            return parseDate(str);        }        return parseDate(match[1]) + parseTime(match[2]);    }    module.exports = parseISO8601;
 |