Js сколько дней между датами
Перейти к содержимому

Js сколько дней между датами

Дата и Время

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/date.

Для работы с датой и временем в JavaScript используются объекты Date.

Создание

Для создания нового объекта типа Date используется один из синтаксисов:

Создаёт объект Date с текущей датой и временем:

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

Если единственный аргумент – строка, используется вызов Date.parse (см. далее) для чтения даты из неё.

new Date(year, month, date, hours, minutes, seconds, ms)

Дату можно создать, используя компоненты в местной временной зоне. Для этого формата обязательны только первые два аргумента. Отсутствующие параметры, начиная с hours считаются равными нулю, а date – единице.

Год year должен быть из 4 цифр.

Отсчёт месяцев month начинается с нуля 0.

Дата задана с точностью до миллисекунд:

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

Для доступа к компонентам даты-времени объекта Date используются следующие методы:

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

Некоторые браузеры реализуют нестандартный метод getYear() . Где-то он возвращает только две цифры из года, где-то четыре. Так или иначе, этот метод отсутствует в стандарте JavaScript. Не используйте его. Для получения года есть getFullYear() .

Дополнительно можно получить день недели:

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

Все методы, указанные выше, возвращают результат для местной временной зоны.

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

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

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

Возвращает число миллисекунд, прошедших с 1 января 1970 года GMT+0, то есть того же вида, который используется в конструкторе new Date(milliseconds) .

Возвращает разницу между местным и UTC-временем, в минутах.

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

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

  • setFullYear(year [, month, date])
  • setMonth(month [, date])
  • setDate(date)
  • setHours(hour [, min, sec, ms])
  • setMinutes(min [, sec, ms])
  • setSeconds(sec [, ms])
  • setMilliseconds(ms)
  • setTime(milliseconds) (устанавливает всю дату по миллисекундам с 01.01.1970 UTC)

Все они, кроме setTime() , обладают также UTC-вариантом, например: setUTCHours() .

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

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

Автоисправление – очень удобное свойство объектов Date . Оно заключается в том, что можно устанавливать заведомо некорректные компоненты (например 32 января), а объект сам себя поправит.

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

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

Также это используют для получения даты, отдалённой от имеющейся на нужный промежуток времени. Например, получим дату на 70 секунд большую текущей:

Можно установить и нулевые, и даже отрицательные компоненты. Например:

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

Когда объект Date используется в числовом контексте, он преобразуется в количество миллисекунд:

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

Это используют для измерения времени:

Бенчмаркинг

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

Как узнать, какой быстрее?

Для примера возьмём две функции, которые бегают по массиву:

Чтобы померить, какая из них быстрее, нельзя запустить один раз walkIn , один раз walkLength и замерить разницу. Одноразовый запуск ненадёжен, любая мини-помеха исказит результат.

Для правильного бенчмаркинга функция запускается много раз, чтобы сам тест занял существенное время. Это сведёт влияние помех к минимуму. Сложную функцию можно запускать 100 раз, простую – 1000 раз…

Померяем, какая из функций быстрее:

Теперь представим себе, что во время первого бенчмаркинга bench(walkIn) компьютер что-то делал параллельно важное (вдруг) и это занимало ресурсы, а во время второго – перестал. Реальная ситуация? Конечно реальна, особенно на современных ОС, где много процессов одновременно.

Гораздо более надёжные результаты можно получить, если весь пакет тестов прогнать много раз.

В современных браузерах (кроме IE9-) вызов performance.now() возвращает количество миллисекунд, прошедшее с начала загрузки страницы. Причём именно с самого начала, до того, как загрузился HTML-файл, если точнее – с момента выгрузки предыдущей страницы из памяти.

Так что это время включает в себя всё, включая начальное обращение к серверу.

Его можно посмотреть в любом месте страницы, даже в <head> , чтобы узнать, сколько времени потребовалось браузеру, чтобы до него добраться, включая загрузку HTML.

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

Для измерения с одновременным выводом результатов в консоли есть методы:

  • console.time(метка) – включить внутренний хронометр браузера с меткой.
  • console.timeEnd(метка) – выключить внутренний хронометр браузера с меткой и вывести результат.

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

