Як обчислити дату в JavaScript за три місяці до сьогоднішнього дня?


147

Я намагаюся призначити дату, яка за 3 місяці до поточної дати. Я отримую поточний місяць за наведеним нижче кодом

var currentDate = new Date();
var currentMonth = currentDate.getMonth()+1;

Чи можете ви, хлопці, надати мені логіку обчислити та сформувати дату (об’єкт типу Dateданих), враховуючи, що коли місяць - січень (1), за 3 місяці до дати це буде ОКТОбер (10)?

Відповіді:


323
var d = new Date();
d.setMonth(d.getMonth() - 3);

Це працює за січень. Запустіть цей фрагмент:

var d = new Date("January 14, 2012");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() - 3);
console.log(d.toLocaleDateString());


Є деякі застереження ...

Місяць - це цікаво. Як Ви визначаєте 1 місяць? 30 днів? Більшість людей скажуть, що місяць тому означає той самий день місяця за необхідним цитуванням попереднього місяця . Але більше половини часу, тобто 31 день тому, а не 30. І якщо сьогодні 31 число місяця (а це не серпень чи декабер), цього місяця не існує в попередньому місяці.

Цікаво, що Google погоджується з JavaScript, якщо ви запитаєте його, який день на місяць раніше, ніж наступний день :

Результат пошуку Google за "місяць до 31 березня" показує "3 березня"

Там також сказано, що один місяць триває 30,4167 днів : Результат пошуку Google за "місяць у дні" показує "30,4167"

Отже, чи є місяць до 31 березня того ж дня, що і один місяць до 28 березня, на 3 дні раніше? Все це залежить від того, що ви маєте на увазі під "місяцем раніше". Ідіть, поспілкуйтеся з власником продукту.

Якщо ви хочете зробити так, як робить momentjs, і виправити ці помилки в останній день місяця, перейшовши на останній день місяця, ви можете зробити щось подібне:

const d = new Date("March 31, 2019");
console.log(d.toLocaleDateString());
const month = d.getMonth();
d.setMonth(d.getMonth() - 1);
while (d.getMonth() === month) {
    d.setDate(d.getDate() - 1);
}
console.log(d.toLocaleDateString());

Якщо ваші вимоги складніші, скористайтеся математикою і напишіть код. Ви розробник! Вам не потрібно встановлювати бібліотеку! Вам не потрібно копіювати та вставляти з stackoverflow! Ви можете розробити код самостійно, щоб зробити саме те, що вам потрібно!


var currentDate = нова дата (); var currentMonth = currentDate.getMonth () -12; var pastDate = нова дата (2011, currentMonth, 01); попередження (pastDate); це спрацювало, перевірено 12 місяців
KeenUser

Це жорстока відповідь ... Звідки я збираюся взяти 2012,0,15? Перетворити існуючий місяць -1?
Alex G

3
@AlexG - Якщо ви новачок у розборі дат JavaScript, то я можу побачити, як мій швидкий приклад був би заплутаним. JavaScript виражає місяці як нульові, де січень дорівнює нулю. Щоб уникнути подібної плутанини, тим більше, що це не має нічого спільного з запитанням або моєю відповіддю, я оновив демонстраційну версію, щоб отримати дату з рядка, яка повинна бути більш інтуїтивно зрозумілою.
gilly3

7
Я знаю, що це стара, але якщо дата - 31 березня, і ви віднімаєте один місяць за цим методом, результат - 2 березня. jsfiddle.net/atamata/rvumf7dg
atamata

@atamata - Так, це дивно, але передбачувано і очікувано. 31 день після закінчення попереднього місяця для березня - 31 березня, а для лютого - 2 березня. Якщо ви хочете рахувати з кінця місяця, вам доведеться написати для цього якийсь спеціальний код.
gilly3

28

Я рекомендую використовувати бібліотеку під назвою Moment.js.

Він добре перевірений, працює між браузером та на серверній стороні (я використовую його як у проектах Angular, так і у вузлах). Він чудово підтримує мовні дати.

http://momentjs.com/

var threeMonthsAgo = moment().subtract(3, 'months');

console.log(threeMonthsAgo.format()); // 2015-10-13T09:37:35+02:00

