fix: даты «только дата» больше не сдвигаются на день назад
Tests / frontend-test (push) Successful in 2m1s

SharePoint хранит поле «только дата» как полночь по поясу сайта (UTC+5)
в UTC: «05.10» приходит из REST как 2026-10-04T19:00:00Z. Формы брали
первые 10 символов и показывали 04.10, а каждое пересохранение (полное
право, исполнитель, повторная отправка) записывало дату ещё на день раньше.

Чтение всех дат идёт через spDateOnlyToIso (округление до ближайшей
полуночи UTC), «сегодня» — через todayIsoDate вместо toISOString, который
до 05:00 давал вчерашнее число. Уже сдвинутые записи в SP не исправляются.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Тимур Городецкий
2026-10-05 12:41:18 +05:00
parent 9400f8546e
commit f8ab2a1d71
21 changed files with 114 additions and 22 deletions
@@ -0,0 +1,51 @@
import { spDateOnlyToIso } from './dateUtils';
// SharePoint хранит поле «только дата» как полночь по поясу САЙТА, переведённую
// в UTC, — поэтому «5 октября» приходит из REST как предыдущий день по UTC.
describe('spDateOnlyToIso', () => {
it('сайт в UTC+5 (Астана с 2024): 04T19:00Z → 5-е', () => {
expect(spDateOnlyToIso('2026-10-04T19:00:00Z')).toBe('2026-10-05');
});
it('сайт в UTC+6 (старый пояс Астаны): 04T18:00Z → 5-е', () => {
expect(spDateOnlyToIso('2026-10-04T18:00:00Z')).toBe('2026-10-05');
});
it('сайт в UTC: 05T00:00Z → 5-е', () => {
expect(spDateOnlyToIso('2026-10-05T00:00:00Z')).toBe('2026-10-05');
});
it('переход через месяц и год', () => {
expect(spDateOnlyToIso('2026-09-30T19:00:00Z')).toBe('2026-10-01');
expect(spDateOnlyToIso('2026-12-31T19:00:00Z')).toBe('2027-01-01');
});
it('високосный год: 28 февраля → 29-е', () => {
expect(spDateOnlyToIso('2028-02-28T19:00:00Z')).toBe('2028-02-29');
});
it('строку без времени возвращает как есть', () => {
expect(spDateOnlyToIso('2026-10-05')).toBe('2026-10-05');
});
it('пустое/отсутствующее значение → пустая строка', () => {
expect(spDateOnlyToIso('')).toBe('');
expect(spDateOnlyToIso(null)).toBe('');
expect(spDateOnlyToIso(undefined)).toBe('');
});
it('повторное сохранение не сдвигает дату (запись → чтение → запись)', () => {
// Имитация: SP вернул 04T19:00Z, мы прочитали, сохранили обратно «как есть»,
// SP снова хранит 04T19:00Z — дата обязана остаться 5-м, а не уехать на 4-е.
const firstRead = spDateOnlyToIso('2026-10-04T19:00:00Z');
expect(firstRead).toBe('2026-10-05');
const secondRead = spDateOnlyToIso(`${addDays(firstRead, -1)}T19:00:00Z`);
expect(secondRead).toBe(firstRead);
});
});
function addDays(isoDate: string, days: number): string {
const d = new Date(`${isoDate}T00:00:00Z`);
d.setUTCDate(d.getUTCDate() + days);
return d.toISOString().slice(0, 10);
}