Вычтите дни из даты в JavaScript

603

Кто-нибудь знает простой способ взять дату (например, сегодня) и вернуться на X дней?

Так, например, если я хочу вычислить дату за 5 дней до сегодняшнего дня.

jonhobbs
источник
4
Я нашел проблемы с использованием принятого ответа. Очевидно, использование отрицательных значений в setDate () не работает должным образом. См. Stackoverflow.com/a/9037132/792287 для другого (лучше?) Решения.
vandiedakaf
5
Возможный дубликат: stackoverflow.com/questions/1187824/…
Андерсон Грин
Проверьте github.com/viebig/datetreta
Гильерме Фибиг

Ответы:

962

Попробуйте что-то вроде этого:

 var d = new Date();
 d.setDate(d.getDate()-5);

Обратите внимание, что это изменяет объект даты и возвращает значение времени обновленной даты.

var d = new Date();

document.write('Today is: ' + d.toLocaleString());

d.setDate(d.getDate() - 5);

document.write('<br>5 days ago was: ' + d.toLocaleString());

Стивен Райтон
источник
9
Вывод этого дает мне длинную строку целых чисел. Любая идея о том, как отформатировать его в 14.05.2012?
user525146
162
Учитывая, что это в верхней части Google, я думаю, я бы ответил на комментарий выше: new Date(new Date().setDate(new Date().getDate()-5))- это будет 5 дней назад. В примере ответа передайте его новой дате, чтобы получить объект даты. Так new Date(d)что вы хотите.
Джесси
8
Проблема в том, что вы можете получить 00, что не является допустимым значением даты.
DominicM
24
setDate(-1)установит дату последнего дня месяца
Питер
5
@ user525146 спросил, как отформатировать число, а не как оно. Нет необходимости в снисходительных ответах. Чтобы отформатировать число, используйте один из toStringметодов Date, например toISOString, toDateStringи т. Д.
Bad Request
83
var dateOffset = (24*60*60*1000) * 5; //5 days
var myDate = new Date();
myDate.setTime(myDate.getTime() - dateOffset);

Если вы выполняете множество непростых манипуляций с датами в своем веб-приложении, DateJS сделает вашу жизнь намного проще:

http://simonwillison.net/2007/Dec/3/datejs/

karim79
источник
23
это крайний случай, но он может потерпеть неудачу в начале / конце летнего времени. вы не вычитаете 5 дней, но 5 * 24 часов. первый день летнего времени длится всего 23 часа, а последний - 25 часов. это обычно не имеет значения, но это то, что нужно учитывать.
Кип
11
@ Кип Я ненавижу летнее время ... и часовые пояса. Мы все должны переехать в GMT.
cwallenpoole
6
@cwallenpoole, чтобы не взорвать ваш пузырь, но они используют DST даже в Гринвиче. Так что, если вы действительно хотите быть в Гринвиче, вы ограничены Исландией и несколькими западноафриканскими странами.
Кип
1
Проблема этого метода в том, что он не работает с новым годом и т. Д.
Даниэль Уильямс
4
@danielWilliams Как это не работает с новым годом? getTime()и setTime()миллисекунды с эпохи. Это не должно иметь значения, если время пересекает границу года.
Машмагар
53

Это выглядит примерно так:

var d = new Date(); // today!
var x = 5; // go back 5 days!
d.setDate(d.getDate() - x);
Крис Нильсен
источник
Вывод этого дает мне длинную строку целых чисел. Любая идея о том, как отформатировать его в 14.05.2012?
user525146
7
Возвращаемое значение d.setDate действительно является целочисленным значением. Тем не менее, вы, вероятно, на самом деле не заинтересованы в возвращаемом значении в этой точке, так как действительное значение «d» было изменено. Ваш реальный вопрос теперь в том, как отформатировать дату, которая теперь находится в «d», а не в возвращаемом значении setDate. (Ну, на самом деле это возвращаемое значение, но к тому моменту это не дата, и я не хочу вводить вас в заблуждение - просто используйте d, это будет быстрее). Для форматирования дат вам нужны методы d.getMonth (), d.getFullYear () и d.getDate (). Вы хотите добавить один в d.getMonth (), поскольку Ян - 0.
Крис Нильсен
2
Как простой метод: function getDaysAgo(b){var a=new Date;a.setDate(a.getDate()-b);return a};тогда простоvar daysAgo45 = getDaysAgo(45);
SpYk3HH
@MiroKrsjak Конечно, это работает, если вы пересекаете конец / начало месяца. Почему бы это не сработало?
Крис Нильсен
23