.format()повертає рядкове подання дати, відформатованої у форматі ISO 8601 . Ви також можете використовувати його у власному форматі дати таким чином:.format('dddd, MMMM Do YYYY, h:mm:ss a')


10

"Один вкладиш" (у багатьох рядках для легкого читання)), який слід поставити безпосередньо у змінну:

var oneMonthAgo = new Date(
    new Date().getFullYear(),
    new Date().getMonth() - 1, 
    new Date().getDate()
);

приємно! Не впевнений, чи застосовний він до кожного сценарію, але, здається, він працює досить добре.
Девін Філдс

8

Щоб зробити речі справді простими, ви можете використовувати DateJS, бібліотеку дат для JavaScript:

http://www.datejs.com/

Приклад для вас:

Date.today().add({ months: -1 });

8

Це має обробляти додавання / віднімання, просто додайте від'ємне значення для віднімання і додатне значення для додавання. Це також вирішує проблему кросовер за місяць.

function monthAdd(date, month) {
    var temp = date;
    temp = new Date(date.getFullYear(), date.getMonth(), 1);
    temp.setMonth(temp.getMonth() + (month + 1));
    temp.setDate(temp.getDate() - 1); 

    if (date.getDate() < temp.getDate()) { 
        temp.setDate(date.getDate()); 
    }

    return temp;    
}

6

Якщо setMonthметод, запропонований gilly3, не є тим, що ви шукаєте, врахуйте:

var someDate = new Date(); // add arguments as needed
someDate.setTime(someDate.getTime() - 3*28*24*60*60);
// assumes the definition of "one month" to be "four weeks".

Можна використовувати будь-який час, просто встановіть правильні кратні.


Я б пішов з відповіддю gilly3. Ваш припускає фіксовану кількість секунд на місяць. Арифметична дата JavaScript не буде тримати день правильним. Три місяці до 28 вересня має бути 28 липня.
Рей Тол

1
Цікаво, який JavaScript обчислить 31 березня мінус 1 місяць.
Niet the Dark Absol

1
У такому випадку ви отримуєте 3 березня (за 2011 рік), оскільки саме так 31 лютого знаходиться в поблажливому режимі. Але відніміть 2 місяці, і ви отримаєте 31 січня. За 28-денною моделлю на місяць ви б не стали. Настільки слабкий, як Dateклас, і стільки, скільки Date.js віддається перевазі, він принаймні моделює поблажливий пролептичний календар, достатньо хороший для випадкового використання.
Рей Тол

Хіба ви не повинні кілька секунд до 1000 правильно setTime()?
Влад Цепелєв

4

Мені подобається простота відповіді gilly3 , але користувачі, ймовірно, будуть здивовані, що за місяць до 31 березня це 3 березня. Я вирішив реалізувати версію, яка дотримується кінця місяця, тому за місяць до 28, 29, 30 березня, і 31 рік буде 28 лютого, коли це не високосний рік.

function addMonths(date, months) {
  var result = new Date(date),
      expectedMonth = ((date.getMonth() + months) % 12 + 12) % 12;
  result.setMonth(result.getMonth() + months);
  if (result.getMonth() !== expectedMonth) {
    result.setDate(0);
  }
  return result;
}

var dt2004_05_31 = new Date("2004-05-31 0:00"),
    dt2001_05_31 = new Date("2001-05-31 0:00"),
    dt2001_03_31 = new Date("2001-03-31 0:00"),
    dt2001_02_28 = new Date("2001-02-28 0:00"),
    result = addMonths(dt2001_05_31, -2);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2001_05_31, -3);
console.assert(dt2001_02_28.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2001_05_31, 36);
console.assert(dt2004_05_31.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2004_05_31, -38);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());

console.log('Done.');


2

Вже є елегантна відповідь, але я вважаю, що її важко читати, тому я зробив власну функцію. Для своїх цілей мені не потрібен був негативний результат, але його не важко було б змінити.

    var subtractMonths = function (date1,date2) {
        if (date1-date2 <=0) {
            return 0;
        }
        var monthCount = 0;
        while (date1 > date2){
            monthCount++;
            date1.setMonth(date1.getMonth() -1);
        }
        return monthCount;
    }


