Как получить последний день месяца переданной даты js
Перейти к содержимому

Как получить последний день месяца переданной даты js

  • автор:

 

Нахождение последнего дня месяца в JavaScript

Используем изученную нами ранее автоматическую корректировку дат, чтобы легко решить нашу задачу. Ведь в JavaScript последний день месяца — это нулевой день следующего месяца.

Для примера определим количество дней в марте 2020 года. Для этого при создании объекта с датой укажем нулевой день апреля (он имеет номер 3 , так как нумерация месяцев с нуля):

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

Определите, какой день недели будет в последнем дне пятого месяца 2025 года.

Как получить последний день месяца переданной даты js

Создаёт экземпляр объекта Date , представляющего собой момент времени. Объект Дата содержит число миллисекунд прошедших с 1 января 1970 г. UTC

Интерактивный пример

Синтаксис

Примечание: объекты Date могут быть созданы только путём вызова функции Date в качестве конструктора: обычный вызов функции (то есть, без использования оператора new ) вернёт строку вместо объекта Date ; в отличие от других объектных типов JavaScript, объекты Date не имеют литерального синтаксиса.

Параметры

Примечание: если функция Date вызывается в качестве конструктора с более, чем одним аргументом, значения, большие логического диапазона (например, 13 в качестве номера месяца или 70 для значения минут) «переметнутся» на соседние значения. Например, вызов new Date(2013, 13, 1) эквивалентен вызову new Date(2014, 1, 1) , оба создадут дату 2014-02-01 (нумерация месяцев начинается с нуля). Тоже самое действует и для других значений: вызов new Date(2013, 2, 1, 0, 70) эквивалентен вызову new Date(2013, 2, 1, 1, 10) — оба вызова создадут дату 2013-03-01T01:10:00 .

Примечание: если функция Date вызывается в качестве конструктора с более чем одним аргументом, то указанные аргументы интерпретируются как локальное время. Если аргументы указывают время в UTC, используйте new Date( Date.UTC(. ) ) с теми же аргументами.

Целое значение, представляющее количество миллисекунд, прошедших с 1 января 1970 00:00:00 по UTC (эпохи Unix).

Строковое значение, представляющее дату. Строка должна быть в одном из форматов, распознаваемых методом Date.parse() (совместимые с IETF RFC 2822 временные метки [на английском, на русском], а также версия ISO8601 [на английском, на русском]).

Целое значение, представляющее год. Значения с 0 по 99 отображаются на года с 1900 по 1999. Смотрите пример ниже.

Целое значение, представляющее месяц, начинается с 0 для января и кончается 11 для декабря.

Необязательный параметр. Целое значение, представляющее день месяца.

Необязательный параметр. Целое значение, представляющее часы дня.

Необязательный параметр. Целое значение, представляющее минуты времени.

Необязательный параметр. Целое значение, представляющее секунды времени.

Необязательный параметр. Целое значение, представляющее миллисекунды времени.

Описание

  • Если никаких аргументов передано не было, конструктор создаёт объект Date для текущих даты и времени, согласно системным настройкам.
  • Если передано как минимум два аргумента, отсутствующие аргументы устанавливаются в стартовые значения — день месяца 1 и время полуночи.
  • Дата в JavaScript измеряется в миллисекундах, прошедших с полуночи 1 января 1970 года по UTC. День содержит 86 400 000 миллисекунд. Диапазон дат объекта Date варьируется от -100 000 000 до 100 000 000 дней относительно 1 января 1970 года по UTC.
  • Объект Date обеспечивает универсальное поведение на всех платформах. Значение времени может передаваться между системами для представления одинакового момента во времени и, если оно используется для создания локального объекта даты, будет отражать местный эквивалент времени.
  • Объект Date поддерживает несколько методов для работы с UTC (всемирным координированным временем), наряду с методами работы с местным временем. UTC, также известное как среднее время по Гринвичу (GMT), ссылается на время, установленное Всемирным стандартом времени. Местное время — это время на компьютере, на котором выполняется JavaScript.
  • Вызов объекта Date в качестве функции (то есть, без использования оператора new ) вернёт строку, представляющую текущие дату и время.

Свойства

Позволяет добавлять свойства к объекту Date .

Значение свойства Date.length равно 7. Это количество аргументов, обрабатываемых конструктором.

Методы

Возвращает числовое значение, соответствующее текущему времени — количество миллисекунд, прошедших с 1 января 1970 года 00:00:00 по UTC.

