Преобразование даты в другой часовой пояс в JavaScript

Я ищу функцию для преобразования даты в одном часовом поясе в другой.

для этого нужны два параметра,

  • дата (в формате "2012/04/10 10:10:30 +0000")
  • строка часового пояса ("Азия/Джакарта")

строка часового пояса описывается вhttp://en.wikipedia.org/wiki/Zone.tab

существует ли простой способ сделать это?

18 ответов


на момент.js пользователи, теперь вы можете использовать время-часовой пояс. Используя его, ваша функция будет выглядеть примерно так:

function toTimeZone(time, zone) {
    var format = 'YYYY/MM/DD HH:mm:ss ZZ';
    return moment(time, format).tz(zone).format(format);
}

бесстыдно украден из: http://www.techrepublic.com/article/convert-the-local-time-to-another-time-zone-with-this-javascript/6016329

/** 
 * function to calculate local time
 * in a different city
 * given the city's UTC offset
 */
function calcTime(city, offset) {

    // create Date object for current location
    var d = new Date();

    // convert to msec
    // add local time zone offset
    // get UTC time in msec
    var utc = d.getTime() + (d.getTimezoneOffset() * 60000);

    // create new Date object for different city
    // using supplied offset
    var nd = new Date(utc + (3600000*offset));

    // return time as a string
    return "The local time in " + city + " is " + nd.toLocaleString();
}

эта функция полезна для вычисления значения часового пояса, предоставляя имя города / страны и значение смещения


Большинство настольных (не мобильных) браузеров, кроме Safari, поддерживают методом tolocalestring функция с аргументами, старые браузеры обычно игнорируют аргументы.

new Date().toLocaleString('en-US', { timeZone: 'Asia/Jakarta' })

ладно, нашел!

Я использую часовой пояс-js. вот код:

var dt = new timezoneJS.Date("2012/04/10 10:10:30 +0000", 'Europe/London');
dt.setTimezone("Asia/Jakarta");

console.debug(dt); //return formatted date-time in asia/jakarta

получил его !

хотел заставить дату, показанную = дата сервера, не Маттер локальные настройки (UTC).

мой сервер GMT-6 --> новая дата ().getTimezoneOffset() = 360.

myTZO = 360;
myNewDate=new Date(myOldDateObj.getTime() + (60000*(myOldDateObj.getTimezoneOffset()-myTZO)));
alert(myNewDate);

Если вам просто нужно конвертировать часовые пояса, я загрузил урезанная версия of время-часовой пояс С минимум функциональности. Его ~1KB + данные:

S.loadData({
    "zones": [
        "Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|11e6",
        "Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1GQg0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|40e5",
    ],
    "links": [
        "Europe/Paris|Europe/Madrid",
    ]
});

let d = new Date();
console.log(S.tz(d, "Europe/Madrid").toLocaleString());
console.log(S.tz(d, "Australia/Sydney").toLocaleString());

установите переменную с годом, месяцем и днем, разделенными символами" -", плюс " T " и время в шаблоне HH:mm:ss, а затем +01:00 в конце строки (в моем случае часовой пояс +1). Затем использовать эту строку в качестве аргумента для конструктора даты.

//desired format: 2001-02-04T08:16:32+01:00
dateAndTime = year+"-"+month+"-"+day+"T"+hour+":"+minutes+":00+01:00";

var date = new Date(dateAndTime );

вы можете использовать метод toLocaleString () для установки часового пояса.

new Date().toLocaleString('en-US', { timeZone: 'Indian/Christmas' })

для Индии вы можете использовать "индийский / Рождество" и следующие различные часовые пояса,

"Antarctica/Davis",
    "Asia/Bangkok",
    "Asia/Hovd",
    "Asia/Jakarta",
    "Asia/Phnom_Penh",
    "Asia/Pontianak",
    "Asia/Saigon",
    "Asia/Vientiane",
    "Etc/GMT-7",
    "Indian/Christmas"

вы можете попробовать это также для конвертировать часовой пояс даты в Индию:

var indianTimeZoneVal = new Date().toLocaleString('en-US', {timeZone: 'Asia/Kolkata'});
var indainDateObj = new Date(indianTimeZoneVal);
indainDateObj.setHours(indainDateObj.getHours() + 5);
indainDateObj.setMinutes(indainDateObj.getMinutes() + 30);
console.log(indainDateObj);

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

объект даты js, который у меня есть, находится в UTC. Мне нужно было получить дату и время от этой даты в определенном часовом поясе ("Америка/Чикаго" в моем случае).

 var currentUtcTime = new Date(); // This is in UTC

 // Converts the UTC time to a locale specific format, including adjusting for timezone.
 var currentDateTimeCentralTimeZone = new Date(currentUtcTime.toLocaleString('en-US', { timeZone: 'America/Chicago' }));

 console.log('currentUtcTime: ' + currentUtcTime.toLocaleDateString());
 console.log('currentUtcTime Hour: ' + currentUtcTime.getHours());
 console.log('currentUtcTime Minute: ' + currentUtcTime.getMinutes());
 console.log('currentDateTimeCentralTimeZone: ' +        currentDateTimeCentralTimeZone.toLocaleDateString());
 console.log('currentDateTimeCentralTimeZone Hour: ' + currentDateTimeCentralTimeZone.getHours());
 console.log('currentDateTimeCentralTimeZone Minute: ' + currentDateTimeCentralTimeZone.getMinutes());

UTC в настоящее время на 6 часов опережает "Америку/Чикаго". Выход есть:

currentUtcTime: 11/25/2016
currentUtcTime Hour: 16
currentUtcTime Minute: 15

currentDateTimeCentralTimeZone: 11/25/2016
currentDateTimeCentralTimeZone Hour: 10
currentDateTimeCentralTimeZone Minute: 15

люди, знакомые с java 8 java.time пакета, или joda-time, вероятно, понравится новый ребенок на блоке:js-joda библиотека.

установить

npm install js-joda js-joda-timezone --save

пример

<script src="node_modules/js-joda/dist/js-joda.js"></script>
<script src="node_modules/js-joda-timezone/dist/js-joda-timezone.js"></script>
<script>
var dateStr = '2012/04/10 10:10:30 +0000';
JSJoda.use(JSJodaTimezone);
var j = JSJoda;
// https://js-joda.github.io/js-joda/esdoc/class/src/format/DateTimeFormatter.js~DateTimeFormatter.html#static-method-of-pattern
var zonedDateTime = j.ZonedDateTime.parse(dateStr, j.DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss xx'));
var adjustedZonedDateTime = zonedDateTime.withZoneSameInstant(j.ZoneId.of('America/New_York'));
console.log(zonedDateTime.toString(), '=>', adjustedZonedDateTime.toString());
// 2012-04-10T10:10:30Z => 2012-04-10T06:10:30-04:00[America/New_York]
</script>

в истинной природе java это довольно многословный lol. Но, будучи портированной библиотекой java, особенно учитывая, что они портировали тестовые случаи 1800'ish, он также, вероятно, работает великолепно точно.

Хроно манипуляции трудно. Вот почему многие другие библиотеки глючат в крайних случаях. Момент.js, кажется, получает правильные часовые пояса, но другие JS libs, которые я видел, включая timezone-js, не кажется надежным.


Если формат не очень важен, и вы не хотите импортировать большую библиотеку, которую вы можете просто использовать Intl.Datetimeformat с для преобразования объектов даты в разные часовые пояса.

const options = {
  year: '2-digit', month: '2-digit', day: '2-digit',
  hour: '2-digit', minute: '2-digit', second: '2-digit',
  timeZone: 'Asia/Jakarta',
  timeZoneName: 'short'
};

const formater = new Intl.DateTimeFormat('sv-SE', options)
const date = new Date("2012/04/10 10:10:30 +0000")

console.log(formater.format(date))

смещения, летнее время и другие различия, измененные в прошлом, будут заботиться о вас

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


у меня были проблемы с использованием Момент Часовой Пояс. Я добавляю этот ответ так, если кто-то другой сталкивается с той же проблемой. Итак, у меня есть строка даты 2018-06-14 13:51:00 мои API. Я знаю, что это хранится в UTC но строка не говорит сама за себя.

Я позволяю часовому поясу момента знать, какой часовой пояс эта дата от делать:

let uTCDatetime = momentTz.tz("2018-06-14 13:51:00", "UTC").format();
// If your datetime is from any other timezone then add that instead of "UTC"
// this actually makes the date as : 2018-06-14T13:51:00Z

теперь я хотел бы преобразовать его в определенный часовой пояс, выполнив:

let dateInMyTimeZone = momentTz.tz(uTCDatetime, "Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");
// now this results into: 2018-06-14 19:21:00, which is the corresponding date in my timezone.

осмотрев много, включая ссылки с этой страницы, я нашел эту замечательную статью, используя часовой пояс момента:

https://www.webniraj.com/2016/11/23/javascript-using-moment-js-to-display-dates-times-in-users-timezone/

подводя итог:

получить часовой пояс пользователя

var tz = moment.tz.guess();
console.info('Timezone: ' + tz);

возвращает например: часовой пояс: Европа/Лондон

установите часовой пояс пользователя по умолчанию

moment.tz.setDefault(tz);

установка пользовательских часовой пояс

moment.tz.setDefault('America/Los_Angeles');

преобразование даты / времени в локальный часовой пояс, предполагает, что исходная дата / время находится в UTC

moment.utc('2016-12-25 07:00').tz(tz).format('ddd, Do MMMM YYYY, h:mma');

возвращает: Солнце, 25 декабря 2016, 7: 00am

преобразовать дату / время в LA Time

moment.utc('2016-12-25 07:00').tz('America/Los_Angeles').format('ddd, Do MMMM YYYY, h:mma');

Returns: СБ, 24 декабря 2016, 11: 00pm

конвертировать из LA time в Лондон

moment.tz('2016-12-25 07:00', 'America/Los_Angeles').tz('Europe/London').format( 'ddd, Do MMMM YYYY, h:mma' );

возвращает: Солнце, 25 декабря 2016, 3: 00pm


существует модуль npm под названием " часовые пояса.json ' вы можете использовать для этого; он в основном состоит из JSON-файла с объектами, содержащими информацию о дневной экономии и смещении....

для Азии / Джакарты он сможет вернуть этот объект:

{
  "value": "SE Asia Standard Time",
  "abbr": "SAST",
  "offset": 7,
  "isdst": false,
  "text": "(UTC+07:00) Bangkok, Hanoi, Jakarta",
  "utc": [
    "Antarctica/Davis",
    "Asia/Bangkok",
    "Asia/Hovd",
    "Asia/Jakarta",
    "Asia/Phnom_Penh",
    "Asia/Pontianak",
    "Asia/Saigon",
    "Asia/Vientiane",
    "Etc/GMT-7",
    "Indian/Christmas"
  ]
}

вы можете найти его здесь:

https://github.com/dmfilipenko/timezones.json

https://www.npmjs.com/package/timezones.json

надеюсь, что это полезно


смещение часового пояса для вашего текущего часового пояса

date +%s -d '1 Jan 1970'

для моего часового пояса GMT+10 (Австралия) он вернулся -36000


недавно я сделал это в Typescript:

// fromTimezone example : Europe/Paris, toTimezone example: Europe/London
private calcTime( fromTimezone: string, toTimezone: string, dateFromTimezone: Date ): Date {
  const dateToGetOffset = new Date( 2018, 5, 1, 12 );

  const fromTimeString = dateToGetOffset.toLocaleTimeString( "en-UK", { timeZone: fromTimezone, hour12: false } );
  const toTimeString = dateToGetOffset.toLocaleTimeString( "en-UK", { timeZone: toTimezone, hour12: false } );

  const fromTimeHours: number = parseInt( fromTimeString.substr( 0, 2 ), 10 );
  const toTimeHours: number = parseInt( toTimeString.substr( 0, 2 ), 10 );

  const offset: number = fromTimeHours - toTimeHours;

  // convert to msec
  // add local time zone offset
  // get UTC time in msec
  const dateFromTimezoneUTC = Date.UTC( dateFromTimezone.getUTCFullYear(),
    dateFromTimezone.getUTCMonth(),
    dateFromTimezone.getUTCDate(),
    dateFromTimezone.getUTCHours(),
    dateFromTimezone.getUTCMinutes(),
    dateFromTimezone.getUTCSeconds(),
  );

  // create new Date object for different city
  // using supplied offset
  const dateUTC = new Date( dateFromTimezoneUTC + ( 3600000 * offset ) );

  // return time as a string
  return dateUTC;
}

Я использую формат "en-UK", потому что он простой. Могло быть "en-US" или что-то еще.

Если первый аргумент-часовой пояс локали, а seconde-целевой часовой пояс, он возвращает объект Date с правильным смещением.


Я не знаю простого метода преобразования объекта даты в любой часовой пояс, но если вы хотите преобразовать его в локальный часовой пояс, вы можете просто преобразовать его с помощью Date.prototype.getTime() до соответствующего количества миллисекунд и обратно.

date = new Date('2016-05-24T13:07:20');
date = new Date(date.getTime());

например, date.getHours() сейчас вернется 15 вместо 13 если вы, как и я, в Австрии (и это летом).

Я читал, что различные функции datetime могут проявлять нестандартное поведение в некоторых браузерах, поэтому сначала проверьте это. Я могу подтвердить, что он работает в Chrome.