Creating new date object which includes timezone identifier

∥☆過路亽.° 提交于 2020-01-06 06:52:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!