Дата в JavaScript — это объект Date, который хранит один момент времени как число миллисекунд от 1 января 1970 года 00:00 UTC. Дата в 1С — примитивный тип Дата: календарная дата и время с точностью до секунды, без часового пояса. Из-за этой разницы одни и те же задачи (вывести дату строкой, прибавить месяц, посчитать дни) решаются по-разному.
Содержание
Ниже — создание даты, форматирование, арифметика и типичные ошибки сначала в JavaScript, потом в 1С. Примеры JavaScript проверены в Node.js 24 (24.21.0) 23 сентября 2026 года; в современных браузерах Date и Intl ведут себя так же.
Три термина, которые важно не путать:
- момент времени (timestamp) — точка на оси времени, одинаковая для всех на планете;
- часовой пояс — правило вроде
Europe/Moscow, которое переводит момент в местные часы, с учетом летнего времени, если оно есть; - смещение — конкретная разница с UTC в данный момент, например
+03:00. Один пояс может иметь разное смещение зимой и летом.
Дата в JavaScript: один момент, разные представления
Минимальный полный пример — один объект Date и пять способов его показать:
// Один и тот же момент времени в разных представлениях
const d = new Date(Date.UTC(2026, 8, 23, 7, 30)); // месяц 8 = сентябрь
console.log(d.getTime()); // миллисекунды от 1970-01-01T00:00:00Z
console.log(d.toISOString()); // всегда UTC
console.log(d.getHours()); // часы в поясе, где запущен код
console.log(d.toLocaleString("ru-RU", { timeZone: "Europe/Moscow" }));
console.log(d.toLocaleString("ru-RU", { timeZone: "Asia/Vladivostok" }));
Вывод при запуске с TZ=Europe/Moscow:
1790148600000
2026-09-23T07:30:00.000Z
10
23.09.2026, 10:30:00
23.09.2026, 17:30:00
Число и ISO-строка не зависят от того, где запущен код. А getHours() зависит: в Москве он вернет 10, с TZ=America/New_York — 3, с TZ=Europe/Berlin — 9. Все методы get... без UTC в имени (кроме getTime()) считают в часовом поясе среды: у браузера это пояс компьютера пользователя, у сервера — пояс процесса.
Если нужен конкретный пояс, передавайте timeZone в toLocaleString или Intl.DateTimeFormat, а не рассчитывайте на настройки машины.
Как создать дату: четыре способа
| Способ | Пример | Что важно |
|---|---|---|
| Текущий момент | new Date() или Date.now() |
Date.now() возвращает число, а не объект |
| Миллисекунды | new Date(1790148600000) |
отсчет от 1970-01-01 UTC |
| Строка | new Date("2026-09-23T10:30:00+03:00") |
надежен только формат ISO 8601 |
| Компоненты | new Date(2026, 8, 23, 10, 30) |
месяц с 0, время местное |
Ошибка 1: месяц считается с нуля
const wrong = new Date(2026, 9, 23); // хотели 23 сентября
console.log(wrong.toDateString());
const right = new Date(2026, 8, 23); // месяц считается с 0
console.log(right.toDateString());
console.log(right.getMonth() + 1); // номер месяца для людей
Fri Oct 23 2026
Wed Sep 23 2026
9
Январь — 0, декабрь — 11. День месяца при этом считается с 1, а getDay() возвращает день недели, где 0 — воскресенье. Путаница getDate() и getDay() — еще одна частая ошибка рядом с номером месяца.
Ошибка 2: строка без времени читается как UTC
const a = new Date("2026-09-23"); // только дата -> полночь UTC
const b = new Date("2026-09-23T00:00"); // дата и время без пояса -> местное время
console.log(a.getDate(), b.getDate());
const c = new Date("23.09.2026"); // не формат ISO
console.log(c.toString(), Number.isNaN(c.getTime()));
С TZ=America/New_York первая строка выводит 22 23: полночь UTC в Нью-Йорке — это еще вечер 22 сентября. В Москве обе даты дают 23, поэтому ошибку легко не заметить на своей машине. Вторая строка во всех поясах выводит Invalid Date true.
Правило: строки с датой разбирайте только в формате ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ или со смещением +03:00). Для других форматов результат зависит от движка, а Invalid Date не бросает исключение — его нужно проверять через Number.isNaN(d.getTime()).
Арифметика дат в JavaScript
Прибавить месяц без переполнения
Методы set... переносят лишнее в следующий разряд. Это удобно для дней (d.setDate(d.getDate() + 10) корректно перейдет через конец месяца), но с месяцами дает сюрприз:
const d = new Date(2026, 0, 31); // 31 января
d.setMonth(d.getMonth() + 1); // "плюс месяц"
console.log(d.toDateString());
function addMonths(date, n) {
const r = new Date(date);
const day = r.getDate();
r.setDate(1); // уходим от переполнения
r.setMonth(r.getMonth() + n);
const last = new Date(r.getFullYear(), r.getMonth() + 1, 0).getDate();
r.setDate(Math.min(day, last)); // последний день, если такого числа нет
return r;
}
console.log(addMonths(new Date(2026, 0, 31), 1).toDateString());
console.log(addMonths(new Date(2028, 0, 31), 1).toDateString());
Tue Mar 03 2026
Sat Feb 28 2026
Tue Feb 29 2028
31 февраля не существует, и setMonth превращает его в 3 марта. Функция addMonths прижимает дату к последнему дню месяца — так ведут себя большинство бизнес-правил («оплата через месяц»). Прием new Date(год, месяц + 1, 0) дает последний день месяца: нулевой день следующего месяца.
Разница в днях и переход на летнее время
const from = new Date(2026, 2, 28); // 28 марта, местная полночь
const to = new Date(2026, 2, 30); // 30 марта
const DAY = 24 * 60 * 60 * 1000;
console.log((to - from) / DAY);
console.log(Math.floor((to - from) / DAY));
// Календарные дни считаем через UTC: переходов на летнее время там нет
const utcDays = (x, y) =>
(Date.UTC(y.getFullYear(), y.getMonth(), y.getDate()) -
Date.UTC(x.getFullYear(), x.getMonth(), x.getDate())) / DAY;
console.log(utcDays(from, to));
С TZ=Europe/Berlin вывод 1.9583333333333333, 1, 2: 29 марта 2026 года в Европе переводят часы, в сутках 23 часа, и наивное деление теряет день. В Москве летнего времени нет, и все три строки дают 2, поэтому такой баг всплывает только у части пользователей. Вычитание дат дает миллисекунды между моментами, а календарные дни надо считать отдельно.
Как вывести дату строкой в JavaScript
| Метод | Результат | Когда брать |
|---|---|---|
toISOString() |
2026-09-23T07:30:00.000Z |
обмен с сервером, JSON, логи |
toLocaleDateString("ru-RU", opts) |
23.09.2026 |
показать пользователю |
Intl.DateTimeFormat |
форматтер с поясом и локалью | много дат в одном формате |
toString(), toDateString() |
Wed Sep 23 2026 10:30:00 GMT+0300 (...): всегда по-английски, в поясе среды |
отладка, не интерфейс |
const d = new Date(Date.UTC(2026, 8, 23, 7, 5));
console.log(d.toLocaleDateString("ru-RU", { timeZone: "Europe/Moscow" }));
console.log(d.toLocaleDateString("ru-RU", {
timeZone: "Europe/Moscow", day: "numeric", month: "long", year: "numeric",
}));
const fmt = new Intl.DateTimeFormat("ru-RU", {
timeZone: "Europe/Moscow",
year: "numeric", month: "2-digit", day: "2-digit",
hour: "2-digit", minute: "2-digit",
});
console.log(fmt.format(d));
// Свой шаблон "ГГГГ-ММ-ДД ЧЧ:ММ" из частей, а не склейкой get-методов
const p = Object.fromEntries(fmt.formatToParts(d).map(x => [x.type, x.value]));
console.log(`${p.year}-${p.month}-${p.day} ${p.hour}:${p.minute}`);
23.09.2026
23 сентября 2026 г.
23.09.2026, 10:05
2026-09-23 10:05
Благодаря timeZone вывод одинаков в любом поясе среды. Формат локали (точки, «г.», порядок полей) задают данные ICU в движке, поэтому для машинного обмена берите ISO, а локальные форматы — только для показа.
А что с Temporal
Temporal — новый API дат в JavaScript с отдельными типами для календарной даты (Temporal.PlainDate), момента времени (Temporal.Instant) и даты с поясом (Temporal.ZonedDateTime). В марте 2026 года TC39 перевел его на стадию 4, он входит в ECMAScript 2026. Встроенная поддержка есть в Firefox 139+, Chrome и Edge 144+ и в Node.js 26; в Safari на сентябрь 2026 года полной поддержки нет, а в Node.js 24 (LTS) typeof Temporal возвращает "undefined". Поэтому примеры выше на Date остаются рабочим вариантом, а для Temporal проверьте целевые браузеры или подключите полифил.
Для сравнения: в Node.js 26.10.0 Temporal.PlainDate.from("2026-01-31").add({ months: 1 }) дает 2026-02-28 — то же прижатие к концу месяца, что и у функции addMonths выше.
Дата в 1С: тип Дата, Формат и ДобавитьМесяц
В 1С:Предприятие 8.3 дата устроена проще: это значение типа Дата с годом, месяцем, днем, часами, минутами и секундами. Миллисекунд и часового пояса в самом значении нет. Месяц, в отличие от JavaScript, считается с 1.
Д = Дата(2026, 9, 23, 10, 30, 0); // 23 сентября 2026, 10:30:00
Д2 = '20260923103000'; // то же значение литералом
Сообщить(Формат(Д, "ДФ=dd.MM.yyyy")); // 23.09.2026
Сообщить(Формат(Д, "ДФ='dd.MM.yyyy HH:mm'")); // 23.09.2026 10:30
Сообщить(Формат(Д, "ДЛФ=DD")); // 23 сентября 2026 г.
Завтра = Д + 86400; // к дате прибавляются секунды
ЧерезМесяц = ДобавитьМесяц('20260131', 1); // 28.02.2026
Дней = (НачалоДня(Д) - НачалоДня('20260901')) / 86400; // 22
Что здесь важно:
Формат(Значение, ФорматнаяСтрока)— основной способ вывести дату строкой. ПараметрДФзадает свой шаблон,ДЛФ— формат локали (D— дата цифрами,DD— месяц прописью,T— время,DT— дата и время). Параметры разделяются точкой с запятой.- Символы шаблона
ДФ:dd— день с ведущим нулем,MM— месяц,MMMM— название месяца,yyyy— год,HH— часы 0-23,hh— часы 12-часового формата,mm— минуты,ss— секунды. Регистр важен:MM— месяц,mm— минуты. - Пустая дата (
'00010101') по умолчанию форматируется в пустую строку. Текст для нее задают параметромДП:Формат(Д, "ДФ=dd.MM.yyyy; ДП='не указана'"). ДобавитьМесяцпри несуществующем числе возвращает последний день месяца — то поведение, которое в JavaScript пришлось писать руками. Признак «конец месяца» при этом не переносится:ДобавитьМесяц('20260430', 1)дает 30.05.2026, а не 31.05.2026. Если нужен именно последний день, беритеКонецМесяца(ДобавитьМесяц(Д, 1)).- Разность двух дат в 1С — число секунд. Летнего времени внутри значения нет, поэтому деление на 86400 для дат, приведенных к началу дня, дает целое число дней.
ТекущаяДата и часовые пояса в 1С
ТекущаяДата() возвращает дату и время компьютера, где выполняется код: на сервере это время сервера, на клиенте — время компьютера пользователя. ТекущаяДатаСеанса() возвращает текущую дату, приведенную к часовому поясу сеанса. Стандарт разработки 1С «Работа в разных часовых поясах» (std643) требует в серверном коде использовать ТекущаяДатаСеанса() вместо ТекущаяДата(), а в клиентском коде ТекущаяДата() не применять (в конфигурациях на БСП для клиента есть ОбщегоНазначенияКлиент.ДатаСеанса()). Поскольку значение Дата пояса не хранит, договоренность о том, в каком поясе записаны даты в базе, остается на разработчике.
JavaScript и 1С: сравнение
| Задача | JavaScript | 1С |
|---|---|---|
| Номер месяца | с 0 (getMonth()) |
с 1 (Месяц()) |
| Точность | миллисекунды | секунды |
| Часовой пояс | момент в UTC, показ в поясе среды | в значении пояса нет |
| Вывод строкой | Intl.DateTimeFormat, toISOString |
Формат с ДФ/ДЛФ |
| Плюс месяц | переполнение, нужна своя функция | ДобавитьМесяц |
| Разность | миллисекунды | секунды |
Если не получилось
- Дата на день меньше у части пользователей — строка вида
"2026-09-23"разобрана как UTC. Разбирайте компоненты или добавляйте времяT00:00. - Месяц на один больше — в
new Date(год, месяц, день)передан календарный номер месяца. Вычтите 1. - Invalid Date — строка не в ISO 8601. Разберите ее вручную или приведите к ISO.
- Разница в днях дробная или теряет день — сработал переход на летнее время. Считайте через
Date.UTC. - В 1С вместо минут выводится месяц — в шаблоне
ДФперепутаныMMиmm.
Выводы
Dateв JavaScript хранит момент времени в UTC, а методыget...иtoLocale...показывают его в поясе среды, если пояс не задан явно.- Месяцы в
Dateсчитаются с 0, строка из одной датыYYYY-MM-DDчитается как полночь UTC, надежен только формат ISO 8601. - Для показа используйте
Intl.DateTimeFormatсtimeZone, для обмена —toISOString(), календарные дни считайте черезDate.UTC. - В 1С тип
Датабез пояса и с точностью до секунды; строку даетФорматсДФ/ДЛФ, месяц прибавляетДобавитьМесяцс прижатием к концу месяца.
Где применяется / связь с практикой
Даты есть почти в любом интерфейсе: сроки оплаты, расписания, фильтры отчетов, отметки времени в логах. Ошибки из этой статьи (сдвиг на день, 31 февраля, летнее время) обычно находят уже пользователи из другого пояса, поэтому их полезно отработать заранее на практике.
Освойте тему на практике
Если хотите системно разобраться с JavaScript — типами, объектами, асинхронностью и работой в браузере, — посмотрите курс «JavaScript Developer. Basic». Для знакомства с форматом обучения подойдут бесплатные открытые уроки Otus.
FAQ
Как получить Unix-время в секундах в JavaScript?
Math.floor(Date.now() / 1000). Date.now() возвращает миллисекунды, а Unix-время обычно передают в секундах.
Как сравнить две даты в JavaScript?
Операторы < и > работают, потому что сравнивают числа. Для равенства сравнивайте a.getTime() === b.getTime(): a === b проверяет, один ли это объект.
Как в 1С получить дату без времени?
НачалоДня(Д) возвращает ту же дату с временем 00:00:00. Для вывода без времени достаточно шаблона ДФ=dd.MM.yyyy или ДЛФ=D.