Разбирает строковое представление даты и возвращает количество миллисекунд с 1 января 1970 года 00:00:00 по местному времени.

Принимает те же самые параметры, что и самый длинный вариант конструктора (то есть, от 2 до 7) и возвращает количество миллисекунд, прошедших с 1 января 1970 года 00:00:00 по UTC.

Экземпляры объекта Date

Все экземпляры объекта Date наследуются от Date.prototype (en-US). Объект прототипа конструктора Date может быть изменён, чтобы затронуть все экземпляры объекта Date .

Методы

Примеры

Пример: несколько способов создания объекта Date

Следующие примеры показывают несколько способов создания дат в JavaScript:

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

Пример: двухциферный год отображается на 1900 — 1999 года

Для того, чтобы создать и получить даты между 0 и 99 годом, нужно использовать методы Date.prototype.setFullYear() и Date.prototype.getFullYear() .

Пример: вычисление затраченного времени

Следующие примеры показывают, как определить разницу во времени между двумя датами в JavaScript:

Дата и время

Встречайте новый встроенный объект: Date. Он содержит дату и время, а также предоставляет методы управления ими.

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

Создание

Для создания нового объекта Date нужно вызвать конструктор new Date() с одним из следующих аргументов:

Без аргументов – создать объект Date с текущими датой и временем:

Создать объект Date с временем, равным количеству миллисекунд (тысячная доля секунды), прошедших с 1 января 1970 года UTC+0.

Целое число, представляющее собой количество миллисекунд, прошедших с начала 1970 года, называется таймстамп (англ. timestamp).

Это – легковесное численное представление даты. Из таймстампа всегда можно получить дату с помощью new Date(timestamp) и преобразовать существующий объект Date в таймстамп, используя метод date.getTime() (см. ниже).

Датам до 1 января 1970 будут соответствовать отрицательные таймстампы, например:

Если аргумент всего один, и это строка, то из неё «прочитывается» дата. Алгоритм разбора – такой же, как в Date.parse , который мы рассмотрим позже.

Создать объект Date с заданными компонентами в местном часовом поясе. Обязательны только первые два аргумента.

  • year должен состоять из четырёх цифр. Для совместимости также принимаются 2 цифры и рассматриваются как 19xx , к примеру, 98 здесь это тоже самое, что и 1998 , но настоятельно рекомендуется всегда использовать 4 цифры.
  • month начинается с 0 (январь) по 11 (декабрь).
  • Параметр date здесь представляет собой день месяца. Если параметр не задан, то принимается значение 1 .
  • Если параметры hours/minutes/seconds/ms отсутствуют, их значением становится 0 .

Максимальная точность – 1 мс (до 1/1000 секунды):

Получение компонентов даты

Существуют методы получения года, месяца и т.д. из объекта Date :

getFullYear() Получить год (4 цифры) getMonth() Получить месяц, от 0 до 11. getDate() Получить день месяца, от 1 до 31, что несколько противоречит названию метода. getHours(), getMinutes(), getSeconds(), getMilliseconds() Получить, соответственно, часы, минуты, секунды или миллисекунды.

Многие интерпретаторы JavaScript реализуют нестандартный и устаревший метод getYear() , который порой возвращает год в виде двух цифр. Пожалуйста, обходите его стороной. Если нужно значение года, используйте getFullYear() .

Кроме того, можно получить определённый день недели:

getDay() Вернуть день недели от 0 (воскресенье) до 6 (суббота). Несмотря на то, что в ряде стран за первый день недели принят понедельник, в JavaScript начало недели приходится на воскресенье.

Все вышеперечисленные методы возвращают значения в соответствии с местным часовым поясом.

Однако существуют и их UTC-варианты, возвращающие день, месяц, год для временной зоны UTC+0: getUTCFullYear(), getUTCMonth(), getUTCDay(). Для их использования требуется после "get" подставить "UTC" .

Если ваш местный часовой пояс смещён относительно UTC, то следующий код покажет разные часы:

Помимо вышеприведённых методов, существуют два особых метода без UTC-варианта:

Для заданной даты возвращает таймстамп – количество миллисекунд, прошедших с 1 января 1970 года UTC+0.

Возвращает разницу в минутах между UTC и местным часовым поясом:

Установка компонентов даты

Следующие методы позволяют установить компоненты даты и времени:

У всех этих методов, кроме setTime() , есть UTC-вариант, например: setUTCHours() .

Как мы видим, некоторые методы могут устанавливать сразу несколько компонентов даты, например: setHours . Если какая-то компонента не указана, она не меняется.

