Moment.js transforma em objeto de data

696

Usando Moment.js, não consigo transformar um objeto de momento correto em um objeto de data com fusos horários. Não consigo a data correta.

Exemplo:

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
fonte
1
Qual saída você espera e qual saída você obtém?
Felix Kling
4
4 linhas me dão saída: <code> (objeto Data) Hora com deslocamento Qui 01/08/2013 15:23:49 GMT + 0300 (Финляндия (лето)) </code> Mas o fuso horário deve ser MST7MDT
vadim.zhiltsov
Wednesday 24th 2019, 12:47:48 amisso é possível converter 2019-04-23T19:17:48.000Z ? @ vadim.zhiltsov
Anupam Maurya
Os objetos de data não possuem um fuso horário, são apenas um deslocamento de 1970-01-01T00: 00: 00Z. Portanto, quando você chama toDate , o objeto retornado perde as informações de fuso horário anexadas ao objeto de momento .tz("MST7MDT"). É por isso que existem bibliotecas como moment.tz, para complementar a capacidade de bare bones do objeto Date incorporado, que apenas entende o UTC e o fuso horário do host, é isso.
RobG 16/02

Respostas:

1235

Use isso para transformar um objeto de momento em um objeto de data:

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

moment().toDate();

Rendimentos:

Tue Nov 04 2014 14:04:01 GMT-0600 (CST)
Chandrew
fonte
11
@ Spencer - Sim, ele responde o título e toDateé realmente como obter um Dateobjeto de a moment. Mas o código no corpo da pergunta pergunta sobre a conversão de fuso horário - o que Datenão pode ser feito. A menos que o horário da montanha seja realmente o fuso horário do usuário, não tenho certeza de como isso respondeu à pergunta.
Matt Johnson-Pint
1
@ Matt depende apenas de qual parte da pergunta você está olhando. A maioria das pessoas pesquisa no google e vê que esse título está alinhado com a pergunta e promove a resposta que responde ao título, não o corpo da pergunta. Isso pode explicar por que isso tem mais votos positivos, embora tecnicamente não ajude o OP.
Spencer
14
Essa é realmente a resposta correta? A questão era como transformar o objeto moment em uma data javascript, mas com TIMEZONE. Ele ainda volta ao fuso horário local quando muda para o objeto de data javascript.
Unspeakable
1
Olá pessoal, verifique este link momentjs.com/guides/#/warnings/js-date . Isso é desencorajado e será removido no próximo grande lançamento.
Gtzinos # 18/16
3
@ gtzinos o que você está vinculando e se referindo é uma questão e um cenário separados, por exemplo, passar uma string para o momento em que o construtor moment("12/12/2011")é onde você receberia essa mensagem. Não tem nada a ver com ir de um momento para o outro, objmoment().toDate()
btbJosh
51

Desde que você tenha inicializado o fuso horário com os dados para as zonas desejadas , seu código funcionará conforme o esperado.

Você está convertendo corretamente o momento no fuso horário, o que é refletido na segunda linha de saída de momentObj.format().

Mudar para UTC não apenas reduz o deslocamento, mas volta para o fuso horário UTC. Se você fizer isso, não precisará da .tz()chamada original . Você poderia apenas fazer moment.utc().

Talvez você esteja apenas tentando alterar a string do formato de saída? Nesse caso, basta especificar os parâmetros que você deseja para o formatmétodo:

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

Com relação às últimas linhas do seu código - quando você volta a Dateusar um objeto toDate(), está desistindo do comportamento de moment.js e voltando ao comportamento do JavaScript. Um Dateobjeto JavaScript sempre será impresso no fuso horário local do computador em que está sendo executado. Não há nada que moment.js possa fazer sobre isso.

Algumas outras pequenas coisas:

  • Embora o momento em que o construtor possa aceitar um Date, geralmente é melhor não usá-lo. Para "agora", não use moment(new Date()). Em vez disso, basta usar moment(). Ambos irão funcionar, mas é desnecessariamente redundante. Se você estiver analisando a partir de uma sequência, passe-a diretamente para o momento. Não tente analisá-lo Dateprimeiro. Você encontrará o analisador de momento muito mais confiável.

  • Os fusos horários como MST7MDTexistem por motivos de compatibilidade com versões anteriores. Eles se originam de fusos horários no estilo POSIX e apenas alguns deles estão nos dados TZDB. A menos que seja absolutamente necessário, você deve usar uma chave como America/Denver.

Matt Johnson-Pint
fonte
Obrigado Matt! Sua resposta foi útil. Como você mencionou sobre o uso da América / Denver em vez do MST7MDT, existe um mapa disponível para esses mapeamentos? Estou usando vários fusos horários como CET, EET, EST5EDT, CST6CDT, PST8PDT.
precisa saber é o seguinte
é possível converter, por exemplo: "10:20 AM" (hora da string obtida do momento (). formato ('hh: mm A')) para o objeto Date?
ram
2
@ram - 1) se tiver um momento, basta usar .toDate(). 2) Não use comentários para fazer novas perguntas. É para isso que serve o grande botão "Fazer pergunta" .
Matt Johnson-Pint
22

