Làm cách nào để tính ngày trong JavaScript ba tháng trước ngày hôm nay?


147

Tôi đang cố gắng hình thành một ngày là 3 tháng trước ngày hiện tại. Tôi nhận được tháng hiện tại bằng mã dưới đây

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

Các bạn có thể cung cấp cho tôi logic để tính toán và hình thành một ngày (một đối tượng của Datekiểu dữ liệu) xem xét rằng khi tháng là tháng 1 (1), 3 tháng trước ngày sẽ là tháng 10 (10)?

Câu trả lời:


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

Điều này làm việc cho tháng một. Chạy đoạn trích này:

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


Có một số hãy cẩn thận ...

Một tháng là một điều tò mò. Làm thế nào để bạn xác định 1 tháng? 30 ngày? Hầu hết mọi người sẽ nói rằng một tháng trước có nghĩa là cùng một ngày trong tháng trên trích dẫn tháng trước cần thiết . Nhưng hơn một nửa thời gian, đó là 31 ngày trước, không phải 30. Và nếu hôm nay là ngày 31 của tháng (và đó không phải là tháng 8 hay Decemeber), ngày đó của tháng không tồn tại trong tháng trước.

Thật thú vị, Google đồng ý với JavaScript nếu bạn hỏi nó ngày nào là một tháng trước ngày khác :

Kết quả tìm kiếm của Google trong 'một tháng trước ngày 31 tháng 3' hiển thị 'ngày 3 tháng 3'

Nó cũng nói rằng một tháng dài 30.4167 ngày : Kết quả tìm kiếm của Google cho 'một tháng trong ngày' hiển thị '30 .4167 '

Vậy, có phải một tháng trước ngày 31 tháng 3 cùng ngày với một tháng trước ngày 28 tháng 3, sớm hơn 3 ngày? Tất cả điều này phụ thuộc vào ý của bạn là "một tháng trước". Đi nói chuyện với chủ sở hữu sản phẩm của bạn.

Nếu bạn muốn làm như khoảnh khắc, và sửa những lỗi cuối cùng của tháng bằng cách chuyển sang ngày cuối cùng của tháng, bạn có thể làm một cái gì đó như thế này:

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());

Nếu yêu cầu của bạn phức tạp hơn thế, hãy sử dụng một số phép toán và viết một số mã. Bạn là một nhà phát triển! Bạn không cần phải cài đặt một thư viện! Bạn không phải sao chép và dán từ stackoverflow! Bạn có thể tự phát triển mã để làm chính xác những gì bạn cần!


var currentDate = ngày mới (); var currentMonth = currentDate.getMonth () -12; var pastDate = Ngày mới (2011, currentMonth, 01); cảnh báo (pastDate); cái này hoạt động, được kiểm tra với 12 tháng
KeenUser

Đây là một câu trả lời bệnh hoạn ... Tôi sẽ lấy 2012,0,15 từ đâu? Chuyển đổi một tháng hiện tại -1?
Alex G

3
@AlexG - Nếu bạn chưa quen với phân tích cú pháp ngày JavaScript, thì tôi có thể thấy ví dụ nhanh của tôi sẽ khó hiểu như thế nào. JavaScript biểu thị các tháng là số không dựa trên, trong đó tháng 1 bằng không. Để tránh nhầm lẫn như vậy, đặc biệt là vì điều đó không liên quan gì đến câu hỏi hoặc câu trả lời của tôi, tôi đã cập nhật bản demo của mình để lấy ngày từ một chuỗi, nên trực quan hơn.
gilly3

7
Tôi biết điều này đã cũ nhưng nếu ngày là 31 tháng 3 và bạn trừ đi một tháng bằng phương pháp này thì kết quả là ngày 2 tháng 3. jsfiddle.net/atamata/rvumf7dg
atamata

@atamata - Vâng, đó là lạ, nhưng có thể dự đoán và dự kiến. 31 ngày sau khi kết thúc tháng trước cho tháng 3 là ngày 31 tháng 3, nhưng vào tháng 2 là ngày 2 tháng 3. Nếu bạn muốn tính từ cuối tháng, bạn sẽ phải viết một số mã tùy chỉnh cho điều đó.
gilly3

28

Tôi khuyên bạn nên sử dụng một thư viện có tên là Moment.js.

Nó được thử nghiệm tốt, hoạt động trên trình duyệt chéo và ở phía máy chủ (tôi đang sử dụng cả trong các dự án Angular và Node). Nó có hỗ trợ tuyệt vời cho ngày địa phương.

http://momentjs.com/

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

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

.format()trả về chuỗi đại diện của ngày được định dạng theo định dạng ISO 8601 . Bạn cũng có thể sử dụng nó với định dạng ngày tùy chỉnh như thế này:.format('dddd, MMMM Do YYYY, h:mm:ss a')