Я заметил, что getDays + X не работает за пределами дня / месяца. Использование getTime работает до тех пор, пока ваша дата не раньше 1970 года.

var todayDate = new Date(), weekDate = new Date();
weekDate.setTime(todayDate.getTime()-(7*24*3600000));
awjr
источник
3
Я заметил то же самое. Я удивлен, что больше нет, или я что-то упустил?
Шон Гловер
11
Это неверно, новый Date (). SetDate (-1) даст вам последний день предыдущего месяца.
Збрунсон
2
Это также неверно в случае начала / окончания летнего времени. Ваш подход вычитает 7 * 24 часов, при условии, что каждый день имеет 24 часа. Первый день летнего времени длится всего 23 часа, а последний день - 25 часов. setDate (getDate () - 7) не имеет этой проблемы.
Кип
1
GetTime работает от универсального времени. Так что будет правильно вычитать 7 дней времени из объекта Date. Когда вы преобразуете его в строку в указанном часовом поясе, он будет правильно показывать время для этого пояса.
awjr
Будьте осторожны в день смены времени. Когда мы упадем осенью, у этого дня будет 25 часов, так что вычитание 24 часов из полуночи приведет вас в тот же день. Но этот метод (вычитание миллисекунд) будет работать, если вы округляете день после каждой операции до ближайшей полуночи. Вы можете сделать это, сначала добавив 12 часов, а затем установив часы на ноль.
Магматическая
18

получить момент.js. Все крутые дети используют это. У него больше опций форматирования и т. Д. Где

var n = 5;
var dateMnsFive = moment(<your date>).subtract(n , 'day');

Необязательный! Конвертировать в JS Date obj для угловой привязки.

var date = new Date(dateMnsFive.toISOString());

Необязательный! Формат

var date = dateMnsFive.format("YYYY-MM-DD");
Kentonbmax
источник
передавая дату в момент, вы начнете получать предупреждения. Предупреждение об устаревании: предоставленное значение не соответствует распознанному формату RFC2822 или ISO. момент конструирования возвращается к js Date (), который не надежен во всех браузерах и версиях. Не RFC2822 / ISO форматы даты не рекомендуется и будут удалены в следующем основном выпуске. Пожалуйста, обратитесь к momentjs.com/guides/#/warnings/js-date для получения дополнительной информации.
Переключить
13

Я сделал этот прототип для Date, чтобы можно было передавать отрицательные значения для вычитания дней и положительные значения для добавления дней.

if(!Date.prototype.adjustDate){
    Date.prototype.adjustDate = function(days){
        var date;

        days = days || 0;

        if(days === 0){
            date = new Date( this.getTime() );
        } else if(days > 0) {
            date = new Date( this.getTime() );

            date.setDate(date.getDate() + days);
        } else {
            date = new Date(
                this.getFullYear(),
                this.getMonth(),
                this.getDate() - Math.abs(days),
                this.getHours(),
                this.getMinutes(),
                this.getSeconds(),
                this.getMilliseconds()
            );
        }

        this.setTime(date.getTime());

        return this;
    };
}

Итак, чтобы использовать его, я могу просто написать:

var date_subtract = new Date().adjustDate(-4),
    date_add = new Date().adjustDate(4);
Роб Доули
источник
2
Вы можете использовать d.setDate(d.getDate() + days)как положительные, так и отрицательные значения для дней, чтобы добавлять и вычитать дни соответственно. И он должен работать с экземпляром (как это делают другие методы Date), а не создавать и возвращать копию.
RobG
13

Некоторые из существующих решений были близки, но не совсем то, что я хотел. Эта функция работает с положительными или отрицательными значениями и обрабатывает граничные случаи.

