使用 Date 对象查找一个月中的所有天数?

IT技术 javascript jquery date datepicker
2021-03-15 20:54:48

有没有办法拥有一个月或一年的所有日子?我正在寻找这个以禁用日期选择器中的某些特定日期,我会在后台有一个页面来选择这些日期以禁用。

所以我需要显示一个月中的所有天数,并在每一天下方添加一个“激活或停用”按钮。有没有办法用 Date 对象找到这些日子?我找到了这个链接,例如:显示一个月的所有天数,但我不太明白,而且它是 Java,我试图在 javascript 中找到解决方案。

谢谢您的帮助

6个回答

要获取一个月中所有天的列表,您可以从一个月Date的第一天开始,增加这一天直到月份发生变化。

/**
 * @param {int} The month number, 0 based
 * @param {int} The year, not zero based, required to account for leap years
 * @return {Date[]} List with date objects for each day of the month
 */
function getDaysInMonth(month, year) {
  var date = new Date(year, month, 1);
  var days = [];
  while (date.getMonth() === month) {
    days.push(new Date(date));
    date.setDate(date.getDate() + 1);
  }
  return days;
}

UTC版本

为了回应一些评论,我创建了一个使用 UTC 方法的版本,以防您想调用 UTC 方法而不是返回本地化时区的标准方法。

我怀疑这是评论说这不起作用的罪魁祸首。您通常希望确保getUTCMonth/Day/Hours在使用 实例化方法时调用方法Date.UTC,反之亦然,除非您尝试转换时区并显示差异。

function getDaysInMonthUTC(month, year) {
  var date = new Date(Date.UTC(year, month, 1));
  var days = [];
  while (date.getUTCMonth() === month) {
    days.push(new Date(date));
    date.setUTCDate(date.getUTCDate() + 1);
  }
  return days;
}

编辑此答案

如果您认为此脚本有问题,请随时:

  • 首先查看下面的现有单元测试
  • 编写一个测试用例来证明它已损坏。
  • 修复代码,确保现有测试通过。

单元测试

/**
 * @param {int} The month number, 0 based
 * @param {int} The year, not zero based, required to account for leap years
 * @return {Date[]} List with date objects for each day of the month
 */
function getDaysInMonthUTC(month, year) {
  var date = new Date(Date.UTC(year, month, 1));
  var days = [];
  while (date.getUTCMonth() === month) {
    days.push(new Date(date));
    date.setUTCDate(date.getUTCDate() + 1);
  }
  return days;
}

function getDaysInMonth(month, year) {
  var date = new Date(year, month, 1);
  var days = [];
  while (date.getMonth() === month) {
    days.push(new Date(date));
    date.setDate(date.getDate() + 1);
  }
  return days;
}

const days2020 = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const days2021 = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

describe("getDaysInMonthUTC", function() {
  it("gets day counts for leap years", function() {
    const actual = days2020.map(
      (day, index) => getDaysInMonthUTC(index, 2020).length
    );
    expect(actual).toEqual(days2020);
  });

  it("gets day counts for non-leap years", function() {
    const actual = days2021.map(
      (day, index) => getDaysInMonthUTC(index, 2021).length
    );
    expect(actual).toEqual(days2021);
  });
});


describe("getDaysInMonth", function() {
  it("gets day counts for leap years", function() {
    const actual = days2020.map(
      (day, index) => getDaysInMonth(index, 2020).length
    );
    expect(actual).toEqual(days2020);
  });

  it("gets day counts for non-leap years", function() {
    const actual = days2021.map(
      (day, index) => getDaysInMonth(index, 2021).length
    );
    expect(actual).toEqual(days2021);
  });
});

// load jasmine htmlReporter
(function() {
  var env = jasmine.getEnv();
  env.addReporter(new jasmine.HtmlReporter());
  env.execute();
}());
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<link href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet"/>

对代码 date.setDate(date.getDate() + 1) 的小修正;应该在 date.push 数组调用之前
2021-04-26 20:54:48
@Timothy 这不起作用的测试用例是什么?
2021-05-02 20:54:48
@Timothy 是对的,脚本并不总是有效。它仅适用于某些时区。我已经编辑了答案来修复它。
2021-05-03 20:54:48
@Timothy 仅当您想排除第一天(1 月 1 日或您开始脚本的任何地方)时。
2021-05-11 20:54:48
@DiegoFaria 您的修复使问题变得更糟,您和 Timothy 都误解了一些东西:) 您忘记更新setDategetDate使用 UTC 方法。我知道使用 UTC 方法通常是最好的选择。通常,如果您保持通话的一致性UTC我写了一些测试来证明这一点。随意进入并创建新的测试用例来解释您在哪里看到问题。我相信在实例化 Date 的方式上保持一致将使其工作,因此请使用正确的getDays,具体取决于您调用的方法
2021-05-19 20:54:48

一个班轮在一个月内将所有天数作为日期对象

const getDaysInMonth = (month, year) => (new Array(31)).fill('').map((v,i)=>new Date(year,month-1,i+1)).filter(v=>v.getMonth()===month-1)

根据您的描述,我不确定标准禁用日期日期选择器是否适用于您,因此我将直接回答您的问题。

通过执行以下操作,您可以相当轻松地构造一个月的天数数组:

var numOfDays = new Date(2012, 10, 0).getDate(); //use 0 here and the actual month
var days = new Array();

//This will construct an array with all the elements represent the day of the week 
//(i.e. Oct 30th would be days[30-1] or days[29]) and the value would be the actual 
//day of the week (i.e. Tuesday which is representing by the number 2)
for(var i=0;i<=numOfDays;i++)
{
    days[i] = new Date(2012,9,i+1).getDay(); //use month-1 here            
}
//This will give you a number from 0 - 6 which represents (Sunday - Saturday)
alert(days[29]); 

使用这一系列的日子,你几乎可以用它做任何你想做的事情,并且知道一周中的哪一天。

带 ES6 的快速且简单的 One 内胆

可以获得指定月份的天数,然后使用该长度填充新数组。

const getAllDaysInMonth = (month, year) =>
  Array.from(
    {length: new Date(year, month, 0).getDate() - 1},
    (_, i) => new Date(year, month, i + 1)
  );

const example = getAllDaysInMonth(8, 2021).map(x => x.toLocaleDateString())
console.log(example)

这是一个遍历每个月的循环以确定该月的最后一天。Javascript Date 对象从零开始索引月份,如果您将日期设置为零,它会恢复到上个月的最后一天。用于确定 2 月最后一天的闰年

Date( 2012, 12, 0) 将于 2012 年 12 月 31 日返回

Date (2012,0,0) 将于 2011 年 12 月 31 日返回

最重要的是要弄清楚的是二月

Date ( 2012,3,0) 返回今年闰年以来的 2 月 29 日

var mos=['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']

for (i = 0; i < 12; i++) {
    var lastDate = new Date(2012, i+1, 0);
    $('body').append('Last day of ' + mos[i] + ' is ' + lastDate.getDate()+'<br>')
}

演示:http : //jsfiddle.net/5k8sn/1/