Рассчитать последний день месяца в JavaScript

Если вы предоставляете 0 как dayValue в Date.setFullYear вы получите последний день предыдущего месяца:

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

Ссылка на это поведение на mozilla. Является ли это надежной кросс-браузерной функцией или я должен смотреть на альтернативные методы?

Ответ 1

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 в качестве последнего дня предыдущего месяца, это не значит, что они будут продолжать это делать или что браузеры, не внесенные в список, будут делать это, но это придает уверенность в том, что это должен работать одинаково в каждом браузере.

Ответ 2

Я бы использовал промежуточную дату в первый день следующего месяца и вернул дату с предыдущего дня:

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

Ответ 3

Я считаю, что это лучшее решение для меня. Пусть объект Date вычислит его для вас.

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

Установка дневного параметра на 0 означает на один день меньше, чем первый день месяца, который является последним днем ​​предыдущего месяца.

Ответ 4

С точки зрения компьютера, new Date() и regular expression работают медленно! Если вам нужен супер-быстрый (и супер-загадочный) однострочный текст, попробуйте этот вариант (при условии, что m в формате Jan=1). Я продолжаю пробовать разные изменения кода, чтобы добиться максимальной производительности.

Моя текущая самая быстрая версия:

После рассмотрения этого связанного вопроса проверки високосного года с использованием побитовых операторов (удивительная скорость) и выяснения, что представляет собой магическое число 25 и 15, я пришел к этому оптимизированному гибриду ответов:

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 сброшены.

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, XOR биты с оригинальным ^ m и посмотреть, будет ли результат 1 или 0 в битовой позиции 0, используя & 1. Примечание: оказывается, что + немного быстрее, чем XOR (^) и (m >> 3) + m дает тот же результат в бите 0.

Результаты JSPerf: http://jsperf.com/days-in-month-perf-test/6

Ответ 6

Небольшая модификация решения, предоставляемая lebreeze:

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

Ответ 7

Я недавно должен был сделать нечто подобное, вот что я придумал:

/**
* 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 довольно 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() если хотите быть более точным.

Ответ 8

попробуйте этот.

lastDateofTheMonth = new Date(year, month, 0)

Пример:

new Date(2012, 8, 0)

выход:

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

Ответ 9

Это работает для меня. Будет предоставлять последний день данного года и месяца:

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

Ответ 10

Это хорошо работает:

Date.prototype.setToLastDateInMonth = function () {

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

    return this;
}

Ответ 11

Я думаю, что лучшее решение вроде этого:

var date = new Date();
var lastDay = new Date(date.getFullYear(), date.getMonth() + 1);
lastDay.setDate(1);
lastDay.setHours(-1);
lastDay.setHours(23);
lastDay.setMinutes(59);
lastDay.setSeconds(59);

В выбранную дату вы можете легко установить дату создания

var date = new Date('2017-07-04'); //Y-m-d format. 

Ответ 12

Это даст вам текущий месяц первый и последний день.

Если вам нужно изменить "год", удалите d.getFullYear() и установите год.

Если вам нужно изменить "месяц", удалите d.getMonth() и установите год.

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

Ответ 13

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

Ответ 14

установите месяц, который вам нужен, а затем установите день на ноль, так что месяц начинается с 1 - 31 в функции даты, а затем получает последний день ^^

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

Ответ 15

Я знаю это только вопрос семантики, но в итоге я использовал его в этой форме.

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

Так как функции разрешены из внутреннего аргумента, то они работают одинаково.

Затем вы можете просто заменить год и месяц/год необходимой информацией, будь то с текущей даты. Или конкретный месяц/год.

Ответ 16

Ниже функция возвращает последний день месяца:

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

Точно так же мы можем получить первый день месяца:

function getFstDayOfMonFnc(date)
{
    return new Date(date.getFullYear(), date.getMonth(), 1).getDate()
}

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

Ответ 17

Попробуй это:

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

Ответ 18

Вот ответ, который сохраняет время по Гринвичу и время начальной даты

var date = new Date();

var first_date = new Date(date); //Make a copy of the date we want the first and last days from
first_date.setUTCDate(1); //Set the day as the first of the month

var last_date = new Date(first_date); //Make a copy of the calculated first day
last_date.setUTCMonth(last_date.getUTCMonth()+1); //Add a month
last_date.setUTCDate(0); //Set the date to 0, this goes to the last day of the previous month

console.log(first_date.toJSON().substring(0, 10), last_date.toJSON().substring(0, 10)); //Log the dates with the format yyyy-mm-dd

Ответ 19

Нет, не все браузеры будут использовать 0 в качестве последнего дня. IE и Firefox будут, но Opera не будет.

Обратитесь к следующему источнику для получения дополнительной информации:

Последний день месяца