ฉันจะคำนวณวันที่ใน JavaScript สามเดือนก่อนวันนี้ได้อย่างไร


147

ฉันกำลังพยายามสร้างวันที่ซึ่งเป็น 3 เดือนก่อนวันที่ปัจจุบัน ฉันได้รับเดือนปัจจุบันตามรหัสด้านล่าง

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

พวกคุณช่วยบอกตรรกะให้ฉันในการคำนวณและจัดรูปแบบวันที่ (วัตถุDateประเภทข้อมูล) โดยพิจารณาว่าเมื่อเดือนคือมกราคม (1) 3 เดือนก่อนวันที่จะเป็น OCtober (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 = new Date (); var currentMonth = currentDate.getMonth () -12; var pastDate = new Date (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 และ Node) มีการสนับสนุนที่ดีสำหรับวันที่เกิดเหตุ

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

ดี! ไม่แน่ใจว่าใช้ได้กับทุกสถานการณ์หรือไม่ แต่ดูเหมือนว่าจะทำงานได้ดีพอ
Devin Fields

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 Absolute

1
ในกรณีนี้คุณจะได้รับ 3 มีนาคม (สำหรับปี 2011) เพราะนั่นคือสิ่งที่ 31 กุมภาพันธ์อยู่ในโหมดผ่อนปรน แต่ลบ2 เดือนและคุณจะได้รับ 31 มกราคมภายใต้รุ่น 28 วันต่อเดือนคุณจะไม่ อ่อนแออย่างที่Dateชั้นเรียนและมากที่สุดเท่าที่ต้องการ Date.js อย่างน้อยก็เป็นนางแบบปฏิทิน proleptic proleptic ที่ดีพอสำหรับการใช้งานทั่วไป
Ray Toal

คุณไม่ควรหลายวินาทีถึง 1,000 ให้ถูกต้องsetTime()หรือไม่
Vlad Tsepelev

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

ในกรณีของฉันฉันต้อง substract 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

ผ่านวัตถุ 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 ข้อที่ค่อนข้างเก่าแล้วมีอยู่แล้วอย่างไร
Stephen Rauch

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.