Работать с датами в JavaScript очень сложно. Собственные методы работы с датами часто многословны и иногда непоследовательны, что также делает их подверженными ошибкам. Но хорошие новости не за горами. Существует несколько библиотек, которые избавляют от устаревших манипуляций. Эти библиотеки для JavaScript — то же, что jQuery для родного DOM API.
Позвольте привести пример. Это принятый ответ на вопрос о переполнении стека с вопросом, как получить последний день месяца:
var t = new Date () ;
alert (new Date (t.getFullYear (), t.getMonth () + 1, 0, 23, 59, 59));
Конечно, это работает, но не сразу понятно, что представляют цифры после getMonth. Теперь сравните это со значительно более читаемым:
const today = new Date () ;
console.log (lastDayOfMonth (today));
Этот lastDayOfMonthметод предоставляется
В этой статье я собираюсь показать вам, как начать работу с
Итак, почему бы просто не использовать Moment.js?
Moment.js — фантастическая библиотека для работы с датами в JavaScript — она имеет множество замечательных функций и предлагает целый ряд полезных утилит. Это, однако, не без его критиков.
Многие люди ссылаются на тот факт, что объекты Moment изменяемы (например, такие операции, как add, или subtractизменяют исходный объект Moment), как на то, что это сбивает с толку разработчиков и является источником ошибок.
Он также подвергся критике
Это зашло так далеко, что инструменты разработчика Chrome теперь подчеркивают тот факт, что использование Moment может привести к снижению производительности.
Все это привело к тому, что сопровождающие Moment перевели проект в режим обслуживания и не рекомендовали использовать Moment в новых проектах в будущем.
Мы понимаем, что многие существующие проекты могут продолжать использовать Moment, но мы хотели бы предотвратить использование Moment в новых проектах в будущем. Вместо этого мы хотели бы порекомендовать альтернативы, которые сегодня являются отличным выбором для использования в современных приложениях.
Это делает
Установка
Начиная со второй версии библиотеки, единственный способ установить
npm install
Или через пряжу:
yarn add
Вы можете использовать
// CommonJS
const { lastDayOfMonth } = require (‘
или:
// ES Modules
import { lastDayOfMonth } from ‘
К сожалению, в настоящее время нет доступной
Давайте посмотрим, как это сделать сейчас.
Как связать
Я предполагаю, что на вашем компьютере установлены Node и npm. Если нет, обратитесь к нашему руководству по установке Node.
Далее устанавливаем Parcel. Это упаковщик (похожий на Webpack), который позволит вам упаковать ваш JavaScript и обслуживать его в браузере.
npm install -g
Далее создайте новый проект с package.jsonфайлом.
mkdir datefns
cd datefns
npm init -y
Установите библиотеку
npm install
Примечание. Это создаст
Теперь создайте два файла index.htmlи index.js.
<! DOCTYPE html>
import { lastDayOfMonth } from ‘
const today = new Date () ;
console.log (lastDayOfMonth (today));
Запустите встроенный сервер разработки посылки:
parcel index.html
И перейдите по адресу http: //localhost:1234. Вы не увидите ничего отображаемого на странице, но если вы откроете консоль браузера. вы должны, чтобы он зарегистрировал последний день текущего месяца.
Когда дело доходит до развертывания, вы можете запустить:
parcel build index.js —
чтобы Parcel выводил в папку минимизированный и древовидный пакет dist.
Базовое использование
Теперь, когда мы готовы, давайте посмотрим, что может сделать
Одной из наиболее распространенных задач при работе с датами является умение красиво их форматировать. Мы можем сделать это с помощью функции формата
Измените
The date today is
Мы index.jsхотим импортировать formatфункцию, которой мы можем передать сегодняшнюю дату и строку формата. Затем мы хотим вывести результат на страницу.
import { format } from ‘
const today = new Date () ;
const formattedDate = format (today, ‘dd.MM.yyyy’) ;
document.querySelector (‘h1 > span’).textContent = formattedDate;
Конечно, мы не ограничены dd.MM.yyyyформатом, давайте попробуем
const formattedDate = format (today, ‘PPPP’) ;
Это отформатирует вывод следующим образом: Wednesday, September 16th, 2020. Вы можете найти полный список параметров форматирования в документации.
Изменить язык
Если у вас есть
Heute ist
И в файле JavaScript мы можем импортировать немецкую локаль и передать ее formatфункции:
import { format } from ‘
import { de } from ‘
const today = new Date () ;
const formattedDate = format (today, ‘PPPP’, { locale: de }) ;
document.querySelector (‘h1 > span’).textContent = formattedDate;
Это выведет
Может показаться сложным требовать и передавать локали в качестве параметров, но в отличие от Moment.js, который раздувает вашу сборку всеми локалями по умолчанию,
Вы можете просмотреть список доступных локалей, заглянув в node_modules/
Неизменность, чистота и простота
Одним из преимуществ
Позвольте мне продемонстрировать это на примере Moment.js. Как упоминалось ранее, даты в Moment изменяемы, что может привести к неожиданному поведению.
const moment = require (‘moment’) ;
const now = new Date () ;
const mNow = moment (now) ;
mNow.add (‘day’, 3) ;
console.log (mNow.toDate ());
mNow.add (3, ‘day’) ;
console.log (mNow.toDate ());
//
//
Здесь есть несколько вещей, на которые следует обратить внимание. Функция Moment addне привередлива к порядку, в котором она принимает свои аргументы (хотя первый метод теперь выдает предупреждение об устаревании). Но еще больше сбивает с толку то, что если вы вызываете addнесколько раз подряд, вы не получите тот же результат, потому что объекты Moment изменяемы:
mNow.add (3, ‘day’) ; // add 3 days
mNow.add (3, ‘day’) ; // adds 3 **more** days
Теперь сравните это с
import { addDays } from ‘
const today = new Date () ;
const threeDaysTime = addDays (3, today) ;
const sixDaysTime = addDays (threeDaysTime, 3) ;
console.log (today) ; // Wed Sep 16 2020 12:11:55 GMT+0200
console.log (threeDaysTime) ; // Sat Sep 19 2020 12:12:58 GMT+0200
console.log (sixDaysTime) ; // Invalid Date
Также обратите внимание на то, что имя метода стало более выразительным (addDaysвместо простого add), сохраняя согласованность и наличие одного метода для выполнения одной и только одной операции.
Сравнение дат
Если вы посмотрите на список сообщений на канале JavaScript SitePoint, вы увидите, что некоторые из них указаны как опубликованные на определенную дату, тогда как другие указаны как опубликованные X дней назад. Это может занять некоторое время, если вы попытаетесь реализовать это в ванильном JavaScript, но с
Давайте сравним две разные даты.
import { formatDistance } from ‘
const startDate = new Date (2020, 8, 16) ; // (Sep 16 2020)
const endDate = new Date (2020, 11, 25) ; // (Dec 25 2020)
const distanceInWords = formatDistance (startDate, endDate) ;
console.log (`It is ${distanceInWords} until Christmas`) ;
// It is 3 months until Christmas
Обратите внимание, что при работе с JavaScript месяцы отсчитываются от нуля (например,
Работа с коллекциями дат
Заказ коллекции фиников
В следующем примере compareAsc используется для сортировки дат по возрастанию. Для этого он возвращает 1, если первая дата предшествует второй, -1, если первая дата предшествует второй, или 0, если даты равны.
import { compareAsc } from ‘
const date1 = new Date ('
const date2 = new Date ('
const date3 = new Date ('
const arr = [date3, date1, date2];
const sortedDates = arr.sort (compareAsc) ;
// [
Как видите, даты расположены в порядке возрастания.
Метод аналога compareAsc— compareDesc.
import { compareDesc } from ‘
...
const sortedDates = arr.sort (compareDesc) ;
// [
Генерация дней между двумя датами
Чтобы сгенерировать дни между двумя датами, вы можете использовать метод addDays, который мы встречали ранее, а также вспомогательную функцию eachDayOfInterval, которая возвращает массив дат в указанном диапазоне.
import { addDays, eachDayOfInterval } from ‘
const today = new Date () ;
const aWeekFromNow = addDays (today, 7) ;
const thisWeek = eachDayOfInterval (
{ start: today, end: aWeekFromNow },
) ;
console.log (thisWeek) ;
/*
[
Wed Sep 16 2020 00:00:00 GMT+0200 (Central European Summer Time),
Thu Sep 17 2020 00:00:00 GMT+0200 (Central European Summer Time),
Fri Sep 18 2020 00:00:00 GMT+0200 (Central European Summer Time),
Sat Sep 19 2020 00:00:00 GMT+0200 (Central European Summer Time),
Sun Sep 20 2020 00:00:00 GMT+0200 (Central European Summer Time),
Mon Sep 21 2020 00:00:00 GMT+0200 (Central European Summer Time),
Tue Sep 22 2020 00:00:00 GMT+0200 (Central European Summer Time),
Wed Sep 23 2020 00:00:00 GMT+0200 (Central European Summer Time)
]
*/
Поиск ближайшей даты
Поиск ближайшей даты к определенной дате в массиве дат можно выполнить с помощью метода NearbyTo. Этот фрагмент кода следует из предыдущего примера:
import { addDays, eachDayOfInterval, closestTo } from ‘
...
const christmas = new Date (2020, 11, 25) ;
const closestToChristmasDate = closestTo (christmas, thisWeek) ;
console.log (closestToChristmasDate) ;
// Wed Sep 23 2020 00:00:00 GMT+0200 (Central European Summer Time)
Также есть метод closeIndexTo, если вместо этого вы хотите получить индекс массива.
Проверка даты
Последний помощник, на который я хочу обратить внимание, — это метод isValid, который, как следует из названия, проверяет, действительна ли заданная дата.
Однако
import { isValid } from ‘
const invalidDate = new Date ('2020, 02, 30') ;
console.log (isValid (invalidDate));
// true, lol, wut?
Простите, если вы думаете, что приведенный выше фрагмент должен выводить false, поскольку 30 февраля 2020 года явно недопустимая дата. Чтобы понять, что происходит, введите new Date ('2020, 02, 30') в консоли браузера. Вы увидите Sun Mar 01 2020, что к вам вернется — JavaScript взял лишний день с конца февраля и превратил его в 1 марта (что, конечно, является допустимой датой).
Чтобы обойти это, мы можем проанализировать дату перед проверкой ее достоверности:
import { isValid, parse } from ‘
const validDate = parse ('29.02.2020', ‘dd.MM.yyyy’, new Date ());
const invalidDate = parse ('30.02.2020', ‘dd.MM.yyyy’, new Date ());
console.log (validDate) ;
// Sat Feb 29 2020 00:00:00 GMT+0100 (Central European Standard Time)
console.log (invalidDate) ;
// Invalid Date
console.log (isValid (validDate));
// true
console.log (isValid (invalidDate));
// false
Это можно легко преобразовать в небольшой вспомогательный метод, полезный, например, для проверки пользовательского ввода в формах.
Часовые пояса
Одним из недостатков
Этот ответ Stack Overflow дает некоторое представление о том, как нативные Dateобъекты на самом деле не хранят данные «реального часового пояса». В этой ветке вы заметите, что они упоминают метод установки часовых поясов изначально в JavaScript. Это не комплексное решение, но оно работает для многих сценариев, требующих только преобразования вывода (из UTC или местного времени в определенный часовой пояс).
new Date ().toLocaleString («
Часовые пояса на самом деле являются сложной проблемой для решения, поэтому MomentJS имеет для этого отдельную библиотеку. Есть планы добавить поддержку часовых поясов в
Однако в npm доступен пакет (на основе неслитного запроса на вытягивание для
Тем не менее, вот как вы можете его использовать:
npm i
import { format, utcToZonedTime } from ‘
const today = new Date () ; // Wed Sep 16 2020 13:25:16
const timeZone = ‘Australia/Brisbane’; // Let’s see what time it is Down Under
const timeInBrisbane = utcToZonedTime (today, timeZone) ;
console.log (`
Time in Munich: ${format (today, ‘
Time in Brisbane: ${format (timeInBrisbane, ‘
`) ;
// Time in Munich:
// Time in Brisbane:
Вывод
Я надеюсь, что эта статья дала вам достаточно понимания и вдохновения, чтобы проверить ее и начать использовать в своих проектах.