用 Javascript 解析 ISO 8601日期

需要帮助/提示转换一个 ISO 8601日期与以下结构成 javascript。

CCYY-MM-DDThh:mm:ssTZD

我想把日期设置成这样:

January 28, 2011 - 7:30PM EST

我希望这个解决方案尽可能的简洁。

141898 次浏览

datejs could parse following, you might want to try out.

Date.parse('1997-07-16T19:20:15')           // ISO 8601 Formats
Date.parse('1997-07-16T19:20:30+01:00')     // ISO 8601 with Timezone offset

Edit: Regex version

x = "2011-01-28T19:30:00EST"


MM = ["January", "February","March","April","May","June","July","August","September","October","November", "December"]


xx = x.replace(
/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):\d{2}(\w{3})/,
function($0,$1,$2,$3,$4,$5,$6){
return MM[$2-1]+" "+$3+", "+$1+" - "+$4%12+":"+$5+(+$4>12?"PM":"AM")+" "+$6
}
)

Result

January 28, 2011 - 7:30PM EST

Edit2: I changed my timezone to EST and now I got following

x = "2011-01-28T19:30:00-05:00"


MM = {Jan:"January", Feb:"February", Mar:"March", Apr:"April", May:"May", Jun:"June", Jul:"July", Aug:"August", Sep:"September", Oct:"October", Nov:"November", Dec:"December"}


xx = String(new Date(x)).replace(
/\w{3} (\w{3}) (\d{2}) (\d{4}) (\d{2}):(\d{2}):[^(]+\(([A-Z]{3})\)/,
function($0,$1,$2,$3,$4,$5,$6){
return MM[$1]+" "+$2+", "+$3+" - "+$4%12+":"+$5+(+$4>12?"PM":"AM")+" "+$6
}
)

return

January 28, 2011 - 7:30PM EST

Basically

String(new Date(x))

return

Fri Jan 28 2011 19:30:00 GMT-0500 (EST)

regex parts just converting above string to your required format.

January 28, 2011 - 7:30PM EST

According to MSDN, the JavaScript Date object does not provide any specific date formatting methods (as you may see with other programming languages). However, you can use a few of the Date methods and formatting to accomplish your goal:

function dateToString (date) {
// Use an array to format the month numbers
var months = [
"January",
"February",
"March",
...
];


// Use an object to format the timezone identifiers
var timeZones = {
"360": "EST",
...
};


var month = months[date.getMonth()];
var day = date.getDate();
var year = date.getFullYear();


var hours = date.getHours();
var minutes = date.getMinutes();
var time = (hours > 11 ? (hours - 11) : (hours + 1)) + ":" + minutes + (hours > 11 ? "PM" : "AM");
var timezone = timeZones[date.getTimezoneOffset()];


// Returns formatted date as string (e.g. January 28, 2011 - 7:30PM EST)
return month + " " + day + ", " + year + " - " + time + " " + timezone;
}


var date = new Date("2011-01-28T19:30:00-05:00");


alert(dateToString(date));

You could even take it one step further and override the Date.toString() method:

function dateToString () { // No date argument this time
// Use an array to format the month numbers
var months = [
"January",
"February",
"March",
...
];


// Use an object to format the timezone identifiers
var timeZones = {
"360": "EST",
...
};


var month = months[*this*.getMonth()];
var day = *this*.getDate();
var year = *this*.getFullYear();


var hours = *this*.getHours();
var minutes = *this*.getMinutes();
var time = (hours > 11 ? (hours - 11) : (hours + 1)) + ":" + minutes + (hours > 11 ? "PM" : "AM");
var timezone = timeZones[*this*.getTimezoneOffset()];


// Returns formatted date as string (e.g. January 28, 2011 - 7:30PM EST)
return month + " " + day + ", " + year + " - " + time + " " + timezone;
}


var date = new Date("2011-01-28T19:30:00-05:00");
Date.prototype.toString = dateToString;


alert(date.toString());

The Date object handles 8601 as it's first parameter:

var d = new Date("2014-04-07T13:58:10.104Z");
console.log(d.toString());

If you want to keep it simple, this should suffice:

function parseIsoDatetime(dtstr) {
var dt = dtstr.split(/[: T-]/).map(parseFloat);
return new Date(dt[0], dt[1] - 1, dt[2], dt[3] || 0, dt[4] || 0, dt[5] || 0, 0);
}

note parseFloat is must, parseInt doesn't always work. Map requires IE9 or later.

Works for formats:

  • 2014-12-28 15:30:30
  • 2014-12-28T15:30:30
  • 2014-12-28

Not valid for timezones, see other answers about those.

Maybe, you can use moment.js which in my opinion is the best JavaScript library for parsing, formatting and working with dates client-side. You could use something like:

var momentDate = moment('1890-09-30T23:59:59+01:16:20', 'YYYY-MM-DDTHH:mm:ss+-HH:mm:ss');
var jsDate = momentDate.toDate();


// Now, you can run any JavaScript Date method


jsDate.toLocaleString();

The advantage of using a library like moment.js is that your code will work perfectly even in legacy browsers like IE 8+.

Here is the documenation about parsing methods: https://momentjs.com/docs/#/parsing/