Получить смещение из строки даты и времени и применить к новому объекту даты - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть строка даты и времени, возвращенная из моего бэкэнда следующим образом:

2018-12-30T20:00:00-05:00

Я пытаюсь получить смещение от этой строки даты и времени и применить его к новому объекту Date.

Когда я делаю это ... я получаю дату часового пояса клиента вместо той, которую я хотел бы.

var time = "2018-12-30T20:00:00-05:00"
new Date(time)

Я не против использовать моменты или любую другую библиотеку в JS, но я пытаюсь сделать этов моем внешнем интерфейсе.

ОБНОВЛЕНИЕ

, если дата, возвращенная из моего бэкэнда, имеет смещение -05: 00 ... тогда, когда я создаю объект датыв переднем конце ... он должен иметь такое же смещение

Например:

2018-12-31T10:00:00-05:00

Ответы [ 3 ]

0 голосов
/ 31 декабря 2018

Вот очень грубый пример того, как подойти к этому с чистым JS, для тех, кто попадает сюда и не хочет использовать Moment JS:

const d = new Date("2018-12-30T20:00:00-05:00");
const epochTimeDate = d.getTime(); // Get milliseconds since Unix Epoch
const localTZOffsetMilliseconds = d.getTimezoneOffset() * (60 * 1000); // Convert minutes to milliseconds
const msCoefficient = (60 * 60 * 1000);
const newTZOffsetHours = -3; // UTC -3

const newTZTime = new Date(epochTimeDate - (-1*(newTZOffsetHours*msCoefficient))); // The -1 reverses the confusing behavior of the browser spec which is the opposite of the actual offset
console.log(newTZTime.toISOString().replace(/T|Z/g,' ')+"(UTC "+newTZOffsetHours+")");

Лучшим способом вывода будет реализация вашей собственной функции, которая отображает дату, используя функции получателя для часов, минут и т. Д. Я не уверен, что .toISOString() стандартно, но работает в Chrome.

0 голосов
/ 01 января 2019

Вам нужно получить часовой пояс из строки, преобразовать его в смещение ECMAScript и использовать его для форматирования строки с требуемым смещением.

Уже есть ответы на SO, чтобы сделать выше, новот ответ в любом случае.

Например

/* Returns offset, uses match to allow for decimal seconds in timestamp
** @param {string} s - ECMAScript formatted datetime string with offset
**                    in the format YYYY-MM-DDTHH:mm:ss+/-HH:mm or Z
** @returns {string} - offset part of string, i.e. +/-HH:mm or Z
*/
function getOffset(s) {
  return offset = (s.match(/z$|[+\-]\d\d:\d\d$/i) || [])[0];
}

/* Convert offset in +/-HH:mm format or Z to ECMAScript offset
** @param {string} offset - in +/-HH:mm format or Z
** @returns {number} - ECMSCript offset in minutes, i.e. -ve east, +ve west
*/
function offsetToMins(offset) {
  // Deal with Z or z
  if (/z/i.test(offset)) return 0;
  // Deal +/-HH:mm
  var sign = /^-/.test(offset)? '1':'-1';
  var [h, m] = offset.slice(-5).split(':');
  return sign * h * 60 + +m; 
}

/* Format date with offset
** @param {Date} date - date to format
** @param {string} offset - ECMASCript offset string, 
**                          e.g. -05:00, Z
** @returns {string} ISO 8601 formatted string with
** specified offset
*/
function adjustToOffset(date, offset) {
  var o = offsetToMins(offset);
  var d = new Date(+date);
  d.setUTCMinutes(d.getUTCMinutes() - o);
  return d.toISOString().replace('Z', offset);
}

// Source string
var s = '2018-12-30T20:00:00-05:00';

// Get offset
var offset = getOffset(s);

// Make sure it's ok
if (typeof offset == 'undefined') {
  console.log('offset not found');

// Otherwise, show current time with specified offset
} else {
  console.log(adjustToOffset(new Date(), offset));
}

Обратите внимание, что типичные смещения ISO 8601 не имеют двоеточия, то есть обычно они равны ± ЧЧмм.

0 голосов
/ 31 декабря 2018

Если вы хотите использовать moment, вы можете легко получить смещение от даты / времени с помощью utcOffset.Вы можете использовать ту же функцию, чтобы применить смещение к новой дате / времени.Вот два момента, которые представляют одно и то же время, но с разными смещениями.Это преобразует секунду в смещение первого без изменения абсолютного времени:

var time = "2018-12-30T10:00:00-05:00"
let m = moment.parseZone(time)
let offset = m.utcOffset()
console.log("original: ", m.format(), "Offset:", offset)

// same time as m but -1 ofset
let m2 = moment.parseZone("2018-12-30T14:00:00-01:00")
console.log("m2 original: ", m2.format())

// change offset
m2.utcOffset(offset)
console.log("m2 converted: ", m2.format())
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>
...