function addDays(date, days) {
    return new Date(
        date.getFullYear(),
        date.getMonth(),
        date.getDate() + days,
        date.getHours(),
        date.getMinutes(),
        date.getSeconds(),
        date.getMilliseconds()
    );
}
Джоэл Филлмор
источник
2
будет ли он перенесен на следующий месяц, если я использую этот метод для добавления 20 дней к 15-му числу текущего месяца? Это не похоже на.
Бора
2
@ Бора - да, он правильно увеличивает месяц, если это необходимо. Например, добавление 20 дней к 15 августа: addDays (новая дата (2015, 07, 15), 20) будет возвращать «Пт 04 сентября 2015 00:00:00 GMT-0700 (PDT)»
Джоэль Филлмор,
12

Мне нравится делать математику в миллисекундах. Так что используйтеDate.now()

var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds

и если вам нравится это отформатировано

new Date(newDate).toString(); // or .toUTCString or .toISOString ...

ПРИМЕЧАНИЕ: Date.now()не работает в старых браузерах (например, IE8, я думаю). Полифилл здесь .

ОБНОВЛЕНИЕ Июнь 2015

@socketpair указал на мою небрежность. Как он / она говорит: «У некоторых дней в году есть 23 часа, а у некоторых 25 из-за правил часового пояса».

Если говорить более подробно, приведенный выше ответ будет содержать неточности перехода на летнее время в том случае, если вы хотите рассчитать МЕСТНЫЙ день 5 дней назад в часовом поясе с изменениями для перехода на летнее время, и вы

  • предположить (ошибочно), что Date.now()дает вам текущее локальное время, или
  • Использование, .toString()которое возвращает локальную дату и, следовательно, несовместимо с Date.now()базовой датой в UTC.

Тем не менее, это работает, если вы все делаете математику в UTC, например

A. Вы хотите дату UTC 5 дней назад от СЕЙЧАС (UTC)

var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds UTC
new Date(newDate).toUTCString(); // or .toISOString(), BUT NOT toString

Б. Вы начинаете с базовой даты UTC, отличной от «сейчас», используя Date.UTC()

newDate = new Date(Date.UTC(2015, 3, 1)).getTime() + -5*24*3600000;
new Date(newDate).toUTCString(); // or .toISOString BUT NOT toString
самый шикарный
источник
3
Это не точно. У некоторых дней в году есть 23 часа, а у некоторых 25 из-за правил часового пояса.
socketpair
Я бы беспокоился о сбойных условиях, когда есть високосные секунды ... так что, возможно, это плохо для критического кода.
Робокат
12

Я нахожу проблему с методом getDate () / setDate () в том, что он слишком легко превращает все в миллисекунды, и мне иногда сложно следовать синтаксису.

Вместо этого мне нравится отрабатывать тот факт, что 1 день = 86 400 000 миллисекунд.

Итак, для вашего конкретного вопроса:

today = new Date()
days = 86400000 //number of milliseconds in a day
fiveDaysAgo = new Date(today - (5*days))

Работает как шарм.

Я все время использую этот метод для расчета 30/60/365 дней.

Вы можете легко экстраполировать это, чтобы создать единицы времени для месяцев, лет и т. Д.

Джонатан Бехтель
источник
11

разбить вашу дату на части, а затем вернуть новую дату с установленными значениями

function DateAdd(date, type, amount){
    var y = date.getFullYear(),
        m = date.getMonth(),
        d = date.getDate();
    if(type === 'y'){
        y += amount;
    };
    if(type === 'm'){
        m += amount;
    };
    if(type === 'd'){
        d += amount;
    };
    return new Date(y, m, d);
}

Помните, что месяцы начинаются с нуля, а дни - нет. т.е. новая дата (2009, 1, 1) == 01 февраля 2009 года, новая дата (2009, 1, 0) == 31 января 2009 года;

Джошуа
источник
2
Что произойдет, если вы добавите, например, 50 дней к дате таким образом? Будет ли установлена ​​дата 68 августа 2009 года? Или вы уверены, что это всегда правильно переносится на соответствующий месяц и / или год?
Джеспер
Используется для добавления addDays, addMonths и addYears в Date.prototype. Красиво и просто.
Скотт Айзекс
1
Это должен быть правильный ответ - он работает даже в последний день года, когда принятый ответ не получается.
Крис
Не работает для дат с годами от 1 до 99. ;-) Гораздо лучше просто использовать методы get * и set * .
RobG
8

