это подтема Создайте веб-сайт, призывающий к демократии в Таиланде, с помощью Svelte и Azure Static Web Apps »

Причина перехода с объектов JS Date

Когда я смотрю на код, он настолько сбивает с толку, что мне нужно постоянно увеличивать значение месяца на единицу, прежде чем я смогу перевести его в фактический месяц. Эта концепция неестественна, по крайней мере, для меня. Посмотрите на пример ниже: Джатупат Бунпатракса, он же« Пай Дао Дин » был заключен в тюрьму 8 марта 2021 года и освобожден под залог 23 апреля 2021 года.

  • _1 _ = ›значение месяца равно 2 =› увеличение на 1 = ›8 марта 2021 г.
  • _2 _ = ›значение месяца 3 =› увеличение на 4 = ›23 апреля 2021 г.

Но!! Вместо того, чтобы передавать значения компонентов даты в new Date() constructor, я могу создать объект Date с типом данных dateString.

  • new Date(2021, 2, 8) = new Date('8 Mar 2021') = new Date('2021-03-08') и
  • new Date(2021, 3, 23) = new Date('23 Apr 2021') = new Date('2021-04-23')

Это более понятно. Но опять же !! Из MDN Web Docs, парсинг строк даты, например '23 Apr 2021'или '2021-04-23' с Date конструктором настоятельно не рекомендуется из-за различий и несоответствий браузеров.

Еще одна проблема - отсутствие методик, поддерживающих некоторые общие операции. См. Пример ниже, следующая функция должна вручную рассчитать разницу дат путем ручного вычитания между двумя датами (в значении эпохи) и деления ее на количество миллисекунд в дне, которое также вычисляется вручную.

const DAYS_IN_MS = 24 * 60 * 60 * 1000;
function getNumberOfDaysUnderDetained(
  detainedDate,
  releasedDate = todayDate
) {
  return Math.floor((releasedDate - detainedDate) / DAYS_IN_MS);
}

Это только две из болевых точек. Что еще? Отсюда видно мотивацию отойти от Date.

Альтернативы

Использование библиотек

Luxon, Day.js, date-fns, js-Joda
Обратите внимание, что я не поместил здесь Moment.js по какой-то причине - Moment.js готов - команда проекта не будет добавлять какие-либо новые функции или возможности, не будет решать проблему размера пакета, не изменит свой API на неизменный, не будет вносить никаких серьезных изменений и решит только критические проблемы безопасности. Команда проекта не рекомендует использовать Moment.js в новых проектах.

Временный

Будущее уже наступило! (вероятно, НЕТ ЕЩЕ, но скоро !!)

Temporal - это новые API-интерфейсы даты и времени, реализованные на языке JavaScript. Это избавит от необходимости использовать сторонние библиотеки и заменит Дата в качестве API для работы с датой и временем в JavaScript. В настоящее время Temporal находится на этапе 3 процесса TC39.

Примечание: поскольку Temporal находится на этапе 3, его API может быть изменен. НЕ рекомендуется использовать в производственной среде.

Выполнение

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

Чтобы узнать больше о том, как работать с Temporal, ознакомьтесь с Temporal Cookbook.

  1. Сначала установите proposal-temporal зависимость
$ npm install --save proposal-temporal

2. Импортируйте proposal-temporal polyfill как модуль ES6 в файл App.svelte.

import { Temporal } from 'proposal-temporal/lib/index.mjs';

3. Получите объект Temporal.PlainDate, представляющий текущую дату в системном часовом поясе и календаре ISO-8601, и сохраните его в переменной todayDate.

const todayDate = Temporal.now.plainDateISO();

4. Создайте объект aTemporal.PlainDate с помощью статического метода Temporal.PlainDate.from, принимающего значение, представляющее желаемую дату. Метод возвращает новый объект Temporal.PlainDate, представляющий календарную дату, которая не связана с определенным временем или часовым поясом, например. 8 марта 2021 года в этом случае.

Temporal.PlainDate.from({ year: 2021, month: 3, day: 8 }),

5. Вычислите разницу между двумя датами (detainedDate иreleasedDate в примере ниже) с помощью date.until(other, options) и верните его как объект Temporal.Duration. Объект options предоставляет свойство largestUnit, управляющее выражением итоговой длительности; например, разница в два года превратится в 24 месяца, когда largestUnit = "months". Однако разница в два месяца все равно будет два месяца, даже если largestUnit равно "years"

detainedDate.until(releasedDate, { largestUnit: 'days' }).days;

6. Соберите все вместе, финальный файл будет выглядеть так:

<script>
//import the polyfill as an ES6 module
import { Temporal } from 'proposal-temporal/lib/index.mjs';
//get the current date in the system time zone and ISO-8601 calendar
const todayDate = Temporal.now.plainDateISO();
const people = [
{
  name: `Jatupat 'Pai Dao Din' Boonpatraksa`,
  nickname: 'pai',
  //A Temporal.PlainDate object represents March 8th, 2021 date
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 8 }),
  //A Temporal.PlainDate object represents April 23rd, 2021 date 
  releasedDate: Temporal.PlainDate.from({ year: 2021, month: 4, day: 23 }),
},
{
  name: `Parit 'Penguin' Chiwarak`,
  nickname: 'penguin',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 2, day: 9 }),
},
{
  name: `Panupong 'Mike' Jadnok`,
  nickname: 'mike',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 8 }),
},
{
  name: `Somyot Pruksakasemsuk`,
  nickname: 'somyot',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 2, day: 9 }),
  releasedDate: Temporal.PlainDate.from({ year: 2021, month: 4, day: 23 }),
},
{
  name: `Arnon Nampa`,
  nickname: 'arnon',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 2, day: 9 }),
},
{
  name: `Patiwat Saraiyaem, 'Mor Lam Bank'`,
  nickname: 'bank',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 2, day: 9 }),
  releasedDate: Temporal.PlainDate.from({ year: 2021, month: 4, day: 9 }),
},
{
  name: `Panusaya Sithijirawattanakul`,
  nickname: 'rung',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 8 }),
},
{
  name: `Chaiamorn 'Ammy' Kaewwiboonpan`,
  nickname: 'ammy',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 4 }),
},
{
  name: `Parinya Cheewin Kulpathom aka 'Port Faiyen'`,
  nickname: 'port',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 6 }),
},
{
  name: `Piyarat 'Toto' Jongthep`,
  nickname: 'toto',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 6 }),
  releasedDate: Temporal.PlainDate.from({ year: 2021, month: 5, day: 5 }),
},
{
  name: `Promsorn 'Fah' Veerathamjaree`,
  nickname: 'fah',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 17 }),
},
{
  name: `Chookiat 'Justin' Saengwong`,
  nickname: 'justin',
  detainedDate: Temporal.PlainDate.from({ year: 2021, month: 3, day: 23 }),
}]
/*until method computes the difference between the two dates
the largestUnit option controls how the resulting duration is expressed. The returned Temporal.Duration object will not have any nonzero fields that are larger than the unit in largestUnit. A difference of two years will become 24 months when largestUnit is "months", for example. However, a difference of two months will still be two months even if largestUnit is "years"*/
function getNumberOfDaysUnderDetained(detainedDate, releasedDate = todayDate) {
  return detainedDate.until(releasedDate, { largestUnit: 'days' }).days;
}
</script>
<main>...
<style>...

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

Ссылка