Moment.js: улучшенная библиотека дат для JavaScript

Как знает любой опытный программист, дата и время невероятно распространены в коде большинства приложений. Вы можете использовать даты для отслеживания создания объекта, для отслеживания времени, прошедшего с момента возникновения события, или для сохранения даты предстоящего события. Однако работать с датами непросто, поэтому важно иметь точную библиотеку с простым интерфейсом. Стандартный объект JavaScript Date не так уж и плох, но в нем отсутствуют некоторые важные функции, и он не всегда прост в работе.

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

В этой статье вы увидите, как Moment упрощает анализ, форматирование и управление датами и временем.

Даты разбора

Струны

По умолчанию Moment пытается анализировать строки даты, используя формат ISO 8601 , который имеет широкий диапазон допустимых дат. С помощью этого формата вы можете указать для даты и времени как можно меньшую или большую точность времени. Это очень удобно, поскольку даты могут принимать самые разные формы в зависимости от уровня детализации, который вы хотите указать.

Рассмотрим попытку разобрать все эти разные форматы самостоятельно:

  • 20160628
  • 2016-06-28T09
  • 20160628T080910,123
  • 2016-06-28, 09:30: 26.123
  • 2016-06-28 09: 30: 26.123 + 07: 00

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

Во-первых, самый простой способ создать moment - вызвать конструктор без аргументов:

 > const moment = require('moment'); 
 > let m = moment(); 

Это создаст экземпляр объекта даты с текущим временем.

Чтобы проанализировать строку даты и времени с помощью Moment, просто передайте ее конструктору:

 > let date = moment('2016-06-28 09:30:26.123'); 

Если по какой-то причине Moment не может проанализировать переданную вами строку, он вернется к использованию встроенного new Date() для синтаксического анализа.

Чтобы проверить, была ли ваша дата проанализирована и действительна, используйте метод .isValid() :

 > moment('2016-06-28 09:30:26.123').isValid(); 
 true 
 > moment('derp').isValid(); 
 false 

Для всех объектов даты, созданных с помощью Moment, независимо от того, как вы их анализируете или создаете, часовой пояс в объекте по умолчанию будет соответствовать текущему часовому поясу, если не указан напрямую. Чтобы вернуть время по Гринвичу, используйте вместо этого moment.utc() Дополнительные сведения о часовых поясах см. В разделе « Часовые пояса моментов» .

Указание форматов

Одна из моих любимых функций синтаксического анализа в Moment - синтаксический анализатор строк / форматов. Это в основном похоже на средство форматирования обратной строки. Вы предоставляете строку даты и времени для синтаксического анализа и другую строку, которая определяет формат, в котором она находится. Таким образом, вы можете использовать строки любого желаемого формата и при этом удобно использовать их с Moment.

Например, в США (по какой-то причине) нам нравится форматировать наши даты как «Месяц / День / Год», тогда как большая часть остального мира форматирует свои даты как «День / Месяц / Год». Это оставляет много места для путаницы. Например, дата «06.11.2016» должна быть 6 ноября или 11 июня?

world timeformats{.ezlazyload}
[Изображение: Джон Хардинг / Мона Чалаби через The Guardian]{.small}

Итак, как мы узнаем, правильно ли анализируются ваши даты? Использование таких спецификаторов формата гарантирует отсутствие двусмысленности в ваших датах, если вы заранее знаете, в каком они формате. В следующем примере мы по-прежнему можем анализировать правильные даты, несмотря на разные и потенциально сбивающие с толку форматы.

 > let d1 = moment('11.06.2016', 'DD-MM-YYYY'); 
 > let d2 = moment('06/11/2016', 'MM-DD-YYYY'); 
 
 > d1.format(); // '2016-06-11T00:00:00-05:00' 
 > d2.format(); // '2016-06-11T00:00:00-05:00' 

Обратите внимание, что мы также используем разные разделители в строках даты, "." а также "/". Moment фактически игнорирует все не буквенно-цифровые символы при использовании этих форматов, поэтому вам не всегда нужно беспокоиться об идеальном сопоставлении форматов.

Полный набор доступных токенов форматирования можно найти в этом разделе документации Moment.js .

