constISO8601_DATE_REGEX=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;// 1 2 3 4 5 6 7 8 9 10 11let value ='2030-12-31T15:59:59.000+0000';let match = value.match(ISO8601_DATE_REGEX);functionisoStringToDate(match){
const date =newDate(0);let tzHour =0;let tzMin =0;// match[8] means that the string contains "Z" (UTC) or a timezone like "+01:00" or "+0100"const dateSetter = match[8]? date.setUTCFullYear : date.setFullYear;const timeSetter = match[8]? date.setUTCHours : date.setHours;// if there is a timezone defined like "+01:00" or "+0100"if(match[9]){
tzHour =Number(match[9]+ match[10]);
tzMin =Number(match[9]+ match[11]);}
dateSetter.call(date,Number(match[1]),Number(match[2])-1,Number(match[3]));const h =Number(match[4]||0)- tzHour;const m =Number(match[5]||0)- tzMin;const s =Number(match[6]||0);// The ECMAScript specification (https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.11)// defines that `DateTime` milliseconds should always be rounded down, so that `999.9ms`// becomes `999ms`.const ms = Math.floor(parseFloat('0.'+(match[7]||0))*1000);
timeSetter.call(date, h, m, s, ms);return date;}
console.log(isoStringToDate(match));