¿Cómo clonar un objeto Date?

498

Asignar una Datevariable a otra copiará la referencia a la misma instancia. Esto significa que cambiar uno cambiará al otro.

¿Cómo puedo clonar o copiar una Dateinstancia?

Árvíztűrő tükörfúrógép
fuente

Respuestas:

739

Use el método del objeto DategetTime() , que devuelve el número de milisegundos desde el 1 de enero de 1970 00:00:00 ( hora de la época ):

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

En Safari 4, también puedes escribir:

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

... pero no estoy seguro de si esto funciona en otros navegadores. (Parece funcionar en IE8).

Steve Harrison
fuente
99
JSON para este fragmento? Parece que estas personas deberían tener sus conceptos básicos claros ... Como confundir jQuery con JavaScript DOM.
Boldewyn el
17
Otra forma de escribir esta buena solución sería extender el prototipo de Fecha: Date.prototype.clone = function() { return new Date(this.getTime()); }; que luego podría usar comocopiedDate = date.clone();
Ryan
66
El copiedDate = new Date(date)enfoque funciona en IE6 +. En Firefox, las dos opciones tienen la misma velocidad.
Ryan
14
new Date(date)igual que new Date(date.getTime()), porque JS intentará llamar date.valueOf()cuando necesite un número, y date.valueOf()es lo mismo que date.getTime(), referencia Date.valueOf Object.valueOf
Steely Wing
10
No use new Date(date), use new Date(date.getTime()o en su new Date(date.valueOf)lugar, ya que la primera forma puede generar diferencias entre las fechas en al menos Firefox e IE (no en Chrome). Por ejemplo, el uso toISOString()en ambas fechas en Firefox genera "2015-04-21T04:56:42.000Z"y "2015-04-21T04:56:42.337Z".
Crudh
115

Este es el enfoque más limpio

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

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

AnthonyWJones
fuente
99
El método "valueOf ()" para los objetos "Date" produce el mismo resultado que su método "getTime ()" (el número de milisegundos desde el tiempo de época).
Steve Harrison
35
@Steve: verdadero, pero getTime () podría "parece" que solo devuelve la hora y no incluye la fecha, de ahí mi referencia a "más limpio". Francamente, el tipo de fecha en Javascript es un poco zona de desastre, nunca debería haber sido mutable en primer lugar.
AnthonyWJones
1
@AnthonyWJones: Correcto, entiendo lo que quieres decir.
Steve Harrison el
3
Estoy de acuerdo en que .valueOf () es más claro. A veces me olvido y uso .getMilliseconds () b / c para mí, que parece que significa milisegundos medios desde la época.
Tom Wayson
1
+1 a Steve Harrison: Me preguntaba si ese era el caso, gracias por la aclaración.
Brian Lacy
26
var orig = new Date();
var copy = new Date(+orig);
Dave
fuente
3
Me gusta esta solución lo mejor.
A1rPun
3
Muy preciso y limpio :)
robinmitra
33
Excepto que tendrás que explicar lo que esa magia +está haciendo a todos menos a los expertos de JS.
Stijn de Witt
8
:) +signo es unray operador aquí. Significa new Date( Number(orig)) . Más aquí: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Leonard Lepadatu
14

Versión simplificada:

Date.prototype.clone = function () {
    return new Date(this.getTime());
}
Berezh
fuente
72
no te meterás con los objetos incorporados
Pawel
3
No te meterás con objetos que no posees. Debe hacer una nueva copia y llamarla SuperDate o algo así, dentro de su alcance. Muchos errores difíciles de probar están causados ​​por la funcionalidad del objeto que cambia inesperadamente.
Ray Foss
Esto funcionaría, pero por razones de mantenimiento, este enfoque se consideraría como un olor a código. He escrito un enfoque que generalmente uso en mi codificación: actuts.wordpress.com/2017/01/10/…
Allan Chua
1
Además, no veo esta necesidad de intentar agregar métodos a las incorporadas en primer lugar. Estudie la programación funcional y descubra por qué una buena función anticuada es en realidad mucho más poderosa que los métodos en el objeto mismo. Es también más corta: const cloneDate = d => new Date(d.getTime()).
Stijn de Witt
6

Descubrí que esta simple asignación también funciona:

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

Pero no sé lo "seguro" que es. Probado con éxito en IE7 y Chrome 19.

LK
fuente
99
No use new Date(date), use new Date(date.getTime()o en su new Date(date.valueOf)lugar, ya que la primera forma puede generar diferencias entre las fechas en al menos Firefox e IE (no en Chrome). Por ejemplo, el uso toISOString()en ambas fechas en Firefox genera "2015-04-21T04:56:42.000Z"y "2015-04-21T04:56:42.337Z".
Crudh