Метки времени Unix

Как и следовало ожидать, Moment также может анализировать целочисленные даты ( время Unix ) в формате секунд или миллисекунд:

 > moment.unix(1467128085); // Date in seconds from 1970 
 > moment(1467128085747); // Date in milliseconds from 1970 

Единственная разница во времени - это точность. millisecondDate будет иметь ненулевое значение для поля миллисекунды.

Даты печати

На мой взгляд, это одна из наиболее полезных частей Moment, в основном потому, что встроенный Date в JavaScript не очень хорошо поддерживает его. Удивительно, но единственный встроенный способ выполнить форматирование с помощью Date - это использовать метод Date.toLocaleDateString() , который кажется довольно неуклюжим и не таким гибким:

 > let d = new Date(1467128085747); 
 > let options = { 
 ... weekday: 'long', year: 'numeric', month: 'short', 
 ... day: 'numeric', hour: '2-digit', minute: '2-digit' 
 ... }; 
 
 > date.toLocaleTimeString('en-us', options); 
 'Tuesday, Jun 28, 2016, 10:34 AM' 

С помощью Moment мы можем легко добиться того же форматирования, используя только одну строку кода (которую я покажу в следующем разделе).

Мы разделим это на несколько подразделов. Сначала мы рассмотрим традиционное форматирование с помощью токенов, затем покажем доступные относительные форматы даты (например, «18 минут назад») и, наконец, покажем, как форматировать даты как различные типы структурированных данных. например, массивы, JSON или простой Object JavaScript.

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

Используйте метод .format() для отображения даты в виде строки. Без каких-либо аргументов он печатает строку в представлении ISO 8601:

 > let date = moment.unix(1467128085); 
 > date.format(); 
 '2016-06-28T10:34:45-05:00' 

В противном случае вы можете указать свой собственный формат и настроить его по своему вкусу с помощью токенов.

 > date.format('dddd, MMMM Do YYYY, h:mm a'); 
 'Tuesday, June 28th 2016, 10:34 am' 

Вы могли заметить, что это то же представление, что и в Date.toLocaleTimeString() , но в одной строке. И все, что потребовалось, это строка 'dddd, MMMM Do YYYY, h: mm a'.

Опять же, полный список токенов формата можно найти на очень подробном веб-сайте документации Moment.

Относительные форматы

Например, в веб-приложениях часто бывает полезно показать пользователю, сколько времени прошло с момента возникновения события. Вместо того, чтобы рассчитывать это самостоятельно, Moment предлагает некоторые служебные функции для обработки этого форматирования за вас.

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

Из коробки вы получаете несколько разных вариантов:

Время с этого момента

Предполагая, что сегодняшняя дата - 1 июля 2016 года, вы получите следующее относительное форматирование:

 > moment({year: 2016, month: 3, day: 13, hour: 10}).fromNow(); 
 '3 months ago' 
 > moment({year: 2016, month: 9, day: 23, hour: 10}).fromNow(); 
 'in 4 months' 

При желании вы можете передать Boolean в .fromNow() сообщающее, следует ли включать строку «назад» (или «в») в форматирование. Таким образом, при необходимости вы можете легко настроить относительную строку.

 > moment({year: 2016, month: 3, day: 13, hour: 10}).fromNow(true); 
 '3 months' 

Время от даты

 > let may = moment({year: 2016, month: 5, day: 3}); 
 > let october = moment({year: 2016, month: 10, day: 9}); 
 > 
 > may.from(october); 
 '5 months ago' 
 > october.from(may); 
 'in 5 months' 

Время сейчас

 > moment({year: 2016, month: 3, day: 13, hour: 10}).toNow(); 
 'in 3 months' 
 > moment({year: 2016, month: 9, day: 23, hour: 10}).toNow(); 
 '4 months ago' 

Время до даты

 > let may = moment({year: 2016, month: 5, day: 3}); 
 > let october = moment({year: 2016, month: 10, day: 9}); 
 > may.to(october) 
 'in 5 months' 
 > 
 > october.to(may) 
 '5 months ago' 

