问题
I am querying event start times from Facebook's API. Most often, they return the string like the following:
2014-04-02T20:00:00-0600
But sometimes, it is returned like:
2014-04-19
When I try to create a new date object, it does not work with the timezone identifier.
However, both of these work:
var d = new Date('2014-04-02T20:00:00')
or
var d = new Date('2014-04-19')
But I need this to work:
var d = new Date('2014-04-02T20:00:00-0600')
// returns Invalid Date
I'm trying to avoid parsing each start_time string to see if I need to remove the timezone identifier since I am working with hundreds of events.
Is there an easier way to do what I'm trying, or do I actually need to remove the timezone identifier for each date that has it?
回答1:
You can parse an ISO 8601 string with offset using the following. If the string has no offset, it is assumed to be Z (i.e. UTC per ECMA-262):
/* Parse an ISO string with an offset
** e.g. '2014-04-02T20:00:00-0600'
** '2014-04-02T20:00:00Z'
**
** 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', treat as UTC date (per ECMA-262)
*/
function parseISOString(s) {
var t = s.split(/\D+/g);
var hasOffset = /\d{2}[-+]\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 ms = hasDecimalSeconds? t[6] : 0;
var offMin, offSign, min;
// If there's an offset, apply it to minutes to get a UTC time value
if (hasOffset) {
offMin = 60 * offset / 100 + offset % 100;
offSign = /-\d{4}$/.test(s)? -1 : 1;
}
min = hasOffset? +t[4] - offMin * offSign : (t[4] || 0);
// Return a date object based on UTC values
return new Date(Date.UTC(t[0], --t[1], t[2], t[3]||0, min, t[5]||0, ms));
}
// Tests
console.log(parseISOString('2014-04-02T20:00:00-0600').toISOString()); // 2014-04-03T02:00:00.000Z
console.log(parseISOString('2014-04-02T20:00:00Z').toISOString()); // 2014-04-02T20:00:00.000Z
console.log(parseISOString('2014-04-02T20:00:00').toISOString()); // 2014-04-02T20:00:00.000Z
console.log(parseISOString('2014-04-02T20:00:00.123-0600').toISOString());// 2014-04-03T02:00:00.123Z
console.log(parseISOString('2014-04-02T20:00:00.123').toISOString()); // 2014-04-02T20:00:00.123Z
console.log(parseISOString('2014-04-02').toISOString()); // 2014-04-02T00:00:00.000Z
Note that if this will create a date object with an offset for the timezone of the host environment based on system settings. The timevalue of the Date will be the equivalent UTC time for the supplied timestamp (in this case, '2014-04-03T02:00:00Z'). You can confirm that using the toISOString method (requires IE9 or higher, or other modern browser).
Edit
Note that you can't set the timezone offset of a Date object. They have a time value that represents a UTC moment in time, and a timezone offset that is based on system settings. You can read "local" date and time values using standard Date methods like getFullYear and getHours, or UTC values if UTC methods are used (e.g. getUTCFullYear, getUTCHours).
Edit 2
Allowed for date only format (treats it as UTC).
来源:https://stackoverflow.com/questions/22827052/creating-new-date-object-which-includes-timezone-identifier