- Подготовьте список событий до запроса
- Что означают основные строки ICS
- Почему однодневное событие заканчивается завтра
- Исправление даты не создаёт второе событие
- Запросите текст, а не обещание вложения
- Какие значения сверить с исходником
- Результат преобразования и проверки
- Как проверить файл до импорта
- Полный запрос для повторения примера
Список встреч можно превратить в календарный текст, не подключая к чату личный календарь. Попросите обычный ICS, сохраните его локально и проверьте даты до любого импорта. Это позволяет отдельно увидеть, что модель поняла из исходника и что оказалось в файле.
ICS использует формат iCalendar. В нём дата и время записываются по определённым правилам, а у события есть собственный идентификатор. Ошибка в одной границе может перенести встречу на другой час или добавить лишний день, хотя название будет выглядеть правильно.
Подготовьте список событий до запроса
Для упражнения собраны шесть вымышленных записей. В первой задана встреча в Москве, во второй — один день без часов. Третья проходит по берлинскому времени. В четвёртой исправлена дата, пятая пересекает местную полночь, у шестой ещё не согласованы время и длительность.
Московское смещение в условиях — UTC+03:00, берлинское для этих дат — UTC+01:00. Часы и даты указаны явно. Задача модели — перенести сведения в формат, сохранив смысл каждой записи. Составлять удобное расписание или находить свободное время здесь не нужно.
До запроса полезно отделить известное от недостающего. Если запись прямо не является событием на весь день и у неё нет времени, отсутствие часов нельзя заменить полуночью. Такая запись должна остаться в списке уточнений.
Что означают основные строки ICS
Календарный блок начинается с BEGIN:VCALENDAR и заканчивается END:VCALENDAR. Каждое событие находится внутри BEGIN:VEVENT и END:VEVENT. В упражнении у события требуются UID, DTSTAMP, DTSTART, DTEND и SUMMARY.
UID отличает одно событие от другого. DTSTAMP задаёт служебную временную отметку компонента в UTC; в этом упражнении её значение задано заранее. DTSTART задаёт начало, DTEND — конец, SUMMARY — название. Общая структура и свойства описаны в RFC 5545.
Для дат и времени важно сохранить тип. Событие на весь день записывается через VALUE=DATE. Оно не превращается во встречу в 00:00: у календарных приложений эти формы имеют разный смысл.
Почему однодневное событие заканчивается завтра
По правилу DTEND конец не входит в интервал. Если «День архива» занимает весь день 3 ноября, начало — 20261103, а конец — 20261104. Это один день, а не два.
Две строки выглядят так:
DTSTART;VALUE=DATE:20261103
DTEND;VALUE=DATE:20261104
Событие с часами, переведёнными в UTC, имеет суффикс Z. Например, 10:00 в Москве при заданном смещении +03:00 соответствует 07:00 UTC. К значению UTC с Z не добавляют параметр TZID.
Часовой пояс следует определять для конкретной даты. В нашем исходнике смещения уже приведены. Для другого списка нельзя автоматически копировать берлинское +01:00 на весь год: переход на летнее время меняет соотношение часов.
Исправление даты не создаёт второе событие
У C04 исходная дата 5 ноября отменена исправлением. Верная — 6 ноября, 16:00–16:30 по Москве. В календарном тексте должно остаться одно событие с исправленной датой. Сохранить обе версии как две встречи — значит исказить исходник.
У C05 начало и конец лежат по разные стороны местной полуночи. После перевода в UTC обе границы приходятся на 7 ноября: 22:30 и 23:30. Проверять только совпадение календарной даты недостаточно — нужен весь интервал.
У C06 известна дата 8 ноября, но не согласованы начало и длительность. Её нельзя включать в VEVENT до уточнения. В ответе отдельно нужны ID записи и вопрос о недостающих сведениях.
Запросите текст, а не обещание вложения
В промпте явно задан обычный текст от BEGIN:VCALENDAR до END:VCALENDAR. После него — отдельная строка уточнений. Никаких ссылок на скачивание, вложений, календарных подключений, организаторов, участников и приглашений не требуется.
Полный запрос с шестью записями приведён ниже. Модель должна вернуть текст в обычном чате. Полный ответ сохраняется отдельно, а в файл .ics переносится только календарный блок, без пояснений до или после него.
При сохранении используйте UTF-8 и физические окончания строк CRLF. Раздел 3.1 RFC рекомендует складывать строки длиннее 75 октетов; продолжение начинается с пробела или табуляции. Октеты — байты, поэтому русская буква в UTF-8 может занимать больше одного.
В текстовых значениях нужно экранировать обратную косую черту, запятую, точку с запятой и перевод строки. Для названий «Проверка прототипа, этап 1» и «Обзор макета; цвет» это отдельная проверка; удалять знаки из названия вместо экранирования не нужно.
Какие значения сверить с исходником
Таблица содержит ручной эталон, сохранённый до опыта. В правом столбце указан фактический результат преобразования.
| ID | Ожидаемое начало | Ожидаемый конец | Ответ ChatGPT |
|---|---|---|---|
| C01 | 20261102T070000Z | 20261102T074500Z | Обе границы совпали |
| C02 | 20261103, DATE | 20261104, DATE | Обе границы совпали |
| C03 | 20261104T130000Z | 20261104T143000Z | Обе границы совпали |
| C04 | 20261106T130000Z | 20261106T133000Z | Обе границы совпали |
| C05 | 20261107T223000Z | 20261107T233000Z | Обе границы совпали |
| C06 | Не включать до уточнения | Узнать часы и длительность | Не включена; запрошено уточнение |
Результат преобразования и проверки
ChatGPT вернул обычный текст календаря и отдельное уточнение по C06. Календарный блок сохранён локально в UTF-8 с окончаниями строк CRLF. Значения событий при сохранении не исправлялись; в файл не переносилось пояснение после END:VCALENDAR.
Внутри оказалось пять VEVENT с разными UID. Начало и конец каждой полной записи совпали с заранее подготовленным эталоном. Для C02 использованы DATE 20261103 и 20261104. C04 присутствует один раз с датой 6 ноября. У C05 границы UTC — 7 ноября, 22:30 и 23:30.
Запятая в названии C01 и точка с запятой в C03 экранированы. Неполная C06 не включена в календарь: модель запросила время начала, длительность или окончание, а также часовой пояс. Ни приглашений, ни участников, ни повторяющихся событий в файле нет.

