Спецификация ISO 8601 допускает широкий спектр форматов даты. Существует посредственное объяснение того, как это сделать здесь . Существует довольно небольшое несоответствие между форматированием ввода даты в Javascript и форматированием ISO для простых дат, которые не задают часовые пояса, и его можно легко смягчить с помощью подстановки строк . Полностью поддерживать спецификацию ISO-8601 нетривиально.
Вот справочный пример, который я не гарантирую, чтобы быть полным, хотя он анализирует непостоянные даты из вышеупомянутой страницы Википедии.
Ниже приведен пример, и вы также можете увидеть его вывод на ideone . К сожалению, он не работает по спецификации, так как не реализует недели должным образом. Определение номера недели 01 в ISO-8601 является нетривиальным и требует некоторого просмотра календаря, чтобы определить, где начинается первая неделя и что именно это означает с точки зрения количества дней в указанном году. Возможно, это довольно легко исправить (я просто устал играть с ним).
function parseISODate (input) {
var iso = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/;
var parts = input.match(iso);
if (parts == null) {
throw new Error("Invalid Date");
}
var year = Number(parts[1]);
if (typeof parts[2] != "undefined") {
/* Convert weeks to days, months 0 */
var weeks = Number(parts[2]) - 1;
var days = Number(parts[3]);
if (typeof days == "undefined") {
days = 0;
}
days += weeks * 7;
var months = 0;
}
else {
if (typeof parts[4] != "undefined") {
var months = Number(parts[4]) - 1;
}
else {
/* it's an ordinal date... */
var months = 0;
}
var days = Number(parts[5]);
}
if (typeof parts[6] != "undefined" &&
typeof parts[7] != "undefined")
{
var hours = Number(parts[6]);
var minutes = Number(parts[7]);
if (typeof parts[8] != "undefined") {
var seconds = Number(parts[8]);
if (typeof parts[9] != "undefined") {
var fractional = Number(parts[9]);
var milliseconds = fractional / 100;
}
else {
var milliseconds = 0
}
}
else {
var seconds = 0;
var milliseconds = 0;
}
}
else {
var hours = 0;
var minutes = 0;
var seconds = 0;
var fractional = 0;
var milliseconds = 0;
}
if (typeof parts[10] != "undefined") {
/* Timezone adjustment, offset the minutes appropriately */
var localzone = -(new Date().getTimezoneOffset());
var timezone = parts[10] * 60;
minutes = Number(minutes) + (timezone - localzone);
}
return new Date(year, months, days, hours, minutes, seconds, milliseconds);
}
print(parseISODate("2010-06-29T15:33:00Z-7"))
print(parseISODate("2010-06-29 06:14Z"))
print(parseISODate("2010-06-29T06:14Z"))
print(parseISODate("2010-06-29T06:14:30.2034Z"))
print(parseISODate("2010-W26-2"))
print(parseISODate("2010-180"))