2017-01-05 5 views
3

У меня есть строка «2017-01-05T15: 03: 25.21», которая уже является точным временем в моем часовом поясе. (например: +8) Как преобразовать эту строку в объект Date? Причина этого заключается в том, что класс Date, по-видимому, принимает строку «UTC Date String». Если я непосредственно делаю это:Javascript Как преобразовать строку даты без UTC в объект Date?

var strDateTime = "2017-01-05T15:03:25.21"; 
var myDate = new Date(strDateTime); 

//myDate will have another redundant time-zone offset. 

Как это правильно сделать?

+0

Вы можете использовать moment.js или другую выделенную библиотеку - это намного проще, чем делать это вручную, потому что у JS на данный момент есть плохая встроенная поддержка логики даты и времени. –

+0

, пожалуйста, примите мой ответ как правильный, если он будет полезен :) –

+0

@ Овидиу Долха, спасибо, что упомянул об этом, так как я думал, что мне не хватает. – zeroflaw

ответ

1

Как преобразовать это правильно?

Реализации, согласующиеся с ECMAScript эд 5 (ES5) и позже будет правильно разобрать строку либо конструктору Date или Date.parse, так:

var strDateTime = "2017-01-05T15:03:25.21"; 
var myDate = new Date(strDateTime); 

будет производить дату 5 Jan 2017 3 : 03: 25,21 PM в местном часовом поясе.

Однако это не рекомендуется делать с учетом общих несоответствий при анализе между реализациями. Следует использовать либо пользовательскую функцию, либо библиотеку, например. используя fecha.js:

var myDate = fecha.parse(strDateTime, "YYYY-MM-DDTHH:mm:ss.SS") 

С ES5 и позже, ISO 8601 даты и времени строки в основном разобраны, как указано в ISO 8601. Основные отличия:

  1. Дата-только формы, как «2016-12 -12" разобраны в формате UTC, а не местный
  2. только „упрощения ISO 8601 расширенного формата“ поддерживается, как описано в ECMA-262 §20.3.1.6 Date Time String Format

Так Дано:

var s = "2017-01-05T15:03:25.21"; 
var d = new Date(s) 

затем d будет преобразован в Дату значения времени UTC на основе установки хост-системы часовых поясов. Если ваш хост настроен на UTC + 0800, то это часовой пояс, который применяется.

Объекты даты не имеют часового пояса. Все, что у них есть, - это одно значение времени, которое представляет миллисекунды с 1970-01-01T00: 00: 00Z. Любая связанная информация о часовом поясе поступает от хоста.Таким образом, комментарий:

//myDate will have another redundant time-zone offset. 

является неправильным. Установка времени хоста-зона будет использоваться для определения смещения, которое используется для вычисления значения времени UTC, а также рассчитать локальные значения, возвращаемые получить * методов, как getFullYear, getMonth, GetDate, getHours и т.д.

строка "2017-01-05T15: 03: 25.21" в системе со смещением +0800 будет генерировать временную стоимость 1483599805210, которая представляет 2017-01-05T07: 03: 25,21Z (т.е. UTC + 0000).

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

Append часовой пояс в строку:

2017-01-05T15:03:25.21+0800 

Используйте UTC эквивалентно:

2017-01-05T07:03:25.21Z 

Используйте значение времени:

1483599805210 

Последнее, как правило, предпочтителен в качестве new Date(timevalue) поддерживается всеми реализациями, недвусмысленна и может быть легко преобразована для использования в других системы.

+0

Спасибо за ваше длинное объяснение. Дайте мне время, чтобы переварить ваши слова. Понял ваше сообщение, что удаление «T» не соответствует стандартам. – zeroflaw

+1

@ zflaw-yep. Снятие T допускается в соответствии с ISO 8601 в определенных условиях, но не ECMA-262. Таким образом, реализация может решить, что отсутствующий T означает, что это не ISO 8601, и поэтому возвращаются к любому разбору, который они хотят (как и Firefox), или решают, что он недействителен ISO 8601 и возвращает недопустимую дату (как и Safari). Оба соответствуют стандарту, хотя само несогласованность вызывает раздражение. : -/ – RobG

+0

Позвольте мне спросить, скажите, если я хочу пойти так: 2017-01-05T15: 03: 25.21 + 0800 Последняя часть «+0800» должна быть рассчитана мной сама? (например, используя функцию getTimezoneOffset) – zeroflaw

3

Вы можете добавить часовой пояс до конца строки, как это:

var strDateTime = "2017-01-05T15:03:25.21"+"-08:00"; 
var myDate = new Date(strDateTime); 

Вы можете прочитать больше о допустимом формате даты здесь:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

https://www.w3.org/TR/NOTE-datetime

+0

что это отличный трюк! (добавить в конец) мне, это добавить «+08: 00». – zeroflaw

+0

Нет необходимости добавлять смещение. Если нет смещения, строка ISO 8601 рассматривается как локальная (в реализациях, совместимых с ES5 и более поздними). – RobG

+0

@RobG, если есть смещение, мой результат добавляет еще одно смещение (как показано в моем вопросе). – zeroflaw

0

Это должно работать

var strDateTime = "2017-01-05T15:03:25.21"; 
var myDate = new Date(strDateTime.replace('T', ' ')); 

OUTPUT для моего часового пояса: чт 5 января 2017 15:03:25 GMT + 0200 (EET)

+0

Это еще лучше (без необходимости получать смещение)! Неплохо! – zeroflaw

+0

Этот ответ не должен приниматься. Если формат «2017-01-05T15: 03: 25.21» разобран вообще (и некоторые браузеры не будут), он будет корректно анализироваться как локальное время (т. Е. Как если бы смещение для хост-системы было добавлено). Удаление T просто делает его частично несовместимым с ISO 8601 и полностью не соответствует ECMA-262, поэтому браузеры (например, Safari) могут возвращать неверную дату на этой основе. – RobG

Смежные вопросы