Автоисправление даты

Автоисправление – это очень полезная особенность объектов Date . Можно устанавливать компоненты даты вне обычного диапазона значений, а объект сам себя исправит.

Неправильные компоненты даты автоматически распределяются по остальным.

Предположим, нам требуется увеличить дату «28 февраля 2016» на два дня. В зависимости от того, високосный это год или нет, результатом будет «2 марта» или «1 марта». Нам об этом думать не нужно. Просто прибавляем два дня. Объект Date позаботится об остальном:

Эту возможность часто используют, чтобы получить дату по прошествии заданного отрезка времени. Например, получим дату «спустя 70 секунд с текущего момента»:

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

Преобразование к числу, разность дат

Если объект Date преобразовать в число, то получим таймстамп по аналогии с date.getTime() :

Важный побочный эффект: даты можно вычитать, в результате получаем разность в миллисекундах.

Этот приём можно использовать для измерения времени:

Date.now()

Если нужно просто измерить время, объект Date нам не нужен.

 

Существует особый метод Date.now() , возвращающий текущую метку времени.

Семантически он эквивалентен new Date().getTime() , однако метод не создаёт промежуточный объект Date . Так что этот способ работает быстрее и не нагружает сборщик мусора.

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

Вероятно, предыдущий пример лучше переписать так:

Бенчмаркинг

Будьте внимательны, если хотите точно протестировать производительность функции, которая зависит от процессора.

Например, сравним две функции, вычисляющие разницу между двумя датами: какая сработает быстрее?

Подобные вычисления, замеряющие производительность, также называют «бенчмарками» (benchmark).

Обе функции делают буквально одно и то же, только одна использует явный метод date.getTime() для получения даты в миллисекундах, а другая полагается на преобразование даты в число. Результат их работы всегда один и тот же.

Но какая функция быстрее?

Для начала можно запустить их много раз подряд и засечь разницу. В нашем случае функции очень простые, так что потребуется хотя бы 100000 повторений.

Вот это да! Метод getTime() работает ощутимо быстрее! Всё потому, что не производится преобразование типов, и интерпретаторам такое намного легче оптимизировать.

Замечательно, это уже что-то. Но до хорошего бенчмарка нам ещё далеко.

Представьте, что при выполнении bench(diffSubtract) процессор параллельно делал что-то ещё, также потребляющее ресурсы. А к началу выполнения bench(diffGetTime) он это уже завершил.

Достаточно реалистичный сценарий в современных многопроцессорных операционных системах.

В итоге у первого бенчмарка окажется меньше ресурсов процессора, чем у второго. Это может исказить результаты.

Для получения наиболее достоверных результатов тестирования производительности весь набор бенчмарков нужно запускать по нескольку раз.

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

Современные интерпретаторы JavaScript выполняют множество оптимизаций. Они могут повлиять на результаты «искусственных тестов» по сравнению с «нормальным использованием», особенно если мы тестируем что-то очень маленькое, например, работу оператора или встроенной функции. Поэтому если хотите серьёзно понять производительность, пожалуйста, изучите, как работают интерпретаторы JavaScript. И тогда вам, вероятно, уже не понадобятся микробенчмарки.

Отличный набор статей о V8 можно найти на https://mrale.ph.

Разбор строки с датой

Метод Date.parse(str) считывает дату из строки.

Формат строки должен быть следующим: YYYY-MM-DDTHH:mm:ss.sssZ , где:

  • YYYY-MM-DD – это дата: год-месяц-день.
  • Символ "T" используется в качестве разделителя.
  • HH:mm:ss.sss – время: часы, минуты, секунды и миллисекунды.
  • Необязательная часть ‘Z’ обозначает часовой пояс в формате +-hh:mm . Если указать просто букву Z , то получим UTC+0.

Возможны и более короткие варианты, например, YYYY-MM-DD или YYYY-MM , или даже YYYY .

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

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

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

Вы не имеете в виду последний день указанного месяца? В ноябре 30 дней, в октябре — 31. — Chris Serra

Месяцы отсчитываются от нуля в javascript, поэтому 11 декабря — Greg

@TheCloudlessSky — попробуйте в своей консоли . (2008,11,0) — нулевой день декабря, а значит, последний день ноября — Ken

@Ken — Ага — я не знал, что там «0» 🙂 . было слишком рано утром. — TheCloudlessSky

21 ответы

Различия в производительности связаны с различиями в toString() реализация не потому, что даты разные.

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

