Рассчитать последний день месяца в 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
Ответ 5
Мой коллега наткнулся на следующее, что может быть более легким решением
function daysInMonth(iMonth, iYear)
{
return 32 - new Date(iYear, iMonth, 32).getDate();
}
украден из http://snippets.dzone.com/posts/show/2099
Ответ 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 не будет.
Обратитесь к следующему источнику для получения дополнительной информации:
Последний день месяца