1

Це найменший і найпростіший код.

   var minDate = new Date(); 
   minDate.setMonth(minDate.getMonth() - 3);

Оголосити змінну, яка має поточну дату. то лише за допомогою вбудованої функції setMonth ми можемо отримати 3 місячну дату повернення.


-1

У моєму випадку мені потрібно було підвести 1 місяць до поточної дати. Важливою частиною був номер місяця, тому не байдуже, в який день поточного місяця ви перебуваєте, мені потрібен був останній місяць. Це мій код:

var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)

dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month

//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)

Суб'єктний 1 місяць до фактичної дати не є точним, тому на першому місці я встановлюю перший день місяця (перший день будь-якого місяця завжди є першим днем), а на другому місці - підсумковий 1 день, який завжди надсилає вас до останнього місяця. Сподіваюся, що допоможе вам чувак.

var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)

dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month

//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)


-1

   

 var date=document.getElementById("date");
    var d = new Date();
   document.write(d + "<br/>");
    d.setMonth(d.getMonth() - 6);
    document.write(d);

 if(d<date)
  document.write("lesser then 6 months");
else
  document.write("greater then 6 months");


-1

Передайте об'єкт JS Date та ціле число, скільки місяців ви хочете додати / відняти. monthsToAddможе бути позитивним чи негативним. Повертає об'єкт дати JS.

Якщо ваш originalDateObjectдень 31 березня, а ви пройдете -1 як monthsToAdd, то дата виходу буде 28 лютого.

Якщо ви пройдете велику кількість місяців, скажімо, 36, вона також буде справляти корекцію року належним чином.

const addMonthsToDate = (originalDateObject, monthsToAdd) => {
  const originalDay = originalDateObject.getUTCDate();
  const originalMonth = originalDateObject.getUTCMonth();
  const originalYear = originalDateObject.getUTCFullYear();

  const monthDayCountMap = {
    "0": 31,
    "1": 28,
    "2": 31,
    "3": 30,
    "4": 31,
    "5": 30,
    "6": 31,
    "7": 31,
    "8": 30,
    "9": 31,
    "10": 30,
    "11": 31
  };

  let newMonth;
  if (newMonth > -1) {
    newMonth = (((originalMonth + monthsToAdd) % 12)).toString();
  } else {
    const delta = (monthsToAdd * -1) % 12;
    newMonth = originalMonth - delta < 0 ? (12+originalMonth) - delta : originalMonth - delta;
  }

  let newDay;

  if (originalDay > monthDayCountMap[newMonth]) {
    newDay = monthDayCountMap[newMonth].toString();
  } else {
    newDay = originalDay.toString();
  }

  newMonth = (+newMonth + 1).toString();

  if (newMonth.length === 1) {
    newMonth = '0' + newMonth;
  }

  if (newDay.length === 1) {
    newDay = '0' + newDay;
  }

  if (monthsToAdd <= 0) {
    monthsToAdd -= 11;
  }

  let newYear = (~~((originalMonth + monthsToAdd) / 12)) + originalYear;

  let newTime = originalDateObject.toISOString().slice(10, 24);

  const newDateISOString = `${newYear}-${newMonth}-${newDay}${newTime}`;

  return new Date(newDateISOString);
};

-5
Following code give me Just Previous Month From Current Month even the date is 31/30 of current date and last month is 30/29/28 days:

   <!DOCTYPE html>
<html>
<body>

<p>Click the button to display the date after changing the month.</p>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {

var d = new Date("March 29, 2017"); // Please Try the result also for "March 31, 2017" Or "March 30, 2017"
var OneMonthBefore =new Date(d);

OneMonthBefore.setMonth(d.getMonth(),0);
if(OneMonthBefore.getDate() < d.getDate()  )
{
d.setMonth(d.getMonth(),0);
}else
{
d.setMonth(d.getMonth()-1);

}

    document.getElementById("demo").innerHTML = d;
}
</script>

</body>
</html>

Чим ця відповідь відрізняється від 7 інших, досить старих відповідей, які вже є?
Стівен Рауч

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.