Вы могли заметить, что оба метода «from» и «to» можно поменять местами, в зависимости от того, какие даты передаются в аргументе. Все относительно.

Структурированная дата-время

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

  • Todate (): Возвращает дату Moment как JavaScript Date
  • toArray () : возвращает данные даты в виде массива - [ 2016, 5, 28, 10, 34, 45, 747 ]
  • toJSON () : возвращает строку даты ISO, скорректированную на UTC - «2016-06-28T15: 34: 45.747Z».
  • toISOString () : возвращает строку даты ISO, скорректированную по всемирному координированному времени - «2016-06-28T15: 34: 45.747Z».
  • toObject () : возвращает простой Object JavaScript с данными даты - {years: 2016, months: 5, date: 28, hours: 10, minutes: 34, seconds: 45, milliseconds: 747}
  • toString () : возвращает отформатированную строку, аналогичную Date.toString() - «Tue Jun 28 2016 10:34:45 GMT-0500».

Управление датами

Возможность манипулировать датами также очень важна для многих приложений. И это не так просто, как обычная арифметика - манипулировать датами сложно. Сможете ли вы легко вычислить эти сложения / вычитания даты / времени? Программировать это непростая задача.

  • 21 февраля + 13 недель
  • 3:14 + 424 минуты
  • 1 июля - 1899400140 миллисекунд

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

Существует довольно много методов манипулирования временем, поэтому мы рассмотрим только наиболее часто используемые:

Сложение / Вычитание

Используйте число / строку или объект для управления датой:

 > moment().add(7, 'days'); 
 > moment().subtract({days:13, months:3}); 

Также хорошо работает цепочка:

 > moment().add({hours: 7}).subtract(13, 'minutes'); 

Начало / конец времени

Эти удобные методы устанавливают дату / время на конец заданной единицы времени. Например, если у вас есть дата с временем 2:15, но вам нужно, чтобы она была началом дня, вы должны использовать:

 > moment().startOf('day'); 

Это установит время на 12:00 того же дня. То же самое работает для года, месяца, часа и многого другого.

 > moment().endOf('year'); // sets date to 12-31-2016 23:59:59.999 

Я обнаружил, что это очень полезно в приложениях для отчетов, где пользователи могут выбирать временные рамки для отчетов, например в Google Analytics. Чтобы получить правильные данные, вам нужен правильный диапазон.

Момент часовых поясов

Moment поддерживает настройку смещения часового пояса из коробки, но если вам нужна лучшая поддержка часового пояса, вам следует подумать об использовании moment-timezone .

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

Чтобы использовать его, установите с помощью npm и require() вместо moment :

 > const moment = require('moment-timezone'); 

Имея более 550 идентификаторов часовых поясов, вы можете разделить спецификаторы часового пояса по различным региональным категориям и названиям:

  • Название часового пояса: США / Центральный, США / Восточный, США / Горный и т. Д.
  • Город: Америка / Чикаго, Америка / Лос-Анджелес, Азия / Дубай, Австралия / Сидней и т. Д.
  • Смещение по Гринвичу: Etc / GMT + 6, Etc / GMT-2, Etc / GMT0 и т. Д.

Чтобы просмотреть полный список идентификаторов часовых поясов, вы можете просмотреть полный список имен, выполнив:

 > const moment = require('moment-timezone'); 
 > moment.tz.names() 

Чтобы использовать эти идентификаторы для установки времени и часового пояса с помощью .tz() :

 > moment.tz({year: 2016, month: 6, day: 30, hour: 11}, 'America/Los_Angeles').format(); 
 '2016-07-30T11:00:00-07:00' 
 > moment.tz({year: 2016, month: 6, day: 30, hour: 11}, 'America/Chicago').format(); 
 '2016-07-30T11:00:00-05:00' 

Заключение

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

В дополнение к синтаксическому анализу, форматированию и манипуляции, которые предоставляет Moment, существует также дополнительная поддержка часовых поясов через пакет moment-timezone Облегчите жизнь себе и своим пользователям, добавив улучшенную поддержку часовых поясов.

Какие еще функции Moment вы часто используете? Дайте нам знать об этом в комментариях!

comments powered by Disqus