Проверка структуры и точных полей этого учебного набора прошла без ошибок. Для полноценного рабочего импорта нужен также профильный iCalendar-парсер; в этом опыте такой парсер не применялся. Сам импорт в личный календарь не выполнялся.
Как проверить файл до импорта
Начните с количества событий: в этом наборе их должно быть пять. Затем сравните ID, названия, типы дат и обе границы каждого события. Проверьте, что исправленная C04 не продублирована, а неполная C06 не получила придуманного времени.
После проверки значений нужен профильный парсер iCalendar. Он помогает обнаружить синтаксические проблемы, которые легко не заметить глазами. Но успешное чтение файла не подтверждает правильность исходных дат: парсер может принять корректно записанную неверную встречу.
UID в реальном календаре должен быть глобально уникальным и сохраняться при обновлении того же события. Короткие c01…c05@gpt-insider.example и фиксированный DTSTAMP в нашем запросе заданы для изолированного упражнения. Их не следует копировать в действующие календари как универсальный образец идентификаторов.
Сначала проверьте текст и структуру, затем решайте вопрос импорта. В этом опыте ничего не импортируется, приглашения не отправляются и доступ к личному календарю не используется.
Полный запрос для повторения примера
Преобразуй текст в обычный текст iCalendar ICS без подключения календаря и любых внешних действий. Никаких ссылок на скачивание, вложений или бинарных файлов. Первым выведи полный текст от BEGIN:VCALENDAR до END:VCALENDAR, без Markdown-ограждений. После него отдельной строкой УТОЧНЕНИЕ: перечисли ID неполных записей и нужные сведения. Неполные записи не включай в VEVENT, не придумывай время или длительность.
VERSION:2.0; PRODID:-//GPT Insider//Synthetic ICS Test 7//RU; для всех VEVENT DTSTAMP:20261023T120000Z. UID формата c01@gpt-insider.example, c02@gpt-insider.example и далее по исходному ID; не переиспользуй UID разных событий. SUMMARY сохраняй с корректным экранированием TEXT. У всех событий явные DTSTART и DTEND. Событие на весь день — VALUE=DATE с исключающей конечной датой. Для событий с часами переведи обе границы в UTC с Z, используя указанные смещения; TZID/VTIMEZONE тогда не нужны. Исправление заменяет старую дату, не добавляет второе событие. Не создавай повторения, приглашения, организаторов или участников.
ИСХОДНИК
Все записи вымышленные; локальные часы и даты указаны явно.
C01. «Проверка прототипа, этап 1»: 2 ноября 2026, 10:00–10:45, Europe/Moscow (UTC+03:00).
C02. «День архива»: весь день 3 ноября 2026, один календарный день.
C03. «Обзор макета; цвет»: 4 ноября 2026, 14:00–15:30, Europe/Berlin (для этих дат UTC+01:00).
C04. «Редактура памятки»: первоначальная запись 5 ноября 2026, 16:00–16:30 Europe/Moscow отменена исправлением: верная дата 6 ноября 2026, время 16:00–16:30 Europe/Moscow (UTC+03:00). Это одно событие с исправленной датой.
C05. «Ночная сборка»: начало 7 ноября 2026 в 23:30, конец 8 ноября 2026 в 00:30, Europe/Berlin (UTC+01:00).
C06. «Практикум по карточкам»: 8 ноября 2026, время начала и продолжительность ещё не согласованы. Это не событие на весь день.
