关于javascript:使用Date对象查找一个月中的所有日子?

Find all the days in a month with Date object?

是否可以利用一个月或一年中的所有日子?我正在寻找此功能,以便禁用日期选择器中的某些特定日期,我会在后台办公室中选择一个页面来禁用这些日期。

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

谢谢您的帮助


要获取一个月中所有天的列表,可以在一个月的第一天以Date开头,增加该天,直到该月发生变化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * @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方法而不是返回本地化时区的标准方法。

我怀疑这是说这没有用的评论的罪魁祸首。通常,如果要使用Date.UTC实例化它,通常要确保调用getUTCMonth/Day/Hours方法,反之亦然,除非尝试转换时区并显示差异。

1
2
3
4
5
6
7
8
9
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;
}

编辑此答案

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

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

单元测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
 * @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();
}());
1
2
3
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js">
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js">
<link href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet"/>


一个衬里将一个月中的所有日期都作为Date对象

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

从您的描述中我不确定标准的禁用日期datepicker是否可以与您配合使用,因此我将直接回答您的问题。

您可以通过以下操作很容易地构建一个月的数组:

1
2
3
4
5
6
7
8
9
10
11
12
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]);


使用这几天的时间,您几乎可以做任何您想做的事情,并且也知道星期几。


我已经使用jQuery datepicker实现了您请求的功能。

首先,将后台要禁用的所有日期添加到数组中

1
2
3
4
5
6
7
// format yyyy-mm-dd
var disabledDates = [
   "2012-10-01",
   "2012-10-02",
   "2012-10-30",
   "2012-09-12"
];

第二,用两个函数指定日期选择器

1
2
3
4
5
6
7
8
$("#datepicker").datepicker({

    // only enable date if dateEnabled returns [true]
    beforeShowDay: dateEnabled,

    // once a date has been selected call dateSelected
    onSelect: dateSelected
});

这是所需功能的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
function dateEnabled( d ) {

    // if date found in array disable date
    if( disabledDates.indexOf( getDate( d ) ) > -1 ) {

        return [false];

    } else {

        return [true] ;

    }
}

将日期转换为字符串,以便与数组中的日期进行比较

1
2
3
4
5
6
7
8
9
10
11
12
13
function getDate( d ) {
    var day,
        month,
        year;

    day = d.getDate( );
    month = d.getMonth( ) + 1; // add 1 as getMonth returns 0 - 11
    year = d.getFullYear( );

    if( month < 10 ) month ="0" + month;
    if( day < 10 ) day ="0" + day;
    return year +"-" + month +"-" + day;
}

选择日期后,将对其进行处理

1
2
3
function dateSelected( d ) {
   // do stuff with string representation of date                                          
}

这里是小提琴http://jsfiddle.net/KYzaR/7/

只是认为值得一提的是Array.indexOf是ECMA-262标准的最新添加,因此在IE7和IE8的情况下不受支持。以下MDN页面提供了为这些浏览器实现Array.indexOf的代码https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Array/indexOf


这里有一个循环播放,以确定每个月的最后一天。 Javascript Date对象索引从零开始的月份,如果将日期设置为零,它将还原为上个月的最后一天。方便确定2月的上一年leap年

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

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

,最重要的一个是2月,

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

1
2
3
4
5
6
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()+'')
}

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


我有解决办法。快乐编码!!
注意:0 =一月,1 =二月,依此类推。
示例w3schools

1
2
3
4
5
6
7
8
9
const getDays = (month, year) => {
    let date = new Date(`${year}-${parseInt(month)+1}-01`);
    let days = [];
    while (date.getMonth() === parseInt(month)) {
        days.push(date.getDate());
        date.setDate(date.getDate() + 1);
    }
    return days;
}


要禁用日期选择器中的日期,可以使用此处描述的答案:
https://stackoverflow.com/a/12061715/48082

要选择多个日期(如在后台应用程序中),可以使用此插件:
http://multidatespickr.sourceforge.net/