Moment.js преобразовать в объект даты

696

Используя Moment.js, я не могу преобразовать правильный объект момента в объект даты с часовыми поясами. Я не могу получить правильную дату.

Пример:

var oldDate = new Date(),
    momentObj = moment(oldDate).tz("MST7MDT"),
    newDate = momentObj.toDate();
console.log("start date " + oldDate)
console.log("Format from moment with offset " + momentObj.format())
console.log("Format from moment without offset " + momentObj.utc().format())
console.log("(Date object) Time with offset " + newDate)
console.log("(Date object) Time without offset "+ moment.utc(newDate).toDate())
vadim.zhiltsov
источник
1
Какой выход вы ожидаете и какой выход вы получаете?
Феликс Клинг
4
Выведите мне 4 строки так: <code> (объект Date) время со смещением чт 01 авг 2013 15:23:49 GMT + 0300 (Финляндия (лето)) </ code> Но часовой пояс должен быть MST7MDT
vadim.zhiltsov
Wednesday 24th 2019, 12:47:48 amэто можно конвертировать в 2019-04-23T19:17:48.000Z ? @ vadim.zhiltsov
Анупам Маурья
У объектов даты нет часового пояса, они просто смещены относительно 1970-01-01T00: 00: 00Z. Поэтому, когда вы вызываете toDate , возвращенный объект потерял информацию о часовом поясе, которую вы прикрепили к объекту момента с помощью .tz("MST7MDT"). Вот почему существуют такие библиотеки, как moment.tz, дополняющие простую возможность встроенного объекта Date, который понимает только UTC и часовой пояс хоста, вот и все.
RobG

Ответы:

1237

Используйте это, чтобы преобразовать объект момента в объект даты:

С http://momentjs.com/docs/#/displaying/as-javascript-date/

moment().toDate();

Урожайность:

Tue Nov 04 2014 14:04:01 GMT-0600 (CST)
Chandrew
источник
11
@ Спенсер - Да, он отвечает на заголовок, и toDateдействительно, как получить Dateобъект из moment. Но код в теле вопроса спрашивает о преобразовании часового пояса - что Dateне может сделать. Если время в горах действительно не является часовым поясом пользователя, то я не уверен, как это ответило на вопрос.
Мэтт Джонсон-Пинт
1
@Matt, это просто зависит от того, на какую часть вопроса вы смотрите. Большинство людей ищут в Google и видят, что этот заголовок совпадает с их вопросом и дает ответ, который отвечает на заголовок, а не на сам вопрос. Это может объяснить, почему это имеет наибольшее количество голосов, хотя технически это не помогает ОП.
Спенсер
14
Это действительно правильный ответ? Вопрос заключался в том, как преобразовать объект момента в дату JavaScript, но с помощью TIMEZONE. Это все еще возвращается к местному часовому поясу, когда изменяется на объект даты javascript.
Невероятно,
1
Эй, ребята, проверьте эту ссылку momentjs.com/guides/#/warnings/js-date . Это не рекомендуется и будет удалено в следующем основном выпуске.
gtzinos
3
@gtzinos - то, на что вы ссылаетесь и на что ссылаетесь, - это отдельная проблема и сценарий, например, передача строки в конструктор момента moment("12/12/2011")- это то, где вы получите это сообщение. Это не имеет ничего общего с переходом от момента к дате objmoment().toDate()
btbJosh
51

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

Вы правильно конвертируете момент в часовой пояс, который отражен во второй строке вывода из momentObj.format().

Переключение на UTC не просто сбрасывает смещение, оно переключается обратно на часовой пояс UTC. Если вы собираетесь это сделать, вам вообще не нужен исходный .tz()звонок. Вы могли бы просто сделать moment.utc().

Возможно, вы просто пытаетесь изменить строку выходного формата? Если это так, просто укажите параметры, которые вы хотите для formatметода:

momentObj.format("YYYY-MM-DD HH:mm:ss")

Что касается последних строк вашего кода - когда вы возвращаетесь к Dateобъекту с помощью объекта toDate(), вы отказываетесь от поведения moment.js и возвращаетесь к поведению JavaScript. Объект JavaScript Dateвсегда будет напечатан в местном часовом поясе компьютера, на котором он работает. Там нет ничего, что может сделать .js.

Пара других мелочей:

  • Хотя конструктор моментов может занять Date, обычно лучше его не использовать. Для «сейчас» не используйте moment(new Date()). Вместо этого просто используйте moment(). Оба будут работать, но это излишне избыточно. Если вы анализируете строку, передайте эту строку непосредственно в момент. Не пытайтесь разобрать это Dateпервым. Вы найдете парсер момента гораздо более надежным.

  • Часовые пояса вроде бы MST7MDTсуществуют по причинам обратной совместимости. Они происходят из часовых поясов в стиле POSIX, и только некоторые из них находятся в данных TZDB. Если это не является абсолютно необходимым, вы должны использовать такой ключ, как America/Denver.

Мэтт Джонсон-Пинт
источник
Спасибо, Мэтт! Ваш ответ был полезен. Как вы упомянули об использовании Америки / Денвера вместо MST7MDT, есть ли карта для этих сопоставлений? Я использую немало таких часовых поясов, как CET, EET, EST5EDT, CST6CDT, PST8PDT.
monish001
Можно ли преобразовать, например: "10:20 AM" (полученное время строки от момента (). формат ('чч: мм A')) в объект Date ??
Овен
2
@ram - 1) если у вас есть время, просто используйте .toDate(). 2) Не используйте комментарии, чтобы задавать новые вопросы. Вот для чего предназначена большая кнопка «Задать вопрос» .
Мэтт Джонсон-Пинт
22