Не используя вторую переменную, вы можете заменить 7 for на x дней:

let d=new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000))
vaibhavmaster
источник
5

function addDays (date, daysToAdd) {
  var _24HoursInMilliseconds = 86400000;
  return new Date(date.getTime() + daysToAdd * _24HoursInMilliseconds);
};

var now = new Date();

var yesterday = addDays(now, - 1);

var tomorrow = addDays(now, 1);

Петр Макаров
источник
2

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

function dateManipulation(date, days, hrs, mins, operator) {
   date = new Date(date);
   if (operator == "-") {
      var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
      var newDate = new Date(date.getTime() - durationInMs);
   } else {
      var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
      var newDate = new Date(date.getTime() + durationInMs);
   }
   return newDate;
 }

Теперь вызовите эту функцию, передав параметры. Например, вот вызов функции для получения даты до 3 дней с сегодняшнего дня.

var today = new Date();
var newDate = dateManipulation(today, 3, 0, 0, "-");
Малви Панчал
источник
2

Используйте MomentJS .

function getXDaysBeforeDate(referenceDate, x) {
  return moment(referenceDate).subtract(x , 'day').format('MMMM Do YYYY, h:mm:ss a');
}

var yourDate = new Date(); // let's say today
var valueOfX = 7; // let's say 7 days before

console.log(getXDaysBeforeDate(yourDate, valueOfX));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

UtkarshPramodGupta
источник
1

Лучшие ответы привели к ошибке в моем коде, когда в первом месяце он установил будущую дату в текущем месяце. Вот что я сделал,

curDate = new Date(); // Took current date as an example
prvDate = new Date(0); // Date set to epoch 0
prvDate.setUTCMilliseconds((curDate - (5 * 24 * 60 * 60 * 1000))); //Set epoch time
Кишоре Авинени
источник
0

Простой способ управлять датами - использовать Moment.js

Вы можете использовать add. пример

var startdate = "20.03.2014";
var new_date = moment(startdate, "DD.MM.YYYY");
new_date.add(5, 'days'); //Add 5 days to start date
alert(new_date);

Документы http://momentjs.com/docs/#/manipulation/add/

Хуан Кайседо
источник
0

Мне нравится следующее, потому что это одна строка. Не идеально подходит для изменений DST, но обычно достаточно для моих нужд.

var fiveDaysAgo = new Date(new Date() - (1000*60*60*24*5));
ScottE
источник
0

для меня все комбинации работали нормально с приведенным ниже фрагментом кода, фрагмент для реализации Angular-2, если вам нужно добавить дни, передайте положительное число дней, если вам нужно вычесть передать отрицательное число дней

function addSubstractDays(date: Date, numberofDays: number): Date {
let d = new Date(date);
return new Date(
    d.getFullYear(),
    d.getMonth(),
    (d.getDate() + numberofDays)
);
}
Прите агравал
источник
0

Я получаю хороший пробег от даты.js:

http://www.datejs.com/

d = new Date();
d.add(-10).days();  // subtract 10 days

Ницца!

Сайт включает в себя эту красоту:

Datejs не просто разбирает строки, он аккуратно разбивает их на две части

Брет Вайнрауб
источник
0

Если вы хотите вычесть количество дней и отформатировать дату в удобочитаемом формате, вам следует рассмотреть возможность создания пользовательского DateHelperобъекта, который выглядит примерно так:

var DateHelper = {
    addDays : function(aDate, numberOfDays) {
        aDate.setDate(aDate.getDate() + numberOfDays); // Add numberOfDays
        return aDate;                                  // Return the date
    },
    format : function format(date) {
        return [
           ("0" + date.getDate()).slice(-2),           // Get day and pad it with zeroes
           ("0" + (date.getMonth()+1)).slice(-2),      // Get month and pad it with zeroes
           date.getFullYear()                          // Get full year
        ].join('/');                                   // Glue the pieces together
    }
}

// With this helper, you can now just use one line of readable code to :
// ---------------------------------------------------------------------
// 1. Get the current date
// 2. Subtract 5 days
// 3. Format it
// 4. Output it
// ---------------------------------------------------------------------
document.body.innerHTML = DateHelper.format(DateHelper.addDays(new Date(), -5));

(см. также эту скрипку )