В коде ниже таймеры walkIn , walkLength – конкретные тесты, а таймер «All Benchmarks» – время «на всё про всё»:

При запуске этого примера нужно открыть консоль, иначе вы ничего не увидите.

Современные интерпретаторы JavaScript делают массу оптимизаций, например:

  1. Автоматически выносят инвариант, то есть постоянное в цикле значение типа arr.length , за пределы цикла.
  2. Стараются понять, значения какого типа хранит данная переменная или массив, какую структуру имеет объект и, исходя из этого, оптимизировать внутренние алгоритмы.
  3. Выполняют простейшие операции, например сложение явно заданных чисел и строк, на этапе компиляции.
  4. Могут обнаружить, что некий код, например присваивание к неиспользуемой локальной переменной, ни на что не влияет и вообще исключить его из выполнения, хотя делают это редко.

Эти оптимизации могут влиять на результаты тестов, поэтому измерять скорость базовых операций JavaScript («проводить микробенчмаркинг») до того, как вы изучите внутренности JavaScript-интерпретаторов и поймёте, что они реально делают на таком коде, не рекомендуется.

Форматирование и вывод дат

Во всех браузерах, кроме IE10-, поддерживается новый стандарт Ecma 402, который добавляет специальные методы для форматирования дат.

Это делается вызовом date.toLocaleString(локаль, опции) , в котором можно задать много настроек. Он позволяет указать, какие параметры даты нужно вывести, и ряд настроек вывода, после чего интерпретатор сам сформирует строку.

Пример с почти всеми параметрами даты и русским, затем английским (США) форматированием:

Вы сможете подробно узнать о них в статье Intl: интернационализация в JavaScript, которая посвящена этому стандарту.

Методы вывода без локализации:

toString() , toDateString() , toTimeString() Возвращают стандартное строчное представление, не заданное жёстко в стандарте, а зависящее от браузера. Единственное требование к нему – читаемость человеком. Метод toString возвращает дату целиком, toDateString() и toTimeString() – только дату и время соответственно.

toUTCString() То же самое, что toString() , но дата в зоне UTC.

toISOString() Возвращает дату в формате ISO Детали формата будут далее. Поддерживается современными браузерами, не поддерживается IE8-.

Если хочется иметь большую гибкость и кросс-браузерность, то также можно воспользоваться специальной библиотекой, например Moment.JS или написать свою функцию форматирования.

Разбор строки, Date.parse

Все современные браузеры, включая IE9+, понимают даты в упрощённом формате ISO 8601 Extended.

Этот формат выглядит так: YYYY-MM-DDTHH:mm:ss.sssZ , где:

  • YYYY-MM-DD – дата в формате год-месяц-день.
  • Обычный символ T используется как разделитель.
  • HH:mm:ss.sss – время: часы-минуты-секунды-миллисекунды.
  • Часть ‘Z’ обозначает временную зону – в формате +-hh:mm , либо символ Z , обозначающий UTC. По стандарту её можно не указывать, тогда UTC, но в Safari с этим ошибка, так что лучше указывать всегда.

Также возможны укороченные варианты, например YYYY-MM-DD или YYYY-MM или даже только YYYY .

Как узнать количество дней между двумя датами в JavaScript?

Как узнать количество дней между двумя датами в JavaScript? Например, в полях ввода указаны две даты:

30 ответов

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

Вы должны знать, что «нормальные» API-интерфейсы Date (без «UTC» в названии) работают в локальном часовом поясе браузера пользователя, поэтому в целом вы можете столкнуться с проблемами, если ваш пользователь находится в часовом поясе, который вы не делаете. ожидайте, и ваш код будет иметь дело с переходами на летнее время. Вам следует внимательно прочитать документацию по объекту Date и его методам, а для чего-либо более сложного настоятельно рекомендуем использовать библиотеку, которая предлагает более безопасные и мощные API для манипулирования датами.

Кроме того, в иллюстративных целях фрагмент использует для краткости именованный доступ к объекту window , но в производстве вы должны использовать стандартизированные API, такие как getElementById или, более вероятно, некоторая структура пользовательского интерфейса.

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

Если вы хотите иметь DateArray с датами, попробуйте это:

Значения даты в JS являются значениями даты и времени.

Таким образом, прямые вычисления даты противоречивы:

Например нам нужно конвертировать 2-ую дату:

Метод можно обрезать мельницы в обе даты:

Я рекомендую использовать библиотеку moment.js (http://momentjs.com/docs/#/displaying / разница / ) . Он правильно обрабатывает переход на летнее время и в целом с ним приятно работать.

Возможно, это не самое элегантное решение, но, кажется, оно отвечает на вопрос относительно простым кусочком кода, я думаю. Разве вы не можете использовать что-то вроде этого:

Предполагается, что вы передаете объекты даты в качестве параметров.

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

Как насчет использования formatDate из виджета DatePicker? Вы можете использовать его для преобразования дат в формат отметки времени (миллисекунды с 01.01.1970), а затем выполнить простое вычитание.

Самый простой способ получить разницу между двумя датами:

Вы получаете разницу дней (или NaN, если один или оба не могут быть проанализированы). Дата разбора дала результат в миллисекундах, и чтобы получить его по дням, нужно разделить его на 24 * 60 * 60 * 1000

Если вы хотите, чтобы оно делилось на дни, часы, минуты, секунды и миллисекунды:

Вот моя переработанная версия Джеймса:

На момент написания статьи только один из остальных ответов правильно обрабатывал переходы DST (летнее время). Вот результаты для системы, расположенной в Калифорнии:

Хотя Math.round возвращает правильные результаты, я думаю, что это несколько неуклюже. Вместо этого, явно учитывая изменения в смещении UTC, когда начинается или заканчивается DST, мы можем использовать точную арифметику:

Объяснение

Вычисление дат в JavaScript сложно, потому что Date объекты хранят время внутри UTC, а не по местному времени. Например, 3/10/2013 12:00 по тихоокеанскому стандартному времени (UTC-08: 00) хранится как 3/10/2013 8:00 по UTC и 11.03.2013 в 12:00 по тихоокеанскому летнему времени ( UTC-07: 00) хранится как 11.03.2013 7:00 UTC. В этот день с полуночи до полуночи по местному времени в UTC только 23 часа!

Хотя день по местному времени может иметь больше или меньше 24 часов, день в UTC всегда равен 24 часам. 1 Показанный выше метод daysBetween использует этот факт, сначала вызывая treatAsUTC для корректировки местного времени до полуночи UTC перед вычитанием и делением.

Date and time

Let’s meet a new built-in object: Date. It stores the date, time and provides methods for date/time management.

For instance, we can use it to store creation/modification times, to measure time, or just to print out the current date.

Creation

To create a new Date object call new Date() with one of the following arguments:

Without arguments – create a Date object for the current date and time:

Create a Date object with the time equal to number of milliseconds (1/1000 of a second) passed after the Jan 1st of 1970 UTC+0.

An integer number representing the number of milliseconds that has passed since the beginning of 1970 is called a timestamp.

It’s a lightweight numeric representation of a date. We can always create a date from a timestamp using new Date(timestamp) and convert the existing Date object to a timestamp using the date.getTime() method (see below).

Dates before 01.01.1970 have negative timestamps, e.g.:

If there is a single argument, and it’s a string, then it is parsed automatically. The algorithm is the same as Date.parse uses, we’ll cover it later.

Create the date with the given components in the local time zone. Only the first two arguments are obligatory.

  • The year should have 4 digits. For compatibility, 2 digits are also accepted and considered 19xx , e.g. 98 is same as 1998 here, but always using 4 digits is strongly encouraged.
  • The month count starts with 0 (Jan), up to 11 (Dec).
  • The date parameter is actually the day of month, if absent then 1 is assumed.
  • If hours/minutes/seconds/ms is absent, they are assumed to be equal 0 .

The maximal precision is 1 ms (1/1000 sec):

Access date components

There are methods to access the year, month and so on from the Date object:

getFullYear() Get the year (4 digits) getMonth() Get the month, from 0 to 11. getDate() Get the day of month, from 1 to 31, the name of the method does look a little bit strange. getHours(), getMinutes(), getSeconds(), getMilliseconds() Get the corresponding time components.

Many JavaScript engines implement a non-standard method getYear() . This method is deprecated. It returns 2-digit year sometimes. Please never use it. There is getFullYear() for the year.

Additionally, we can get a day of week:

getDay() Get the day of week, from 0 (Sunday) to 6 (Saturday). The first day is always Sunday, in some countries that’s not so, but can’t be changed.

All the methods above return the components relative to the local time zone.

There are also their UTC-counterparts, that return day, month, year and so on for the time zone UTC+0: getUTCFullYear(), getUTCMonth(), getUTCDay(). Just insert the "UTC" right after "get" .

If your local time zone is shifted relative to UTC, then the code below shows different hours:

Besides the given methods, there are two special ones that do not have a UTC-variant:

Returns the timestamp for the date – a number of milliseconds passed from the January 1st of 1970 UTC+0.

Returns the difference between UTC and the local time zone, in minutes:

Setting date components

The following methods allow to set date/time components:

Every one of them except setTime() has a UTC-variant, for instance: setUTCHours() .

As we can see, some methods can set multiple components at once, for example setHours . The components that are not mentioned are not modified.

Autocorrection

The autocorrection is a very handy feature of Date objects. We can set out-of-range values, and it will auto-adjust itself.

Out-of-range date components are distributed automatically.

Let’s say we need to increase the date “28 Feb 2016” by 2 days. It may be “2 Mar” or “1 Mar” in case of a leap-year. We don’t need to think about it. Just add 2 days. The Date object will do the rest:

That feature is often used to get the date after the given period of time. For instance, let’s get the date for “70 seconds after now”:

We can also set zero or even negative values. For example:

Date to number, date diff

When a Date object is converted to number, it becomes the timestamp same as date.getTime() :

The important side effect: dates can be subtracted, the result is their difference in ms.

That can be used for time measurements:

Date.now()

If we only want to measure time, we don’t need the Date object.

There’s a special method Date.now() that returns the current timestamp.

It is semantically equivalent to new Date().getTime() , but it doesn’t create an intermediate Date object. So it’s faster and doesn’t put pressure on garbage collection.

It is used mostly for convenience or when performance matters, like in games in JavaScript or other specialized applications.

So this is probably better:

Benchmarking

If we want a reliable benchmark of CPU-hungry function, we should be careful.

For instance, let’s measure two functions that calculate the difference between two dates: which one is faster?

Such performance measurements are often called “benchmarks”.

These two do exactly the same thing, but one of them uses an explicit date.getTime() to get the date in ms, and the other one relies on a date-to-number transform. Their result is always the same.

So, which one is faster?

The first idea may be to run them many times in a row and measure the time difference. For our case, functions are very simple, so we have to do it at least 100000 times.

Wow! Using getTime() is so much faster! That’s because there’s no type conversion, it is much easier for engines to optimize.

Okay, we have something. But that’s not a good benchmark yet.

Imagine that at the time of running bench(diffSubtract) CPU was doing something in parallel, and it was taking resources. And by the time of running bench(diffGetTime) that work has finished.

A pretty real scenario for a modern multi-process OS.

As a result, the first benchmark will have less CPU resources than the second. That may lead to wrong results.

For more reliable benchmarking, the whole pack of benchmarks should be rerun multiple times.

For example, like this:

Modern JavaScript engines start applying advanced optimizations only to “hot code” that executes many times (no need to optimize rarely executed things). So, in the example above, first executions are not well-optimized. We may want to add a heat-up run:

Modern JavaScript engines perform many optimizations. They may tweak results of “artificial tests” compared to “normal usage”, especially when we benchmark something very small, such as how an operator works, or a built-in function. So if you seriously want to understand performance, then please study how the JavaScript engine works. And then you probably won’t need microbenchmarks at all.

The great pack of articles about V8 can be found at http://mrale.ph.

Date.parse from a string

The method Date.parse(str) can read a date from a string.

The string format should be: YYYY-MM-DDTHH:mm:ss.sssZ , where:

  • YYYY-MM-DD – is the date: year-month-day.
  • The character "T" is used as the delimiter.
  • HH:mm:ss.sss – is the time: hours, minutes, seconds and milliseconds.
  • The optional ‘Z’ part denotes the time zone in the format +-hh:mm . A single letter Z would mean UTC+0.

Shorter variants are also possible, like YYYY-MM-DD or YYYY-MM or even YYYY .

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

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