admin管理员组

文章数量:1389754

Scenario

I have a UTC date in string format and an associated offset number in minutes:

  • Date: "2017-10-01T12:00:00.000Z"
  • Offset: 360

The user's browser is in the Mountain Standard Time (-7) timezone. The date value was recorded from the Central Standard Time (-6) timezone, and was saved along with its offset (hence the offset of 360 minutes). It can be assumed the offset does not include for daylight savings time.

Question

How do I parse the UTC date using the offset for the timezone it was recorded in? In other words, despite the user's browser being MST, I still want to display the date in a string as something like "2017-10-01 6:00 AM". Displaying the timezone is not required. Is this possible using moment-timezone without having the name of the timezone and just having the offset that doesn't include DST?

Scenario

I have a UTC date in string format and an associated offset number in minutes:

  • Date: "2017-10-01T12:00:00.000Z"
  • Offset: 360

The user's browser is in the Mountain Standard Time (-7) timezone. The date value was recorded from the Central Standard Time (-6) timezone, and was saved along with its offset (hence the offset of 360 minutes). It can be assumed the offset does not include for daylight savings time.

Question

How do I parse the UTC date using the offset for the timezone it was recorded in? In other words, despite the user's browser being MST, I still want to display the date in a string as something like "2017-10-01 6:00 AM". Displaying the timezone is not required. Is this possible using moment-timezone without having the name of the timezone and just having the offset that doesn't include DST?

Share Improve this question edited Feb 27, 2018 at 15:36 Andrew asked Feb 27, 2018 at 3:03 AndrewAndrew 94315 silver badges31 bronze badges 2
  • There is more than one timezones that is UTC-6. Also, there is no standard for naming timezones so the same timezone can be called different things by different people. – RobG Commented Feb 27, 2018 at 13:03
  • Fair point. It is not required to display the "CST" in the output string, so I can avoid that mess. Updated the question to reflect that. – Andrew Commented Feb 27, 2018 at 15:35
Add a ment  | 

2 Answers 2

Reset to default 3

Is that what you need ?

const moment = require('moment');
moment
  .utc('2013-06-20T07:00:00.427')
  .zone(-360)
  .format();

here you'll find a lot of displaying options -> http://momentjs./docs/#/displaying/

or maybe just:

const date = new Date('2017-10-01T12:00:00.000Z');
date.setMinutes(-360);
date.toISOString();

I guess that the timestamp "2017-10-01T12:00:00.000Z" is correct and that the offset of 360 is really -360 (since you say it should really be US Central Standard Time of -0600).

It can be assumed the offset does not include for daylight savings time.

Offsets never consider daylight saving, they are absolute values. Daylight saving changes the offset for a region within a timezone, usually reflected by also changing the timezone name (e.g. Central Standard Time to Central Daylight Time).

Anyway, if the original value is always UTC and you want to display it in the original timezone, you can parse the original UTC date to a Date, adjust the UTC time value, then use toISOString (which is always UTC) and append the appropriate offset designator. You also have to flip the sign of the offset.

The following does all that and avoids the built-in parser, don't be tempted to use it:

// Offset has opposite sign: 360 == -0600
var data = {date: "2017-10-01T12:00:00.000Z",
            offset: 360};
            
/* Return a timestamp adjusted for offset
** @param {object} data - object with the following properties 
**                          date: ISO 8601 format date and time string with Z offset
**                          offset: offset in minutes +ve west, -ve east
** @returns {string} ISO 8601 timestamp in zone
*/
function formatDate(data) {

  // Pad single digits with leading zero
  function pad(n){return (n<10? '0' : '') + n}

  // Format offset: 360 => -0600
  function formatOffset(offset) {
    var sign = offset < 0? '+' : '-'; // Note sign flip
    offset = Math.abs(offset);
    return sign + pad(offset/60|0) + pad(offset%60);
  }

  // Parse ISO 8601 date and time string, assume UTC and valid, ms may be missing
  function parseISO(s) {
    var b = s.split(/\D/);
    return new Date(Date.UTC(b[0],--b[1],b[2],b[3],b[4],b[5],b[6]|0));
  }

  var d = parseISO(data.date);
  var offset = data.offset;
  d.setUTCMinutes(d.getUTCMinutes() - offset);
  return d.toISOString().replace(/z$/i, formatOffset(offset));
}

console.log(formatDate(data));

本文标签: Javascript How to parse date from UTC string and offsetStack Overflow