Согласно МДН:

Дата в JavaScript определяется как время в миллисекундах, прошедшее с эпохи, которая определяется как полночь начала 1 января 1970 года по Гринвичу (эквивалентно эпохе UNIX). Эта отметка временинезависима от часового поясаи однозначно определяет момент в истории.

Мы знаем, что можем получить текущее время, используя Date.now(). Что вернет нам количество миллисекунд прошедшее с полуночи в начале 1 января 1970 года по всемирному координированному времени.

Обычно дата и время хранятся в базе данных в отметке времени UNIX.

Временная метка UNIX – это числопрошедших с 1 января 1970 года.

Преобразование метки времени в прошедшее время (день, минуты и секунды)

Давайте возьмем пример, когда у нас есть сообщение в Facebook, и нам нужно показать в нем строку относительного времени. Если пост был сделан 17.05.2023, а сегодня 19.05.2023. В сообщении должно отображаться 2 days ago. И вчера, если это было размещено 18 числа.

Сначала рассчитаем время между временем поста и текущим временем.

Мы получаем временную метку сообщения UNIX с сервера, и мы можем получить текущее время от Date.now().

Мы преобразуем метку времени UNIX (в секундах) в миллисекунды. Date.now() возвращает нам время в миллисекундах.

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

let currentTimestamp = Date.now(); let postTimestamp = getPostDateFromServer()*1000 let timePassedInMilliseconds = currentTimestamp - postTimestamp

Теперь у нас есть timePassedInMilliseconds. Мы можем использовать его, чтобы вычислить, сколько дней, минут или секунд назад был сделан пост. Мы покажем X дней назад, если дней больше 0, иначе мы покажем ему X часов назад и так далее.

Мы также можем показывать пользователю годы и месяцы, но мы будем использовать только дни. Если дней больше 30. Мы показываем 31 день назад, а не 1 месяц назад.

Давайте сначала посчитаем, сколько миллисекунд в одном (день, час, минута и секунда)

let millsecInOneSec=1000; let millsecInOneMinute=60*millsecInOneSec; let millsecInOneHour=60*millsecInOneMinute; let millsecInOneDay=24*millsecInOneHour;

Теперь берем timePassedInMilliseconds с момента публикации и считаем прошедшие дни, часы и минуты.

Мы можем вычислить unitOfTimePassed по таймфрейму/millsecInTimeframe, тогда мы можем Math.floor UnitsOfTimePassed показать только единицу, а не ее дробную часть.

let unitsOfTimePassed; let timePassedString; let daysPassed = timePassedInMilliseconds/millsecInOneDay; let hoursPassed = timePassedInMilliseconds/millisecInOneHour; let minPassed = timePassedInMilliseconds/millisecInOneMin; let secPassed = timePassedInMilliseconds/millisecInOneSec; let unitTypes=['day','hour','minute','second'] let displayUnitType; if(daysPassed>1){ unitsOfTimePassed = Math.floor(daysPassed) displayUnitType=unitTypes[0] } else if(hoursPassed>1){ unitsOfTimePassed = Math.floor(hoursPassed) displayUnitType=unitTypes[1] } else if(minPassed>1){ unitsOfTimePassed = Math.floor(minPassed) displayUnitType=unitTypes[2] } else{ unitsOfTimePassed = Math.floor(secPassed) displayUnitType=unitTypes[3] }

Теперь, когда у нас есть unitsOfTimePassed, мы можем создать нашу строку относительного времени. Для этого мы будем использовать Intl API. В частности, Intl.RelativeTimeFormat.

Что такое международный API??

Давайте узнаем, что такое Intl (интернационализация),

Согласно MDN это

Объект пространства имен Intl содержит несколько конструкторов, а также функции, общие для конструкторов интернационализации и других функций, зависящих от языка. В совокупности они составляют API-интерфейс интернационализации ECMAScript, который обеспечивает сравнение строк с учетом языка, форматирование чисел, форматирование даты и времени и многое другое.

Проще говоря, он предоставляет правильные строки для таких единиц, как (дата, время, число и количество), которые совместимы с разными языками и стилями письма в разных регионах.

Eg :

У нас может быть новостной веб-сайт, на котором мы показываем даты новостей в разных регионах на разных языках, для этого мы можем использовать Intl.DateTimeFormat.

Обратите внимание, что в первом журнале мы использовали locale как 'en-US', поэтому в нем используется дата в американском стиле. А во втором журнале у нас есть 'hi', что на хинди. Что делает дату в формате индийского хинди. В дате сначала идет день (19), а затем месяц, потому что это стиль, которому следует хинди, а в 'en-US' месяц (май) идет первым.

Есть много других способов использования intl API, таких как Intl.Collator, Intl.ListFormat, Intl.NumberFormat, Intl.PluralRules и т.д.

Использование Intl API для скрытия времени, перешедшего в относительное время

Мы будем использовать Intl.RelativeTimeFormat, чтобы получить строку относительного времени для времени, прошедшего с момента публикации сообщения.

Мы уже знаем unitsOfTimePassed и displayUnitType, поэтому мы можем получить строку:

Мы настраиваем Intl.RelativeTimeFormat и locales в соответствии с нашими потребностями.

const displayString = rtf.format(-1 * unitsOfTimePassed,displayUnitType );

Мы ставим -1, чтобы сообщить rtf, что время прошло. Чтобы показать предстоящую дату, мы можем поставить +1.

Теперь мы можем использовать отображаемую строку в сообщении, чтобы показать пользователю относительное время с момента публикации сообщения.

ЕСЛИ ВАМ ПОНРАВИЛСЯ ПОСТ, ПОДЕЛИТЕСЬ ЕГО 😄.

Первоначально опубликовано на https://ghosty.hashnode.dev.