10

Một "một lớp lót" (trên nhiều dòng để dễ đọc)) được đặt trực tiếp vào một biến:

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

đẹp! Không chắc chắn nếu nó được áp dụng cho mọi kịch bản, nhưng dường như hoạt động đủ tốt.
Trường Devin

8

Để làm cho mọi thứ thực sự đơn giản, bạn có thể sử dụng DateJS, thư viện ngày cho JavaScript:

http://www.datejs.com/

Mã ví dụ cho bạn:

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

8

Điều này sẽ xử lý cộng / trừ, chỉ cần đặt một giá trị âm vào để trừ và một giá trị dương để thêm. Điều này cũng giải quyết vấn đề chéo tháng.

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

Nếu setMonthphương pháp được cung cấp bởi gilly3 không phải là thứ bạn đang tìm kiếm, hãy xem xét:

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".

Có thể được sử dụng cho bất kỳ số lượng thời gian, chỉ cần đặt đúng bội số.


Tôi sẽ đi với câu trả lời của gilly3. Bạn giả định một số giây cố định mỗi tháng. Số học ngày khoan hồng của JavaScript sẽ giữ đúng ngày. Ba tháng trước ngày 28 tháng 9 sẽ là ngày 28 tháng 7.
Ray Toal

1
Tôi tự hỏi JavaScript sẽ tính toán ngày 31 tháng 3 trừ đi 1 tháng.
Niet the Dark Tuyệt đối

1
Trong trường hợp đó, bạn nhận được ngày 3 tháng 3 (năm 2011) vì đó là ngày 31 tháng 2 ở chế độ khoan hồng. Nhưng trừ đi 2 tháng và bạn sẽ nhận được ngày 31 tháng 1. Theo mô hình 28 ngày mỗi tháng, bạn sẽ không. DateLớp học cũng yếu như vậy , và càng nhiều ưu tiên của Date.js, thì ít nhất nó cũng mô hình một lịch proleptic nhẹ nhàng, đủ tốt để sử dụng thông thường.
Ray Toal

Bạn không nên nhiều giây đến 1000 để chính xác setTime()?
Vlad Tsepelev

4

Tôi thích sự đơn giản trong câu trả lời của gilly3 , nhưng người dùng có thể sẽ ngạc nhiên khi một tháng trước ngày 31 tháng 3 là ngày 3 tháng 3. Tôi đã chọn thực hiện một phiên bản dính vào cuối tháng, vì vậy một tháng trước ngày 28, 29, 30 tháng 3, và 31 tất cả sẽ là ngày 28 tháng 2 khi đó không phải là một năm nhuận.

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

Đã có một câu trả lời tao nhã nhưng tôi thấy rằng nó khó đọc nên tôi đã thực hiện chức năng của riêng mình. Đối với mục đích của tôi, tôi không cần một kết quả tiêu cực nhưng sẽ không khó để sửa đổi.

    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;
    }

2

var d = new Date("2013/01/01");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() + 18);
console.log(d.toLocaleDateString());


1

Đây là mã nhỏ nhất và dễ nhất.

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

Khai báo biến có ngày hiện tại. sau đó chỉ bằng cách sử dụng hàm setMonth inbuilt, chúng ta có thể lấy lại ngày 3 tháng.


-1

Trong trường hợp của tôi, tôi cần phải trừ đi 1 tháng cho đến ngày hiện tại. Phần quan trọng là số tháng, vì vậy nó không quan tâm đến ngày nào của tháng hiện tại, tôi cần tháng trước. Đây là mã của tôi:

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)

Trừ 1 tháng đến ngày thực tế không chính xác, đó là lý do tại sao ở nơi đầu tiên tôi đặt ngày đầu tiên của tháng (ngày đầu tiên của bất kỳ tháng nào luôn là ngày đầu tiên) và ở vị trí thứ hai tôi trừ đi 1 ngày, luôn gửi bạn đến tháng trước. Hy vọng sẽ giúp bạn anh chàng.

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

Vượt qua một đối tượng Ngày JS và một số nguyên bao nhiêu tháng bạn muốn thêm / trừ. monthsToAddcó thể tích cực hoặc tiêu cực. Trả về một đối tượng ngày JS.

Nếu bạn originalDateObjectlà ngày 31 tháng 3 và bạn vượt qua -1 nhưmonthsToAdd , thì ngày đầu ra của bạn sẽ là ngày 28 tháng 2.

Nếu bạn vượt qua một số lượng lớn các tháng, giả sử 36, nó cũng sẽ xử lý việc điều chỉnh năm đúng cách.

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>

Làm thế nào để câu trả lời này khác với 7 câu trả lời khác, khá cũ, đã có mặt?
Stephen Rauch

-5

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.