Собственно, сам сниппет
Не так давно столкнулся с задачей, которая позволила бы получить количество дней в указанном месяце в JavaScript. Штатной функции для этого в языке к сожалению нет.
На эту тему был нагуглен один изящный механизм, использующий одну известную особенность многих языков программирования. Если установить несуществующую дату для какого-либо месяца (например 31 апреля), то в результате нашем объекте будет сохранено соответствующее число следующего месяца (в данном случае — 1 мая).
Таким образом, для того, чтобы получить количество дней в указанном месяце, необходимо отнять результат вышеописанной операции из числа 32. То есть, если задать в качестве даты 32 апреля, в результате мы получим 2 мая. Проверим: 32-2=30 — такое количество дней будет в апреле.
var days_in_april = 32 - new Date(2013, 3, 32).getDate();
Способ применения
Используя прекрассную возможность прототипирования в JavaScript можно расширить встроенный объект языка Date собственным методом:
Date.prototype.daysInMonth = function() {
return 32 - new Date(this.getFullYear(), this.getMonth(), 32).getDate();
};
Таким образом, чтобы получить количество дней в текущем месяце, достаточно будет обратиться непосредственно к Date:
alert(new Date().daysInMonth());
Однако, как выяснилось со временем на практике — этот способ всё ещё не идеален. По крайней мере не для Safari.
Особенности Safari
Иногда результаты работы этого снипета не совпадали с ожидаемыми, и в Safari вместо привычных 30 и 31 можно было получить единицу. Исследование проблемы показали, что оказывается в Safari не в 100% случаев срабатывает описанная особенность языка при работе с датами. Лучше всего это проиллюстрирует следующий пример:
<script>
var date = new Date(1982, 9, 32);
document.write(date);
</script>
И вот что мы видим в Chrome 26 и Safari 6 соответственно:
Идеальная практика
Чтобы выкрутиться и избежать нагромождения ненужных проверок специально для Safari, достаточно изменить опорное число 32 на 33. Данный способ работает в Safari пока также хорошо, как и в остальных браузерах:
Date.prototype.daysInMonth = function() {
return 33 - new Date(this.getFullYear(), this.getMonth(), 33).getDate();
};
Автор: uoziod