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

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

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

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

15 ответов


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


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

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

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

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

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


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

мой быстрый версия:

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

единственная реальная конкуренция за скорость - от @GitaarLab, поэтому я создал jsperf для тестирования:http://jsperf.com/days-in-month-head-to-head/5


он работает на основе моего ответа здесь: JavaScript, чтобы найти прыжок год ответ здесь проверка високосного года с помощью побитовых операторов (удивительная скорость) а также следующая двоичная логика.

быстрый урок в двоичных месяцах:

если вы интерпретируете индекс желаемых месяцев (Jan = 1) в двоичном вы заметите, что месяцы с 31 днями либо имеют бит 3 clear и бит 0 set, либо бит 3 set и бит 0 clear.

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


мой коллега наткнулся на следующее, которое может быть более простым решением

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

украдено из http://snippets.dzone.com/posts/show/2099


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

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

это работает для меня. Обеспечит последний день данного года и месяца:

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

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

lastDateofTheMonth = new Date(year, month, 0)

пример:

new Date(2012, 8, 0)

выход:

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

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

Date.prototype.setToLastDateInMonth = function () {

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

    return this;
}

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

/**
* 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 spec:

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

затем я устанавливаю час / минуты / секунды до конца дня, так что если вы используете какой-то API, который ожидает диапазон дат, вы сможете захватить весь этот последний день. Эта часть может выйти за рамки того, что просит оригинальный пост, но это может помочь кому-то еще ищу подобное решение.

Edit: вы также можете пройти лишнюю милю и установить миллисекунды с setMilliseconds() если вы хотите быть очень точным.


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

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

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

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

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

поскольку функции разрешаются из внутреннего аргумента, наружу, он работает одинаково.

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


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

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

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

Если вам нужно изменить "год", удалите 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);