Джон Слегерс
источник
0

Посмотрите следующий код, вычтите дни из текущей даты. Также установите месяц в соответствии с вычтенной датой.

var today = new Date();
var substract_no_of_days = 25;

today.setTime(today.getTime() - substract_no_of_days* 24 * 60 * 60 * 1000);
var substracted_date = (today.getMonth()+1) + "/" +today.getDate() + "/" + today.getFullYear();

alert(substracted_date);
Манодж Джа
источник
-1

При установке даты она конвертируется в миллисекунды, поэтому вам необходимо преобразовать ее обратно в дату:

Этот метод также принимает во внимание, изменение нового года и т. Д.

function addDays( date, days ) {
    var dateInMs = date.setDate(date.getDate() - days);
    return new Date(dateInMs);
}

var date_from = new Date();
var date_to = addDays( new Date(), parseInt(days) );
Дэниел Уильямс
источник
-1

Вы можете использовать Javascript.

var CurrDate = new Date(); // Current Date
var numberOfDays = 5;
var days = CurrDate.setDate(CurrDate.getDate() + numberOfDays);
alert(days); // It will print 5 days before today

Для PHP,

$date =  date('Y-m-d', strtotime("-5 days")); // it shows 5 days before today.
echo $date;

Надеюсь, это поможет вам.

Феникс
источник
-1

Я пересчитал в миллисекунды и вычтенные дни иначе месяц и год не изменится и логично

var numberOfDays = 10;//number of days need to deducted or added
var date = "01-01-2018"// date need to change
var dt = new Date(parseInt(date.substring(6), 10),        // Year
              parseInt(date.substring(3,5), 10) - 1, // Month (0-11)
              parseInt(date.substring(0,2), 10));
var new_dt = dt.setMilliseconds(dt.getMilliseconds() - numberOfDays*24*60*60*1000);
new_dt = new Date(new_dt);
var changed_date = new_dt.getDate()+"-"+(new_dt.getMonth()+1)+"-"+new_dt.getFullYear();

Надежда помогает

hemanjosko
источник
-1

var date = new Date();
var day = date.getDate();
var mnth = date.getMonth() + 1;

var fDate = day + '/' + mnth + '/' + date.getFullYear();
document.write('Today is: ' + fDate);
var subDate = date.setDate(date.getDate() - 1);
var todate = new Date(subDate);
var today = todate.getDate();
var tomnth = todate.getMonth() + 1;
var endDate = today + '/' + tomnth + '/' + todate.getFullYear();
document.write('<br>1 days ago was: ' + endDate );

белал ахмад
источник
1
Вы всегда должны комментировать свой код / ​​ответ, так как некоторые люди могут не получить то, что вы делаете
Майкл
-1

Использование современного синтаксиса функции JavaScript

const getDaysPastDate = (daysBefore, date = new Date) => new Date(date - (1000 * 60 * 60 * 24 * daysBefore));

console.log(getDaysPastDate(1)); // yesterday

vdegenne
источник
-1

Попробуйте что-то вроде этого

dateLimit = (curDate, limit) => {
    offset  = curDate.getDate() + limit
    return new Date( curDate.setDate( offset) )
}

currDate может быть любой датой

предел может быть разницей в количестве дней (положительный для будущего и отрицательный для прошлого)

wahid_abdul
источник
-1

Это даст вам результат в последние 10 дней. Работая на 110%, вы не получите никаких проблем.

var date = new Date();
var day=date.getDate();
var month=date.getMonth() + 1;
var year=date.getFullYear();
var startDate=day+"/"+month+"/"+year;
var dayBeforeNineDays=moment().subtract(10, 'days').format('DD/MM/YYYY');
startDate=dayBeforeNineDays;
var endDate=day+"/"+month+"/"+year;

Вы можете изменить дни вычитания в соответствии с вашими требованиями

Зубайр
источник
-2
var daysToSubtract = 3;
$.datepicker.formatDate('yy/mm/dd', new Date() - daysToSubtract) ;
сэр Уолтмор III
источник
-2

var d = new Date();

document.write('Today is: ' + d.toLocaleString());

d.setDate(d.getDate() - 31);

document.write('<br>5 days ago was: ' + d.toLocaleString());

gatlingovind
источник