Skip to content

Date Utils ​

Central Design System includes a set of functions for working with the native JS Date: mask-based formatting, string parsing, arithmetic, comparison and calendar math. You don't need a separate date library (dayjs, date-fns) for everyday tasks. The date and time components use the very same functions — CdsDateInput, CdsDatePicker, CdsTimePicker — so format masks are identical in the utilities and in the components.

The functions accept a Date, a timestamp (milliseconds) or a date string, return a native Date and never mutate the arguments you pass — the result is always a new object.

Setup ​

The utilities are exported from the package under the utils namespace:

ts
import { utils } from '@central-design-system/components';

const { formatDate, addToDate } = utils;

formatDate(new Date(2026, 7, 18), 'DD.MM.YYYY'); // '18.08.2026'

Formatting — formatDate ​

formatDate(value, mask, dateLocale?) turns a date into a string using a mask:

ts
const { formatDate } = utils;

formatDate(new Date(2026, 7, 18, 14, 30), 'DD.MM.YYYY HH:mm'); // '18.08.2026 14:30'
formatDate(Date.now(), 'D MMM YYYY'); // '18 Авг 2026'
formatDate(new Date(2026, 7, 18), 'dddd'); // 'Вторник'

Without a mask, an ISO-like format is used: YYYY-MM-DDTHH:mm:ss.SSSZ. For an invalid value the function returns undefined.

Month and weekday names come from the Russian date locale by default. To print them in another language, pass a date locale as the third argument — the built-in ones live in the locales export:

ts
import { locales, utils } from '@central-design-system/components';

utils.formatDate(new Date(2026, 7, 18), 'dddd, D MMMM', locales.enDate);
// 'Tuesday, 18 August'

Your own language is plugged in as a TDateLocale object — the same fields as locales.ruDate. See the Internationalization guide for more on date locales.

Format tokens ​

UnitTokenResult
YearYY / YYYY26 / 2026
MonthM / MM8 / 08
Month (name)MMM / MMMMАвг / Август
QuarterQ / Qo3 / 3rd
Day of monthD / Do / DD18 / 18th / 18
Day of yearDDD / DDDD230 / 230 (zero-padded to 3 digits)
Day of weekd2 (0 — Sunday)
Day of week (name)dd / ddd / ddddВт / Вт / Вторник
Day of week (ISO)E2 (1 — Monday, 7 — Sunday)
Week of yearw / ww34 / 34
Hour (0–23)H / HH14 / 14
Hour (1–12)h / hh2 / 02
Minutem / mm30 / 30
Seconds / ss5 / 05
Fractions of a secondS / SS / SSS1 / 12 / 123
Time zoneZ / ZZ+03:00 / +0300
MeridiemA / a / aaPM / pm / p.m.
Unix timeX / xseconds / milliseconds

Ordinal suffixes (Do, Qo) are English (1st, 2nd…) regardless of the locale.

Arbitrary text inside a mask is escaped with square brackets:

ts
formatDate(new Date(2026, 7, 18), '[Сегодня] DD.MM'); // 'Сегодня 18.08'

Parsing — extractDate and splitDate ​

extractDate(str, mask, dateLocale?) parses a string with a mask and returns a Date:

ts
const { extractDate } = utils;

extractDate('21.03.1985', 'DD.MM.YYYY'); // Date: 21 March 1985
extractDate('2019-10-29 23:12', 'YYYY-MM-DD HH:mm'); // Date: 29 October 2019, 23:12

Month and day names inside the string are recognized through the date locale — Russian by default, just like in formatDate.

A non-existent day overflows following the rules of the native Date: extractDate('30.02.2024', 'DD.MM.YYYY') gives 1 March 2024. When you need strict input validation, format the result back and compare it with the string:

ts
const strict = (str: string, mask: string) => formatDate(extractDate(str, mask), mask) === str;

strict('18.08.2026', 'DD.MM.YYYY'); // true
strict('30.02.2024', 'DD.MM.YYYY'); // false — overflowed into 01.03.2024

If you don't need a Date, splitDate(str, mask, dateLocale?) splits the string into its parts — an IRawDate object with the fields year, month, day, hour, minute, second, millisecond (anything not found is null):

ts
const { splitDate } = utils;

splitDate('18.08.2026', 'DD.MM.YYYY');
// { year: 2026, month: 8, day: 18, hour: null, … }

Creating and changing ​

buildDate ​

buildDate(modified, utc?) — the current moment with individual parts replaced. Handy when you need "now, but at 15:00" or "today, but in 2010":

ts
const { buildDate } = utils;

buildDate({ year: 2010, day: 5, hour: 15 });
// current month, minutes and seconds; year 2010, day 5, hour 15