.toDate на самом деле не работает для меня, так вот, что я сделал:

futureStartAtDate = new Date(moment().locale("en").add(1, 'd').format("MMM DD, YYYY HH:MM"))

надеюсь это поможет

Mawaheb
источник
2
Этот ответ не отвечает на вопрос. Код - это многословный способ написания moment().add(1, 'd').toDate().
RobG
12

Так как momentjs не контролирует объект даты в JavaScript, я нашел способ обойти это.

const currentTime = new Date();    
const convertTime = moment(currentTime).tz(timezone).format("YYYY-MM-DD HH:mm:ss");
const convertTimeObject = new Date(convertTime);

Это даст вам объект даты javascript с конвертированным временем

Ясит Прабуддхака
источник
2
Это единственный правильный ответ, который прямо отвечает на вопрос.
Аниша Сана
1
Это именно то, что я хотел. Я ожидал, что родные даты будут правильно представлять часовые пояса, но, к сожалению, я ошибся.
mklbtz
1
Формат «ГГГГ-ММ-ДД ЧЧ: мм: сс» не поддерживается Safari, поэтому результат равен нулю . Формат должен быть «ГГГГ-ММ-ДДТЧ: мм: сс» (использовать поддерживаемый формат ECMAScript, букву «Т» между датой и временем).
RobG
4

Мне нужно было иметь информацию о часовом поясе в моей строке даты. Первоначально я использовал, moment.tz(dateStr, 'America/New_York').toString();но затем я начал получать ошибки о подаче этой строки в момент.

Я попытался, moment.tz(dateStr, 'America/New_York').toDate();но затем я потерял информацию о часовом поясе, которая мне была нужна.

Единственное решение, которое возвратило пригодную для использования строку даты с часовым поясом, которое могло быть возвращено в момент, былоmoment.tz(dateStr, 'America/New_York').format();

chovy
источник
4
let dateVar = moment('any date value');
let newDateVar = dateVar.utc().format();

красиво и чисто !!!!

Эмерсон Боттеро
источник
Это было единственное решение в моем случае, которое работало в формате utc. Спасибо
Луис Фебро
3

Чтобы преобразовать любую дату, например, utc:

moment( moment().utc().format( "YYYY-MM-DD HH:mm:ss" )).toDate()
kizoso
источник
2
Это действительно спасло мой день!
HV Шарма
Этот ответ неверен. Он применяет смещение часового пояса дважды: moment().utc()возвращает значения для UTC, затем .format( "YYYY-MM-DD HH:mm:ss" )возвращает строку, для которой было установлено значение UTC без смещения часового пояса, поэтому он анализируется как локальный. Он не соответствует формату момента по умолчанию, поэтому анализируется встроенным парсером. Он также не соответствует ни одному поддерживаемому формату ECMAScript, поэтому синтаксический анализ зависит от реализации. В любом случае, он анализируется как локальный, поэтому смещение часового пояса применяется снова при создании значения времени Date.
RobG
3

Вопрос немного неясен. Я сделаю все возможное, чтобы объяснить это. Сначала вы должны понять, как использовать момент-часовой пояс . В соответствии с этим ответом здесь TypeError: moment (). Tz не является функцией , вы должны импортировать момент из момента времени-часа вместо момента по умолчанию (конечно же, вам нужно сначала установить момент-время npm!). Для большей ясности,

const moment=require('moment-timezone')//import from moment-timezone

Теперь, чтобы использовать функцию часового пояса, используйте moment.tz («date_string / moment ()», «time_zone») ( для получения более подробной информации посетите https://momentjs.com/timezone/ ). Эта функция вернет моментный объект с определенным часовым поясом. Для большей ясности,

var newYork= moment.tz("2014-06-01 12:00", "America/New_York");/*this code will consider NewYork as the timezone.*/

Теперь, когда вы попытаетесь преобразовать newYork (объект момента) с помощью метода toDate () (преобразование формата ISO 8601), вы получите время в Гринвиче, Великобритания. Для получения дополнительной информации просмотрите эту статью https://www.nhc.noaa.gov/aboututc.shtml о UTC. Однако, если вы просто хотите указать свое местное время в этом формате (по нью-йоркскому времени, в соответствии с этим примером), просто добавьте метод .utc (true) с аргументом true к своему объекту момента. Для большей ясности,

newYork.toDate()//will give you the Greenwich ,UK, time.

newYork.utc(true).toDate()//will give you the local time. according to the moment.tz method arg we specified above, it is 12:00.you can ofcourse change this by using moment()

Вкратце, moment.tz учитывает указанный вами часовой пояс и сравнивает ваше местное время с временем в Гринвиче, чтобы получить результат. Я надеюсь, что это было полезно.

Виджей Джошуа Надар
источник
2

момент обновил js lib по состоянию на 06/2018.

var newYork    = moment.tz("2014-06-01 12:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london     = newYork.clone().tz("Europe/London");

newYork.format();    // 2014-06-01T12:00:00-04:00
losAngeles.format(); // 2014-06-01T09:00:00-07:00
london.format();     // 2014-06-01T17:00:00+01:00

если у вас есть свобода использования Angular5 +, то лучше использовать функцию datePipe там, чем функцию часового пояса здесь. Я должен использовать moment.js, потому что мой проект ограничен только Angular2.

Фэн Чжан
источник
1

попробуй (без formatшага)

new Date(moment())

Камил Келчевски
источник
new Date(moment())эквивалентно new Date(). Часовой пояс установлен только для d .
RobG