Даты в JavaScript: количество дней в месяце и некоторые особенности Safari

в 16:33, , рубрики: date, javascript, snippets, метки: , ,

Собственно, сам сниппет

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

image

Идеальная практика

Чтобы выкрутиться и избежать нагромождения ненужных проверок специально для Safari, достаточно изменить опорное число 32 на 33. Данный способ работает в Safari пока также хорошо, как и в остальных браузерах:

	Date.prototype.daysInMonth = function() {
		return 33 - new Date(this.getFullYear(), this.getMonth(), 33).getDate();
	};

Автор: uoziod

Источник


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js