Кажется, это работает отлично. Из любопытства, что вы используете для запуска javascript на всех этих движках? Все настроено или какой-то инструмент? — неонски

вы можете использовать d.getDate (), чтобы получить фактический день. — Рыноп

«просто потому, что браузеры . используют 0 в качестве последнего дня предыдущего месяца, не означает, что они будут продолжать это делать». Да, они обязаны это делать по ECMA-262. — РобГ

Обратите внимание, что использование new Date is so намного медленнее, чем другие методы расчета, даже не отображается на графике производительности: jsperf.com/дни-в-месяце-перф-тест/6 — Исчезло кодирование

У меня это не работает в Chrome 48.0.2564.116. Возможно, этот способ перестал быть «стандартом». — харлымг89

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

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

ответ дан 08 дек ’12, 01:12

Ничего страшного, я заметил, что выбранный ответ предполагает то же самое. Это самый быстрый и надежный способ, работающий независимо от типа календаря. Например, если бы Date реализовал что-то другое, кроме григорианского календаря, он все равно работал бы. Видеть intldate.codeplex.com для примера негрегорианской реализации объекта Date. — Orad

@orad: Остерегайтесь требовать чего-то «самый быстрый» поскольку этот метод на самом деле значительно медленнее, чем некоторые альтернативы. С использованием new Date is so намного медленнее даже не отображается на графике производительности: jsperf.com/дни-в-месяце-перф-тест/6 — Исчезло кодирование

@TrueBlueAussie ОК. Я предполагал, что он быстрее, потому что он был родным. Но ты прав, это не быстро. Спасибо за собственное тестирование. В любом случае, это решение работает лучше всего для меня, потому что оно краткое и удобочитаемое и, в отличие от всех других решений, не привязано к григорианскому календарю. — Orad

«в отличие от всех других решений не привязан к григорианскому календарю» . Этот алгоритм возвращает те же значения, что и мой, для 1-4000 лет. jsfiddle.net/2973x9m3/3 Какой дополнительный диапазон дат, по вашему мнению, будет поддерживаться (что было бы полезно)? 🙂 — Исчезло кодирование

В Native JS Date используется только григорианский календарь. Но вы можете издеваться над ним с помощью другой реализации, чтобы получить другие типы календарей. Например см. IntlDate. Если у вас есть средство выбора даты, которое использует объекты Date для создания ежемесячных представлений, ему все равно, какую реализацию Date (встроенную или имитируемую) он использует, если у них один и тот же интерфейс. Таким образом, использование общего интерфейса позволяет переключаться между различными типами календаря без необходимости знать, сколько дней в месяце в каждом календаре. — Orad

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

ответ дан 12 мар ’16, в 23:03

В соответствии с Спецификация ECMAScript, использование конструктора Date, как вы указали, является допустимым. Следуя алгоритму, указанному функцией «MakeDay», он должен хорошо справиться с проблемой. — Пабло Кабрера

это лучшее решение IMO. Я попробовал принятый ответ, но при получении последнего числа текущего месяца в нем есть ошибка. Возвращает сегодняшнюю дату. Не уверен, почему это происходит. — Гоголь

Я не могу воспроизвести ошибку. Это дает мне правильную дату во всех браузерах: today = new Date(); new Date(today.getFullYear(), today.getMonth()+1, 0).toString(); — Orad

Это создает объект Date для последнего дня месяца со временем, установленным на последнюю миллисекунду (например, 23: 59: 59.999). Лучше просто использовать метод в OP и сохранить дополнительный шаг и объект Date. — РобГ

@RobG: согласен! хотя мое решение может быть проще для понимания, поскольку идея использования 0 в последний день месяца, на мой взгляд, кажется немного неуклюжей. — Кони

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

Мой нынешний быстрый Версия:

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

Учитывая битовый сдвиг, это, очевидно, предполагает, что ваш m & y параметры являются целыми числами, так как передача чисел в виде строк приведет к странным результатам.

По некоторым причинам, (m+(m>>3)&1) более эффективен, чем (5546>>m&1) on почти все браузеры.

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

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

Небольшой урок по бинарным месяцам:

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

Это означает, что вы можете переместить значение на 3 позиции с помощью >> 3 , XOR бит с оригиналом ^ m и посмотрим, будет ли результат 1 or 0 в позиции бита 0 через & 1 . Примечание: оказывается + немного быстрее, чем XOR ( ^ ) и расширение (m >> 3) + m дает тот же результат в бите 0.

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *