关于日期:使用JavaScript计算月中的最后一天

Calculate last day of month in JavaScript

如果在Date.setFullYear中提供0作为dayValue,则会获得上个月的最后一天:

1
d = new Date(); d.setFullYear(2008, 11, 0); //  Sun Nov 30 2008

在mozilla中提到了这种行为。 这是一个可靠的跨浏览器功能还是我应该考虑其他方法?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
var month = 0; // January
var d = new Date(2008, month + 1, 0);
alert(d); // last day in January

IE 6: Thu Jan 31 00:00:00 CST 2008
IE 7: Thu Jan 31 00:00:00 CST 2008
IE 8: Beta 2: Thu Jan 31 00:00:00 CST 2008
Opera 8.54: Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.27: Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.60: Thu Jan 31 2008 00:00:00 GMT-0600
Firefox 2.0.0.17: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Firefox 3.0.3: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Google Chrome 0.2.149.30: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Safari for Windows 3.1.2: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)

输出差异是由于toString()实现的差异,而不是因为日期不同。

当然,仅仅因为上面提到的浏览器使用0作为上个月的最后一天并不意味着他们将继续这样做,或者未列出的浏览器会这样做,但它使人们相信它应该工作的可信度每个浏览器都一样。


我会在下个月的第一天使用中间日期,并返回前一天的日期:

1
2
int_d = new Date(2008, 11+1,1);
d = new Date(int_d - 1);


我觉得这对我来说是最好的解决方案。让Date对象为您计算它。

1
2
var today = new Date();
var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0);

将day参数设置为0表示比上个月的最后一天月份的第一天少一天。


在计算机方面,new Date()regular expression解决方案很慢!如果你想要一个超快(并且超级神秘)的单行,请尝试这个(假设mJan=1格式)。我一直在尝试不同的代码更改以获得最佳性能。

我目前最快的版本:

看完这个相关的问题闰年检查使用按位运算符(惊人的速度)并发现25& 15个幻数代表,我已经想出了这个优化的答案混合:

1
2
3
function getDaysInMonth(m, y) {
    return m===2 ? y & 3 || !(y%25) && y & 15 ? 28 : 29 : 30 + (m+(m>>3)&1);
}

鉴于位移,这显然假设您的m& y参数都是整数,因为将数字作为字符串传递会产生奇怪的结果。

JSFiddle:http://jsfiddle.net/TrueBlueAussie/H89X3/22/

JSPerf结果:http://jsperf.com/days-in-month-head-to-head/5

出于某种原因,(m+(m>>3)&1)在几乎所有浏览器上都比(5546>>m&1)更有效。

唯一真正的速度竞争来自@GitaarLab,所以我创建了一个头对头的JSPerf供我们测试:http://jsperf.com/days-in-month-head-to-head/5

它基于我的闰年答案在这里工作:javascript找到闰年这个答案在这里闰年检查使用按位运算符(惊人的速度)以及以下二进制逻辑。

二进制月的快速教训:

如果您以二进制形式解释所需月份(Jan = 1)的索引,您会注意到31天的月份有3位清除和位0设置,或位3设置和位0清除。

1
2
3
4
5
6
7
8
9
10
11
12
Jan = 1  = 0001 : 31 days
Feb = 2  = 0010
Mar = 3  = 0011 : 31 days
Apr = 4  = 0100
May = 5  = 0101 : 31 days
Jun = 6  = 0110
Jul = 7  = 0111 : 31 days
Aug = 8  = 1000 : 31 days
Sep = 9  = 1001
Oct = 10 = 1010 : 31 days
Nov = 11 = 1011
Dec = 12 = 1100 : 31 days

这意味着您可以使用>> 3将值移位3位,使用原始^ m对位进行异或,并使用& 1查看位置0中的结果是1还是0。注意:结果+略快于XOR(^),(m >> 3) + m在位0中给出相同的结果。

JSPerf结果:http://jsperf.com/days-in-month-perf-test/6


我的同事偶然发现了以下问题,这可能是一个更容易的解决方案

1
2
3
4
function daysInMonth(iMonth, iYear)
{
    return 32 - new Date(iYear, iMonth, 32).getDate();
}

从http://snippets.dzone.com/posts/show/2099偷来的


对lebreeze提供的解决方案略有修改:

1
2
3
4
function daysInMonth(iMonth, iYear)
{
    return new Date(iYear, iMonth, 0).getDate();
}


我最近不得不做类似的事情,这就是我想出的:

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
/**
* Returns a date set to the begining of the month
*
* @param {Date} myDate
* @returns {Date}
*/

function beginningOfMonth(myDate){    
  let date = new Date(myDate);
  date.setDate(1)
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);  
  return date;    
}

/**
 * Returns a date set to the end of the month
 *
 * @param {Date} myDate
 * @returns {Date}
 */

function endOfMonth(myDate){
  let date = new Date(myDate);
  date.setMonth(date.getMonth() +1)
  date.setDate(0);
  date.setHours(23);
  date.setMinutes(59);
  date.setSeconds(59);
  return date;
}

在日期中传递它,它将返回设置为月初或月末的日期。

begninngOfMonth函数是相当不言自明的,但endOfMonth函数中的内容是我将月份递增到下个月,然后使用setDate(0)将日期回滚到最后一天上个月是setDate规范的一部分:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate
https://www.w3schools.com/jsref/jsref_setdate.asp

然后我将小时/分钟/秒设置为当天结束,这样如果您使用某种期望日期范围的API,您将能够捕获整个最后一天。这部分可能超出原始帖子所要求的范围,但它可以帮助其他人寻找类似的解决方案。

编辑:如果您想要更精确,您还可以使用setMilliseconds()进行额外的步骤并设置毫秒数。


试试这个。

1
lastDateofTheMonth = new Date(year, month, 0)

例:

1
new Date(2012, 8, 0)

输出:

1
Date {Fri Aug 31 2012 00:00:00 GMT+0900 (Tokyo Standard Time)}


这适合我。
将提供给定年份和月份的最后一天:

1
2
3
var d = new Date(2012,02,0);
var n = d.getDate();
alert(n);


这个很好用:

1
2
3
4
5
6
7
8
Date.prototype.setToLastDateInMonth = function () {

    this.setDate(1);
    this.setMonth(this.getMonth() + 1);
    this.setDate(this.getDate() - 1);

    return this;
}

这将为您提供当前的第一天和最后一天。

如果您需要更改'年',请删除d.getFullYear()并设置您的年份。

如果您需要更改'月',请删除d.getMonth()并设置您的年份。

1
2
3
4
5
6
7
8
var d = new Date();
var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var fistDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth(), 1).getDay())];
    var LastDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth() + 1, 0).getDay())];
console.log("First Day :" + fistDayOfMonth);
console.log("Last Day:" + LastDayOfMonth);
alert("First Day :" + fistDayOfMonth);
alert("Last Day:" + LastDayOfMonth);


试试这个:

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
function _getEndOfMonth(time_stamp) {
    let time = new Date(time_stamp * 1000);
    let month = time.getMonth() + 1;
    let year = time.getFullYear();
    let day = time.getDate();
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            day = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            day = 30;
            break;
        case 2:
            if (_leapyear(year))
                day = 29;
            else
                day = 28;
            break
    }
    let m = moment(`${year}-${month}-${day}`, 'YYYY-MM-DD')
    return m.unix() + constants.DAY - 1;
}

function _leapyear(year) {
    return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
}

设置月份你需要约会,然后将日期设置为零,所以月份开始于1 - 31日期函数然后得到最后一天^^

1
2
var last = new Date(new Date(new Date().setMonth(7)).setDate(0)).getDate();
console.log(last);

我知道这只是一个语义问题,但我最终以这种形式使用它。

1
2
var lastDay = new Date(new Date(2008, 11+1,1) - 1).getDate();
console.log(lastDay);

由于函数是从内部参数向外解析的,因此它的工作原理相同。

然后,您可以使用所需的详细信息替换年份和月份/年份,无论是从当前日期开始。或者特定的月/年。


下面的函数给出了该月的最后一天:

1
2
3
4
5
6
7
8
9
function getLstDayOfMonFnc(date)
{
    return new Date(date.getFullYear(), date.getMonth(), 0).getDate()
}

console.log(getLstDayOfMonFnc(new Date(2016, 2, 15)))   // Output : 29
console.log(getLstDayOfMonFnc(new Date(2017, 2, 15)))   // Output : 28
console.log(getLstDayOfMonFnc(new Date(2017, 11, 15)))  // Output : 30
console.log(getLstDayOfMonFnc(new Date(2017, 12, 15)))  // Output : 31

同样,我们可以获得该月的第一天:

1
2
3
4
5
6
function getFstDayOfMonFnc(date)
{
    return new Date(date.getFullYear(), date.getMonth(), 1).getDate()
}

console.log(getFstDayOfMonFnc(new Date(2016, 2, 15)))   // Output : 1

1
2
3
function getLastDay(y, m) {
   return 30 + (m <= 7 ? ((m % 2) ? 1 : 0) : (!(m % 2) ? 1 : 0)) - (m == 2) - (m == 2 && y % 4 != 0 || !(y % 100 == 0 && y % 400 == 0));
}