Как клонировать объект Date?

498

Присвоение Dateпеременной другой скопирует ссылку на тот же экземпляр. Это означает, что изменение одного изменит другое.

Как я могу на самом деле клонировать или скопировать Dateэкземпляр?

Árvíztűrő tükörfúrógép
источник

Ответы:

739

Используйте метод объекта DategetTime() , который возвращает количество миллисекунд с 1 января 1970 года 00:00:00 ( время эпохи ):

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

В Safari 4 вы также можете написать:

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

... но я не уверен, работает ли это в других браузерах. (Похоже, работает в IE8).

Стив Харрисон
источник
9
JSON для этого фрагмента? Похоже, что эти люди должны понять свои основы ... Как принять jQuery для JavaScript DOM.
Болдевин
17
Другим способом написать это хорошее решение было бы расширение прототипа Date: Date.prototype.clone = function() { return new Date(this.getTime()); }; который вы могли бы затем использовать какcopiedDate = date.clone();
Ryan
6
copiedDate = new Date(date)Подход работает в IE6 +. В Firefox оба варианта имеют одинаковую скорость.
Райан
14
new Date(date)так же, как new Date(date.getTime()), потому что JS будет пытаться звонить, date.valueOf()когда ему нужен номер, и date.valueOf()аналогичен date.getTime()ссылке Date.valueOf Object.valueOf
Steely Wing
10
Не используйте new Date(date), используйте new Date(date.getTime()или new Date(date.valueOf)вместо этого, так как первый способ может привести к различиям между датами по крайней мере в Firefox и IE (не в Chrome). Например, использование toISOString()обеих дат в Firefox создает "2015-04-21T04:56:42.000Z"и "2015-04-21T04:56:42.337Z".
Crudh
115

Это самый чистый подход

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

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

AnthonyWJones
источник
9
Метод «valueOf ()» для объектов «Date» дает тот же результат, что и его метод «getTime ()» (количество миллисекунд с начала эпохи).
Стив Харрисон
35
@Steve: true, но getTime () может «выглядеть» так, как будто возвращает только время и не включать в себя дату, поэтому я ссылаюсь на «самый чистый». Честно говоря, тип Date в Javascript - это нечто вроде зоны бедствия, он никогда не должен был изменяться с самого начала.
AnthonyWJones
1
@AnthonyWJones: Хорошо, я понимаю, что вы имеете в виду.
Стив Харрисон
3
Я согласен, что .valueOf () более понятен. Иногда я забываю и использую .getMilliseconds () b / c для меня, который звучит так, как будто это означает средние миллисекунды со времени эпохи.
Том Уэйсон
1
+1 Стиву Харрисону: мне было интересно, так ли это, спасибо за разъяснения.
Брайан Лейси
26
var orig = new Date();
var copy = new Date(+orig);
Дейв
источник
3
Мне нравится это решение больше всего.
A1rPun
3
Очень точный и чистый :)
Робинмитра
33
За исключением того, что вам придется объяснять, что эта магия +делает никому, кроме экспертов JS.
Стейн де Витт
8
:) +знак является единственным оператором здесь. Значит new Date( Number(orig)) . Подробнее здесь: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Леонард Лепадату,
14

Упрощенная версия:

Date.prototype.clone = function () {
    return new Date(this.getTime());
}
Berezh
источник
72
ты не должен связываться со встроенными объектами
Павел
3
Не связывайся с предметами, которыми ты не владеешь. Вы должны сделать новую копию и назвать ее SuperDate или что-то, не выходя за рамки. Много трудностей для проверки на наличие ошибок вызвано неожиданным изменением функциональности объекта.
Рэй Фосс
Это будет работать, но по причинам ремонтопригодности. Этот подход будет рассматриваться как запах кода. Я написал подход, который обычно использую в своем кодировании: actuts.wordpress.com/2017/01/10/…
Аллан Чуа
1
Также я не вижу необходимости пытаться добавлять методы во встроенные модули. Изучите функциональное программирование и выясните, почему хорошая старомодная функция на самом деле намного мощнее методов самого объекта. Это также короче const cloneDate = d => new Date(d.getTime()).
Стейн де Витт
6

Я узнал, что это простое назначение также работает:

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

Но я не знаю, насколько это безопасно. Успешно протестировано в IE7 и Chrome 19.

LK
источник
9
Не используйте new Date(date), используйте new Date(date.getTime()или new Date(date.valueOf)вместо этого, так как первый способ может привести к различиям между датами по крайней мере в Firefox и IE (не в Chrome). Например, использование toISOString()обеих дат в Firefox создает "2015-04-21T04:56:42.000Z"и "2015-04-21T04:56:42.337Z".
Crudh