Содержит всё необходимое и не раздувает бандл.
- Иммутабельные и чистые функции. Каждая из них хранится в отдельном файле, не содержит сайд-эффектов, не мутирует параметры. При импорте функции в бандл добавляется только то, что необходимо для её работы, и ничего более.
- ESM & CommonJS. Работает c Node.js и в браузере. Настройте самостоятельно список поддерживаемых браузеров для транспиляции ES6, чтобы получить минимальный набор полифиллов.
- TypeScript. Каждая функция типизирована, и все типы поставляются вместе с пакетом.
- Нативное АПИ. Использует
Date
иIntl
под капотом. - Только русская локаль. Чтобы не добавлять ничего лишнего.
Давным-давно, когда мы начинали разрабатывать наши фронтенд-проекты, мы выбрали самую популярную на тот момент библиотеку для работы с датами. Мы использовали всего несколько методов, которые она предоставляла, но в бандл попали все существующие в ней, а в довесок и все имеющиеся локали.
Тогда мы настроили конфиги бандлера таким обарзом, чтобы он вырезал эти локали. Однако, та библиотека всё ещё была самой большой из тех, что мы использовали, но пользы от неё было совсем немного. Мы попробовали поискать библиотеку, которая бы решала необходимые нам задачи, и при этом была бы небольшой и с удобным АПИ, но таковых не нашлось.
Потому мы просто написали несколько небольших функций, которые делали дело. А со временем этот набор функций разросся и превратился в Хроноса — простую, но удобную библиотеку для работы с датами, которая работает в каждом нашем проекте.
- Установка и использование
- Типы
- Функции
- addMinutes
- addHours
- addDays
- addMonths
- addCalendarMonths
- addYears
- subtractMinutes
- subtractHours
- subtractDays
- subtractMonths
- subtractCalendarMonths
- subtractYears
- formatDate
- formatTimeString
- getMinutes
- getHours
- getDay
- getMonth
- getYear
- getWeekdayName
- getMonthName
- getDuration
- isSameMinute
- isSameHour
- isSameDay
- isSameMonth
- isSameYear
- getDiffInMinutes
- getDiffInHours
- getDiffInDays
- getDiffInCalendarDays
- getDiffInMonths
- getDiffInCalendarMonths
- getDiffInYears
- getDiffInCalendarYears
- getStartOfMinutes
- getStartOfHours
- getStartOfDay
- getStartOfWeek
- getStartOfMonth
- getStartOfYear
- getStartOfDecade
- getEndOfMinutes
- getEndOfHours
- getEndOfDay
- getEndOfWeek
- getEndOfMonth
- getEndOfYear
- getEndOfDecade
- getRelativeDate
- getUtcOffset
- getUnixTimestamp
- getTimezoneName
- isTimeValid
- parseDate
- Благодарности
Добавить пакет в зависимости проекта:
npm install --save @funboxteam/chronos
Импортировать необходимые функции в JS:
import { addDate } from '@funboxteam/chronos';
Библиотека экспортирует несколько типов, доступных для использования где угодно. Но, что более важно, они используются внутри для обеспечения одинакового поведения функций.
declare type ChronosDate = Date | number | string;
Каждая функция, которая принимает дату в качестве первого параметра, ожидает получить или инстанс Date
,
или временную метку в виде строки или числа.
Временная метка может быть выражена как в секундах, так и в миллисекундах (т. е. 1596803254000
и 1596803254
— одно и то же значение).
declare type Duration = {
days: number;
hours: number;
minutes: number;
seconds: number;
};
Тип, описывающий возвращаемое значение функций, которые работают временными интервалами.
Каждая функция иммутабельна, а потому если передать в них инстанс Date
, они всегда вернут новый инстанс Date
,
и не будут изменять переданный.
(value: ChronosDate, quantity: number) => Date;
value
, дата;quantity
, количество единиц, которые нужно добавить.
addDays(new Date('2020-01-01T00:00:00.000Z'), 1); // 2020-01-02T00:00:00.000Z
// 1577836800 — это 2020-01-01T00:00:00.000Z
addYears(1577836800, 1); // 2021-01-01T00:00:00.000Z
addMonths(new Date(2020, 0, 1), 1); // == new Date(2020, 1, 1);
addMonths(new Date(2020, 0, 31), 1); // == new Date(2020, 2, 2);
addCalendarMonths(new Date(2020, 0, 1), 1); // == new Date(2020, 1, 1);
addCalendarMonths(new Date(2020, 0, 31), 1); // == new Date(2020, 1, 29);
(value: ChronosDate, quantity: number) => Date;
value
, дата;quantity
, количество единиц, которые нужно вычесть.
subtractDays(new Date('2020-01-01T00:00:00.000Z'), 1); // 2019-12-31T00:00:00.000Z
// 1577836800 — это 2020-01-01T00:00:00.000Z
subtractYears(1577836800, 1); // 2019-01-01T00:00:00.000Z
subtractMonths(new Date(2020, 0, 1), 1); // == new Date(2019, 11, 1);
subtractMonths(new Date(2020, 2, 31), 1); // == new Date(2020, 2, 2);
subtractCalendarMonths(new Date(2020, 0, 1), 1); // == new Date(2019, 11, 1);
subtractCalendarMonths(new Date(2020, 2, 31), 1); // == new Date(2020, 1, 29);
(value: ChronosDate, format: string) => string;
value
, дата;format
, желаемый формат.
Тип | Ключ | Значение |
---|---|---|
Секунды | ss |
00, 01, 02, ..., 57, 58, 59 |
Минуты | mm |
00, 01, 02, ..., 57, 58, 59 |
Часы | HH |
00, 01, 02, ..., 21, 22, 23 |
Дни недели | dddd |
понедельник, вторник, ..., суббота, воскресенье |
Дни месяца | DD |
01, 02, 03, ..., 29, 30, 31 |
D |
1, 2, 3, ..., 29, 30, 31 | |
Месяцы | MMMM |
январь, февраль, ..., ноябрь, декабрь |
MMM |
янв, фев, ..., ноя, дек | |
MM |
01, 02, 03, ..., 10, 11, 12 | |
Годы | YYYY |
Полный год, т. е.: 1885, 1955, 1985, 2015 |
YY |
00, 01, 02, ..., 97, 98, 99 | |
Смещение | ZZ |
-1200, -1100, ..., +1300, +1400 |
Z |
-12:00, -11:00, ..., +13:00, +14:00 |
formatDate(new Date(2020, 0, 1), 'YYYY-MM-DDTHH:mm:ssZ'); // '2020-01-01T00:00:00+03:00' (для GMT+3)
// 1577836800 — это 2020-01-01T00:00:00.000Z
formatDate(1577836800, 'HH:mm:ss'); // '03:00:00' (для GMT+3)
На текущий момент поддерживается только русская локаль!
(value: string, valueFormat: string, format: string) => string;
value
, время;valueFormat
, шаблон, описывающий форматvalue
;format
, желаемый формат.
Тип | Ключ | Значение |
---|---|---|
Секунды | ss |
00, 01, 02, ..., 57, 58, 59 |
Минуты | mm |
00, 01, 02, ..., 57, 58, 59 |
Часы | HH |
00, 01, 02, ..., 21, 22, 23 |
H |
0, 1, 2, ..., 21, 22, 23 |
formatTime('22:00', 'HH:mm', 'HH:mm:ss'); // '22:00:00'
(value: ChronosDate) => number;
value
, дата.
getDay(new Date(2020, 0, 1)); // 1;
// 1577836800 — это 2020-01-01T00:00:00.000Z
getYear(1577836800); // 2020
(value: ChronosDate, format?: string) => string;
value
, дата;format
, формат возвращаемой строки. По умолчанию длинный ('long'
), может быть короткий ('short'
).
getWeekdayName(new Date(2020, 11, 30)); // 'среда' (11-й месяц в JS — это декабрь)
getWeekdayName(new Date(2020, 11, 30), 'short'); // 'ср'
getMonthName(new Date(2020, 0, 1)); // 'январь'
getMonthName(new Date(2020, 0, 1), 'short'); // 'янв'
(seconds: number) => Duration;
seconds
, интервал времени в секундах.
getDuration(1000000); // { days: 11, hours: 13, minutes: 46, seconds: 40 }
(firstValue: ChronosDate, secondValue: ChronosDate) => boolean;
firstDate
, дата;secondDate
, дата.
// 1577750400 — это 2019-12-31T00:00:00.000Z
// 1577836800 — это 2020-01-01T00:00:00.000Z
isSameYear(1577750400, 1577836800); // false
getDiffInMinutes, getDiffInHours, getDiffInDays, getDiffInCalendarDays, getDiffInMonths, getDiffInCalendarMonths, getDiffInYears, getDiffInCalendarYears
(firstValue: ChronosDate, secondValue: ChronosDate) => number;
firstDate
, дата;secondDate
, дата.
// 1577750400 — это 2019-12-31T00:00:00.000Z
// 1577836800 — это 2020-01-01T00:00:00.000Z
getDiffInDays(1577750400, 1577836800); // -1
getStartOfMinutes, getStartOfHours, getStartOfDay, getStartOfWeek, getStartOfMonth, getStartOfYear, getStartOfDecade
(value: ChronosDate, diff?: number) => Date;
value
, дата;diff
, количество единиц, которые нужно добавить в итоговой дате. По умолчанию0
.
// 1577836800 — это 2020-01-01T00:00:00.000Z
getStartOfDay(1577836800); // 2019-12-31T21:00:00.000Z (для GMT+3)
getStartOfDay(1577836800, 1); // 2020-01-01T21:00:00.000Z (для GMT+3)
getStartOfDay(1577836800, -1); // 2019-12-30T21:00:00.000Z (для GMT+3)
getEndOfMinutes, getEndOfHours, getEndOfDay, getEndOfWeek, getEndOfMonth, getEndOfYear, getEndOfDecade
(value: ChronosDate, diff?: number) => Date;
value
, дата;diff
, количество единиц, которые нужно добавить в итоговой дате. По умолчанию0
.
// 1577836800 — это 2020-01-01T00:00:00.000Z
getEndOfDay(1577836800); // 2020-01-01T20:59:59.999Z (для GMT+3)
getEndOfDay(1577836800, 1); // 2020-01-02T20:59:59.999Z (для GMT+3)
getEndOfDay(1577836800, -1); // 2019-12-31T20:59:59.999Z (для GMT+3)
(value: ChronosDate) => string;
value
, дата.
getRelativeDate(1577081613); // '2 месяца' (для 07.02.2020)
getRelativeDate(new Date()); // 'меньше минуты'
(value: ChronosDate) => number;
value
, дата.
getUtcOffset(new Date(2020, 0, 1)); // 3 (для GMT+3)
(value?: ChronosDate) => number;
date
, объект Date. По умолчаниюnew Date()
.
// сейчас 2020-02-07T08:26:59.422Z
getUnixTimestamp(); // 1581064019 (unixtime от new Date())
getUnixTimestamp(new Date(2020, 0, 1)); // 1577826000 (для GMT+3)
() => string;
getTimezoneName(); // 'Europe/Moscow' (для GMT+3 в ИЕ11 и для MSK в новых браузерах)
В случае отсутствия поддержки Intl API в текущем браузере, будет возвращена ближайшая к пользователю таймзона, смещение которое выражено целым числом часов.
(value: string, format: string) => boolean;
value
, строка с временем;format
, строка с форматом, который нужно использовать для валидации.
isTimeValid('22:30', 'HH:mm'); // true
(value: string, format: string) => Date;
value
, строка с датой;format
, строка с форматом, который нужно использовать для парсинга.
Тип | Ключ | Распознаваемые значения |
---|---|---|
День месяца | DD |
01, 02, 03, ..., 29, 30, 31 |
D |
1, 2, 3, ..., 29, 30, 31 | |
Месяц | MM |
01, 02, 03, ..., 10, 11, 12 |
Год | YYYY |
Full year, e.g.: 1885, 1955, 1985, 2015 |
YY |
00, 01, 02, ..., 97, 98, 99 |
parseDate('2000-01-21', 'YYYY-MM-DD'); // == new Date(2000, 0, 21)
parseDate('2020-01-01T00:00:00+03:00'); // == new Date(2020, 0, 1) (для GMT+3)
Если format
не передан, то функция пытается распарсить value
используя встроенный Date.parse
.
Теоретически он поддерживает ISO 8691 и RFC 2822. Другие форматы не рекомендуется парсить без явного указания format
.
Картинки для репозитория нарисовал Игорь Гарибальди.