.toDate realmente não funcionou para mim, então, aqui está o que eu fiz:

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

espero que isto ajude

Mawaheb
fonte
2
Esta resposta não responde à pergunta. O código é uma maneira extensa de escrever moment().add(1, 'd').toDate().
RobG 16/02
12

Como momentjs não tem controle sobre o objeto de data do javascript, encontrei uma solução alternativa para isso.

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

Isso fornecerá um objeto de data javascript com o horário convertido

Yasith Prabuddhaka
fonte
2
Esta é a única resposta correta que responde diretamente à pergunta.
Anish Sana
1
Isto é exatamente o que eu queria. Eu esperava que as datas nativas representassem os fusos horários corretamente, mas infelizmente estava errado.
Mklbtz
1
O formato "AAAA-MM-DD HH: mm: ss" não é suportado pelo Safari, portanto, o resultado é nulo . O formato deve ser "AAAA-MM-DDTHH: mm: ss" (use um formato compatível com ECMAScript, um "T" entre as partes de data e hora).
RobG 16/02
4

Eu precisava ter informações de fuso horário na minha sequência de datas. Eu estava usando originalmente, moment.tz(dateStr, 'America/New_York').toString();mas então comecei a receber erros sobre a alimentação dessa string de volta ao momento.

Eu tentei o, moment.tz(dateStr, 'America/New_York').toDate();mas depois perdi as informações de fuso horário que eu precisava.

A única solução que retornou uma sequência de datas utilizável com fuso horário que poderia ser recuperada no momento foimoment.tz(dateStr, 'America/New_York').format();

chovy
fonte
4
let dateVar = moment('any date value');
let newDateVar = dateVar.utc().format();

Legal e Limpo!!!!

Emerson Bottero
fonte
Esta foi a única solução aqui no meu caso que funcionou para ter um formato utc. Obrigado
Luis Febro
3

Para converter qualquer data, por exemplo, utc:

moment( moment().utc().format( "YYYY-MM-DD HH:mm:ss" )).toDate()
kizoso
fonte
2
Isso realmente salvou meu dia!
HV Sharma
Esta resposta está errada. Aplica o deslocamento do fuso horário duas vezes: moment().utc()retorna valores para UTC e, em seguida, .format( "YYYY-MM-DD HH:mm:ss" )retorna uma sequência que foi definida como UTC sem um deslocamento de fuso horário e, portanto, é analisada como local. Ele não corresponde a um formato de momento padrão e, portanto, é analisado pelo analisador incorporado. Também não corresponde a nenhum formato suportado pelo ECMAScript, portanto, a análise depende da implementação. De qualquer forma, ele é analisado como local para que o deslocamento do fuso horário seja aplicado novamente ao criar o valor da hora da Data.
RobG 16/02
3

A questão é um pouco obscura. Eu farei o meu melhor para explicar isso. Primeiro você deve entender como usar o fuso horário do momento . De acordo com esta resposta aqui, TypeError: moment (). Tz não é uma função , você precisa importar o momento do fuso horário do momento em vez do momento padrão (é claro que você precisará instalar o fuso horário do momento!). Por uma questão de clareza,

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

Agora, para usar o recurso de fuso horário, use moment.tz ("date_string / moment ()", "time_zone") (visite https://momentjs.com/timezone/ para obter mais detalhes). Esta função retornará um objeto de momento com um fuso horário específico. Por uma questão de clareza,

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

Agora, quando você tenta converter newYork (o objeto momento) com toDate () do momento ( conversão de formato ISO 8601), você obtém o horário de Greenwich, Reino Unido. Para mais detalhes, consulte este artigo https://www.nhc.noaa.gov/aboututc.shtml , sobre o UTC. No entanto, se você quiser apenas a hora local neste formato (hora de Nova York, de acordo com este exemplo), adicione o método .utc (true) , com o argumento true , ao objeto moment. Por uma questão de clareza,

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()

Em resumo, o moment.tz considera o fuso horário especificado e compara o horário local com o horário de Greenwich para fornecer um resultado. Espero que isso tenha sido útil.

Vijay Joshua Nadar
fonte
2

moment atualizou o js lib a partir de 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

se você tiver liberdade para usar o Angular5 +, use melhor o recurso datePipe lá do que a função de fuso horário aqui. Eu tenho que usar o moment.js porque meu projeto se limita apenas ao Angular2.

Feng Zhang
fonte
1

tente (sem formatpasso)

new Date(moment())

Kamil Kiełczewski
fonte
new Date(moment())é equivalente a new Date(). O fuso horário está definido apenas para d .
RobG 16/02