Como clonar um objeto Date?

498

Atribuir uma Datevariável a outra copiará a referência para a mesma instância. Isso significa que mudar um mudará o outro.

Como posso realmente clonar ou copiar uma Dateinstância?

Controlaríztűrő tükörfúrógép
fonte

Respostas:

739

Use o método do objeto DategetTime() , que retorna o número de milissegundos desde 1 de janeiro de 1970 00:00:00 ( horário da época ):

var date = new Date();
var copiedDate = new Date(date.getTime());

No Safari 4, você também pode escrever:

var date = new Date();
var copiedDate = new Date(date);

... mas não tenho certeza se isso funciona em outros navegadores. (Parece funcionar no IE8).

Steve Harrison
fonte
9
JSON para este snippet? Parece que essas pessoas devem esclarecer o básico ... Como confundir jQuery com JavaScript DOM.
7119 Boldewyn
17
Outra maneira de escrever esta solução agradável seria estender o protótipo Data: Date.prototype.clone = function() { return new Date(this.getTime()); }; O que você poderia então usar comocopiedDate = date.clone();
Ryan
6
A copiedDate = new Date(date)abordagem funciona no IE6 +. No Firefox, as duas opções são da mesma velocidade.
Ryan
14
new Date(date)igual a new Date(date.getTime()), porque o JS tentará ligar date.valueOf()quando precisar de um número e date.valueOf()é o mesmo que date.getTime(), referência Date.valueOf Object.valueOf
Steely Wing
10
Não use new Date(date), use new Date(date.getTime()ou, new Date(date.valueOf)em vez disso, pois a primeira maneira pode levar a diferenças entre as datas no mínimo no Firefox e no IE (não no Chrome). Por exemplo, o uso toISOString()nas duas datas no Firefox gera "2015-04-21T04:56:42.000Z"e "2015-04-21T04:56:42.337Z".
crudh
115

Esta é a abordagem mais limpa

let dat = new Date() 
let copyOf = new Date(dat.valueOf())

console.log(dat);
console.log(copyOf);

AnthonyWJones
fonte
9
O método "valueOf ()" para objetos "Date" produz o mesmo resultado que o método "getTime ()" (o número de milissegundos desde o tempo da época).
Steve Harrison
35
@ Steve: true, mas getTime () poderia "parecer", pois apenas retorna a hora e não inclui a data, portanto, minha referência a "mais limpa". Francamente, o tipo Data em Javascript é um pouco desastroso, nunca deveria ter sido mutável.
7119 AnthonyWJones
1
@AnthonyWJones: Certo, entendo o que você quer dizer.
Steve Harrison
3
Concordo que .valueOf () é mais claro. Às vezes, esqueço e uso .getMilliseconds () b / c para mim que parece significar milissegundos desde o tempo da época.
Tom Wayson
1
+1 para Steve Harrison: Eu queria saber se era esse o caso, obrigado pelo esclarecimento.
Brian Lacy
26
var orig = new Date();
var copy = new Date(+orig);
Dave
fonte
3
Eu gosto desta solução da melhor maneira.
A1rPun
3
Muito preciso e limpo :)
robinmitra
33
Exceto que você terá que explicar o que essa mágica +está fazendo com ninguém além de especialistas em JS.
Stijn de Witt
8
:) +sinal é operador unaray aqui. Isso significa new Date( Number(orig)) . Mais aqui: developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Leonard Lepadatu # 03
14

Versão simplificada:

Date.prototype.clone = function () {
    return new Date(this.getTime());
}
Berezh
fonte
72
tu não mexerás com objetos embutidos
Pawel
3
Não mexerás com objetos que não possuis. Você deve fazer uma nova cópia e chamá-la SuperDate ou algo assim, dentro do seu escopo. Muitos erros de teste são causados ​​pela alteração inesperada da funcionalidade do objeto.
Ray Foss
Isso funcionaria, mas por motivos de manutenção, essa abordagem seria considerada um cheiro de código. Eu escrevi uma abordagem que eu costumo usar na minha codificação: actuts.wordpress.com/2017/01/10/…
Allan Chua
1
Também não vejo essa necessidade de tentar adicionar métodos aos built-ins em primeiro lugar. Estude programação funcional e descubra por que uma boa função antiquada é realmente muito mais poderosa que os métodos no próprio objeto. É também mais curtos: const cloneDate = d => new Date(d.getTime()).
Stijn de Witt
6

Descobri que esse simples trabalho também funciona:

dateOriginal = new Date();
cloneDate = new Date(dateOriginal);

Mas não sei o quão "seguro" é. Testado com sucesso no IE7 e Chrome 19.

LK
fonte
9
Não use new Date(date), use new Date(date.getTime()ou, new Date(date.valueOf)em vez disso, pois a primeira maneira pode levar a diferenças entre as datas no mínimo no Firefox e no IE (não no Chrome). Por exemplo, o uso toISOString()nas duas datas no Firefox gera "2015-04-21T04:56:42.000Z"e "2015-04-21T04:56:42.337Z".
crudh