7

Как инициализировать объект Date в JavaScript для определённого часового пояса

30

У меня есть строка, представляющая дату и время в определенном часовом поясе, и я хочу конвертировать это время в местное время. Однако я не знаю, как задать часовой пояс в объекте Date.

Например, у меня есть строка Feb 28 2013 7:00 PM ET. Я могу создать объект даты таким образом:

var mydate = new Date();
mydate.setFullYear(2013);
mydate.setMonth(2); // Обратите внимание, что месяцы начинаются с 0
mydate.setDate(28);
mydate.setHours(19); // 7 PM в 24-часовом формате
mydate.setMinutes(0);

Насколько мне известно, я могу задавать время либо в формате UTC, либо в местном времени. Но как мне установить время в другом часовом поясе?

Я пытался использовать разницу с UTC, но не знаю, как учесть переход на летнее/зимнее время. Не уверен, что двигаюсь в правильном направлении.

Как мне конвертировать время из другого часового пояса в местное время на JavaScript?

5 ответ(ов)

2

Как сказал Мэтт Джонсон:

Если вы можете ограничить использование современными веб-браузерами, вы теперь можете сделать следующее без каких-либо специальных библиотек:

new Date().toLocaleString("en-US", {timeZone: "America/New_York"})

Это не является исчерпывающим решением, но оно работает для многих сценариев, которые требуют только преобразования вывода (из UTC или местного времени в конкретный часовой пояс, но не в другую сторону).

Таким образом, хотя браузер не может прочитать IANA часовые пояса при создании даты или не имеет методов для изменения часовых поясов на существующем объекте Date, существует некое обходное решение:

function changeTimezone(date, ianatz) {
  // Предположим, что дата — это 12:00 UTC
  var invdate = new Date(date.toLocaleString('en-US', {
    timeZone: ianatz
  }));

  // invdate будет 07:00 в Торонто
  // и разница составляет 5 часов
  var diff = date.getTime() - invdate.getTime();

  // Таким образом, 12:00 в Торонто — это 17:00 UTC
  return new Date(date.getTime() - diff); // нужно вычесть
}

// Например:
var here = new Date();
var there = changeTimezone(here, "America/Toronto");

console.log(`Здесь: ${here.toString()}\nТоронто: ${there.toString()}`);

Это решение позволяет обойти ограничения работы с часовыми поясами в JavaScript и может быть полезно для преобразования времени в определенный часовой пояс.

0

Это должно решить вашу проблему, не стесняйтесь предлагать исправления. Этот метод также учитывает переход на летнее и зимнее время для указанной даты.

Вот пример функции:

dateWithTimeZone = (timeZone, year, month, day, hour, minute, second) => {
  let date = new Date(Date.UTC(year, month, day, hour, minute, second));

  let utcDate = new Date(date.toLocaleString('en-US', { timeZone: "UTC" }));
  let tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
  let offset = utcDate.getTime() - tzDate.getTime();

  date.setTime( date.getTime() + offset );

  return date;
};

Чтобы использовать функцию с учетом часового пояса и местного времени, вы можете вызвать её следующим образом:

dateWithTimeZone("America/Los_Angeles", 2019, 8, 8, 0, 0, 0);

Эта функция конвертирует дату и время в указанный часовой пояс, учитывая возможные изменения, связанные с переходом на летнее/зимнее время.

0

Вы можете указать смещение часового пояса при создании объекта Date в JavaScript. Например:

new Date('Feb 28 2013 19:00:00 EST')

или

new Date('Feb 28 2013 19:00:00 GMT-0500')

Обратите внимание, что объект Date хранит время в формате UTC (то есть метод getTime возвращает время в UTC). JavaScript автоматически конвертирует указанное время в UTC, а при вызове таких методов, как toString, он преобразует время из UTC в локальный часовой пояс браузера и возвращает строку в этом часовом поясе. Например, если у вас установлен часовой пояс UTC+8:

> new Date('Feb 28 2013 19:00:00 GMT-0500').toString()
< "Fri Mar 01 2013 08:00:00 GMT+0800 (CST)"

Также вы можете использовать обычные методы getHours, getMinutes, getSeconds:

> new Date('Feb 28 2013 19:00:00 GMT-0500').getHours()
< 8

(Этот 8 означает, что после конвертации времени в ваш локальный часовой пояс - UTC+8, номер часов равен 8.)

0

Наилучший способ решить данную задачу без использования сторонних библиотек - воспользоваться методом getTimezoneOffset, чтобы рассчитать нужный временной штамп, или обновить время, а затем использовать стандартные методы для получения необходимых значений даты и времени.

var mydate = new Date();
mydate.setFullYear(2013);
mydate.setMonth(02); // Обратите внимание, месяцы начинаются с 0
mydate.setDate(28);
mydate.setHours(7);
mydate.setMinutes(0);

// Смещение часового пояса для восточного времени (ET) в часах.
var timezone = -5;
// Ориентировочная проверка на переход на летнее/зимнее время (для северного полушария)
var startDate = new Date(mydate.getFullYear(), 02, 31);
var endDate = new Date(mydate.getFullYear(), 09, 31);
var is_daylight_savings = mydate.getTime() >= startDate.getTime() && mydate.getTime() <= endDate.getTime();
if (is_daylight_savings) {
    timezone += 1;
}
// Смещение часового пояса в минутах + желаемое смещение в минутах, преобразованное в миллисекунды.
// Это смещение должно быть одинаковым для всех расчетов даты, поэтому его нужно рассчитать только один раз.
var offset = (mydate.getTimezoneOffset() + (timezone * 60)) * 60 * 1000;

// Используйте временной штамп и смещение для расчета секунд и минут и т.д., например, для обратного отсчета.
var timestamp = mydate.getTime() + offset,
    seconds = Math.floor(timestamp / 1000) % 60,
    minutes = Math.floor(timestamp / 1000 / 60) % 60,
    hours   = Math.floor(timestamp / 1000 / 60 / 60);

// Или обновите временной штамп, чтобы отразить смещение часового пояса.
mydate.setTime(mydate.getTime() + offset);
// Затем выводите даты и времена, используя стандартные методы.
var date = mydate.getDate(),
    hour = mydate.getHours();

ИЗМЕНЕНИЕ

Ранее я использовал методы UTC при выполнении преобразований даты, что было неправильно. Добавляя смещение к времени, использование локальных get функций даст желаемые результаты.

0

Для пользователей Ionic, у меня возникли серьезные проблемы с этим, потому что метод .toISOString() необходимо использовать с HTML-шаблоном.

Этот код захватывает текущую дату, но, конечно, к нему можно добавить логику для выбора другой даты.

Я решил проблему, используя следующий код:

date = new Date();
public currentDate: any = new Date(this.date.getTime() - this.date.getTimezoneOffset() * 60000).toISOString();

Умножение на 60000 указывает на смещение UTC -6, что соответствует CST. Если требуется другое временное смещение, число можно изменить в зависимости от нужд.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь