Остановить функцию javascript Date от изменения смещения временной зоны
Итак, у меня есть iso date time, которые необходимо преобразовать из объекта с привязкой к текущей. Как сохранить дату перехода на локальный часовой пояс браузера.
new Date('2013-07-18T17:00:00-05:00')
Thu Jul 18 2013 18:00:00 GMT-0400 (EDT)
Я хочу получить
Thu Jul 18 2013 17:00:00 GMT-0500 (XX)
Ответы
Ответ 1
Вы не можете изменить это поведение Javascript, потому что это единственный простой способ работы Javascript. Случается, что Javascript просматривает временной сдвиг, вычисляет совпадающую временную метку и затем запрашивает ОС для представления этой метки времени в локальном часовом поясе. Здесь важно понять, что -05:00
не является указанием часового пояса, а просто сдвигом с UTC.
Часовые пояса - это сложные звери, которые являются просто произвольными политическими решениями. ОС предоставляет услугу для отображения времени в локальном часовом поясе, но не в других часовых поясах. Для этого вам нужно принимать во внимание такие вещи, как DST, которые в значительной степени ада.
Как всегда с управлением временем, единственный достойный способ решить эту проблему - использовать специальную библиотеку. В Javascript вы найдете Moment.js и Moment.Timezone.js очень полезно.
Пример http://codepen.io/Xowap/pen/XKpKZb?editors=0010
document.write(moment('2013-07-18T17:00:00-05:00').tz('America/New_York').format('LLL'));
В качестве бонуса вы получаете тонну функций форматирования/разбора из Moment.js.
Также обратите внимание, что до тех пор, пока вы используете ISO 8601, ваша дата может быть точно определена и, таким образом, будет отображаться в любой временной зоне по вашему вкусу. Другими словами, JS "преобразование" вашей даты не имеет значения.
Ответ 2
Для этого вы можете использовать библиотеку, такую как Moment.js.
Смотрите синтаксический анализ Строка + Формат.
http://momentjs.com/docs/#/parsing/string-format/
Следующее должно проанализировать предоставленную вами дату, но вам может потребоваться изменить ее для ваших нужд.
var dateString = "2013-07-18T17:00:00-05:00";
var dateObject = moment(dateString, "YYYY-MM-DDTHH:mm:ssZ").toDate();
В качестве альтернативы см. парсер Moment String, который выглядит так, как будто он находится в указанном вами формате, за исключением пробела между секундами времени и часового пояса.
http://momentjs.com/docs/#/parsing/string/
Ответ 3
Хотя MomentJS - отличная библиотека, она не может обеспечить решение для каждого варианта использования. Например, мой сервер предоставляет даты в формате UTC, и когда часть времени даты не сохраняется в БД (потому что это не имеет значения), клиент получает строку со временем по умолчанию всех нулей - полночь - и оканчивается на смещение +0000
. Затем браузер автоматически подстраивается под мой локальный часовой пояс и тянет время назад на несколько часов, что приводит к предыдущему дню.
Это верно и для MomentJ.
Одно из решений состоит в том, чтобы отрезать временную часть строки, а затем использовать MomentJS, как описано в других ответах.
Но что произойдет, если MomentJS не является жизнеспособным вариантом, то есть у меня уже есть много мест, которые используют JS Date и не хотят обновлять так много строк кода? Вопрос в том, как остановить браузер от конвертации дат в зависимости от локального часового пояса. И ответ таков: когда дата в формате ISO, вы не можете.
Однако не существует правила, согласно которому строка, передаваемая в конструктор JavaScript, должна быть в формате ISO. Если вы просто замените -
который разделяет год, месяц и день на /
, ваш браузер не выполнит конвертацию.
В моем случае я просто изменил формат серверной части Dates, и проблема была решена без необходимости обновлять все даты JS на стороне клиента с помощью MomentJS.
Обратите внимание, что документы MDN для класса Date JavaScript предупреждают о непредсказуемом поведении браузера при разборе строки для создания экземпляра Date.
Ответ 4
Интересно, поможет ли это:
function goAheadMakeMyDate(s){
var d = new Date(s);
// override Date.toString()
d.toString = function(){ return ''+s; };
return d;
}
var example = goAheadMakeMyDate("Fri 19 July 2013 12:00:00 GMT");
example.toString() // returns string actually used to construct the date
'Fri 19 July 2013 12:00:00 GMT'
example.toLocaleString()
'Fri Jul 19 2013 08:00:00 GMT-0400 (EDT)'
1*example // gives seconds since epoch
1374235200000
С вашим вводом:
example = goAheadMakeMyDate('2013-07-18T17:00:00-05:00')
{ Thu, 18 Jul 2013 22:00:00 GMT toString: [Function] }
> example.toString()
'2013-07-18T17:00:00-05:00'
> example.toLocaleString() // I live in GMT-4
'Thu Jul 18 2013 18:00:00 GMT-0400 (EDT)'
> 1*example // convert to integer date
1374184800000
Однако, если вы начнете изменять эту дату, toString не изменится и вас укусит.
Ответ 5
Это старый вопрос, который недавно был связан в ответе на новый вопрос, но ни один из существующих ответов, кажется, не полностью отвечает первоначальному вопросу.
Во многих случаях самый простой способ отформатировать и отобразить строку даты-времени в полученном часовом поясе - вообще не преобразовывать строку в объект Date
. Вместо этого просто проанализируйте строку даты и времени и объедините части в желаемый формат. Например, если вы можете прожить без дня недели в выходных данных, запрошенных в вопросе, вы можете сделать что-то вроде следующего для обработки запрошенного формата ввода и вывода (в том числе день недели добавляет достаточно сложности, чтобы это могло быть стоит использовать библиотеку на тот момент). Конечно, этот подход требует модификации на основе формата строк даты и времени, которые вы получаете на стороне клиента.
const months = {1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'};
const format = (datetime) => {
let [date, time] = datetime.split('T');
let [y, m, d] = date.match(/\d+/g);
let [t, tz] = time.split(/(?=[+-])/);
return '${months[parseInt(m)]} ${d} ${y} ${t} GMT${tz}';
}
let dt = format('2013-07-18T17:00:00-05:00');
console.log(dt);
// Jul 18 2013 17:00:00 GMT-05:00
Ответ 6
Если вы открыты для использования библиотеки, библиотека JavaScript MomentJS является популярной для обработки времени и дат.