Supported object fields: year, month (1–12), day (or date), hour, minute, second, millisecond.

adjustDate ​

adjustDate(date, modified, utc?) — the same thing, but for an arbitrary date:

ts
const { adjustDate } = utils;

adjustDate(new Date(2026, 10, 2), { year: 2010, month: 2 });
// Date: 2 February 2010

Note that month here is 1-based (February is 2), unlike in the Date constructor.

addToDate / subtractFromDate ​

Add and subtract intervals. The object fields are the same, but they mean "how much to add" rather than "what to set":

ts
const { addToDate, subtractFromDate } = utils;

addToDate(new Date(2026, 2, 7), { day: 7, month: 1 }); // Date: 14 April 2026
subtractFromDate(new Date(2026, 2, 7), { hour: 24 }); // Date: 6 March 2026

startOfDate / endOfDate ​

The start and the end of a period — year, month, day, hour, minute or second:

ts
const { startOfDate, endOfDate } = utils;

startOfDate(new Date(2026, 7, 18, 14, 30), 'year'); // Date: 1 January 2026, 00:00:00.000
endOfDate(new Date(2026, 7, 18, 14, 30), 'month'); // Date: 31 August 2026, 23:59:59.999

Period unit: 'year', 'month', 'day', 'hour', 'minute', 'second' (the plural form is accepted too).

Comparison and ranges ​

isSameDate ​

Compares dates down to a unit: 'year' — the year only, 'month' — month and year, 'day' — the calendar day, and so on. Without a unit, the timestamps are compared in full.

ts
const { isSameDate } = utils;

isSameDate(new Date(2026, 7, 1), new Date(2026, 7, 30), 'month'); // true
isSameDate(new Date(2026, 7, 1), new Date(2026, 7, 30), 'day'); // false

getDateDiff ​

The difference between two dates in the chosen unit (days by default):

ts
const { getDateDiff } = utils;

getDateDiff(new Date(2026, 4, 12), new Date(2026, 3, 8)); // 34 (days)
getDateDiff(new Date(2026, 4, 12), new Date(2026, 3, 8), 'months'); // 1

isBetweenDates / getDateBetween ​

isBetweenDates(date, from, to, opts?) checks whether a date falls inside a range. The bounds are excluded by default; the inclusiveFrom and inclusiveTo options include them, and onlyDate: true compares calendar days only, ignoring the time:

ts
const { isBetweenDates } = utils;

isBetweenDates(date, from, to); // strict range
isBetweenDates(date, from, to, { inclusiveFrom: true, inclusiveTo: true, onlyDate: true });

getDateBetween(date, min, max) clamps a date to a range: it returns the date itself if it is inside, otherwise the nearest bound:

ts
const { getDateBetween } = utils;

getDateBetween(new Date(2025, 0, 1), new Date(2026, 0, 1), new Date(2026, 11, 31));
// Date: 1 January 2026 — the date is below the minimum, so the min bound came back

getMinDate / getMaxDate ​

The smallest and the largest of a set of dates. They return a timestamp (number) — wrap it in new Date() if you need a date object:

ts
const { getMinDate, getMaxDate } = utils;

const min = getMinDate(new Date(2026, 6, 24), new Date(2026, 5, 20), new Date(2026, 6, 26));
new Date(min); // Date: 20 June 2026

const dates = [/* Date[] */];
const max = getMaxDate(dates[0], ...dates.slice(1));

Calendar ​

ts
const { getDayOfWeek, getWeekOfYear, getDayOfYear, daysInMonth } = utils;

getDayOfWeek(new Date(2026, 7, 16)); // 7 — Sunday (ISO: 1 — Monday)
getWeekOfYear(new Date(2026, 0, 4)); // 1 — ISO week number in the year
getDayOfYear(new Date(2026, 1, 4)); // 35 — ordinal day in the year
daysInMonth(new Date(2024, 1, 15)); // 29 — February of a leap year

Other ​

isValidDate ​

Checks whether a value parses into a date:

ts
const { isValidDate } = utils;

isValidDate('2026-08-18'); // true
isValidDate('не дата'); // false

The check is syntactic — it does not catch non-existent calendar days (see splitDate above).

cloneDate ​

A copy of a date. Useful before handing it to third-party code that might mutate the object (CDS utilities themselves never modify their arguments):

ts
const { cloneDate } = utils;

const copy = cloneDate(original);

inferDateFormat ​

Detects the shape of a value — handy for returning the result in the same form the value came in:

ts
const { inferDateFormat } = utils;

inferDateFormat(new Date()); // 'date'
inferDateFormat(1787059805000); // 'number'
inferDateFormat('18.08.2026'); // 'string'