Даты и часовые пояса в CSV: отделите день от момента времени
Как договориться о date-only и timestamp, сохранить исходную строку и проверить переход UTC без скрытой локали конвертера.
Строка 06.10.2026 обозначает календарную дату. Строка 2026-10-06T00:30:00+07:00 обозначает момент с явным смещением. Первая не содержит времени, вторая при переводе в UTC может оказаться предыдущим днём. До импорта CSV определите, что хранит каждая колонка: день, момент или местное время события.
CSV → JSON в Neraviko оставляет все ячейки строками. Он не переводит даты в UTC, не выбирает локаль и не проверяет существование календарного дня. Это позволяет отделить перенос данных от последующей смысловой интерпретации.
Согласуйте два разных типа поля
Для календарного дня можно принять вид YYYY-MM-DD и запретить добавление времени. Пример — дата рождения или день отчёта, когда задача не требует определённого момента. Не превращайте такой день автоматически в полночь UTC: это добавляет отсутствующую в источнике информацию.
Для момента договоритесь о полном timestamp с явным Z или числовым смещением. Формат RFC 3339 описывает дату, время и смещение относительно UTC. RFC 3339, раздел 5.6, июль 2002; проверено 05.10.2026.
Смещение +07:00 описывает отношение к UTC для данного значения. Оно не заменяет название зоны и её правила на все будущие даты. Если нужен будущий местный график, отдельно храните согласованное название зоны и правило вычисления времени исполнения. Конвертер CSV не является календарным scheduler.
Проверенный синтетический пример
Исходный файл:
id;occurred_at;date_only
A01;2026-10-06T00:30:00+07:00;2026-10-06
Откройте CSV → JSON, установите delimiter=semicolon, header=true, pretty=false, trailing_newline=false. Проверенный результат csv.to_json версии 1:
[{"id":"A01","occurred_at":"2026-10-06T00:30:00+07:00","date_only":"2026-10-06"}]
Ни одно поле не преобразовано в дату. Для timestamp отдельный расчёт даёт 2026-10-05T17:30:00Z: от местного времени вычитаются семь часов. Расчёт проверен стандартной библиотекой Python, независимо от CSV-конвертера. Календарное поле date_only остаётся 2026-10-06.
Если в принимающей системе дата события выводится как 5 октября, сначала посмотрите, показывает ли она UTC-день timestamp вместо исходного календарного поля. Это не обязательно потеря данных при конвертации; проблема может находиться в выборе колонки или зоны отображения.
Не угадывайте двусмысленные даты
Запись 03/04/2026 допускает как минимум два распространённых прочтения. Договоритесь о единственном формате у экспортёра либо потребуйте отдельную колонку, указывающую формат. Массовая перестановка частей по первой встретившейся записи не подтверждает, что остальная колонка использует тот же порядок.
Timestamp без смещения, например 2026-10-06 10:00:00, не сообщает, к какой зоне относится. Не присваивайте ему текущую зону компьютера импортёра молча. Зафиксируйте исходную зону в контракте; при неизвестной зоне сохраните текст и отметьте запись для уточнения.
Пустая ячейка тоже требует решения: неизвестная дата, разрешённый пропуск или ошибка. В Neraviko она станет пустой строкой. Чтобы получить null в модели приложения, нужен отдельный явно разрешённый шаг. Буквальная строка null не меняет тип автоматически.
Сначала валидируйте смысл, затем вычисляйте
На этапе приложения проверьте допустимость даты, точность дробных секунд и требование смещения. Затем преобразуйте только timestamp-колонки. Исходный текст полезно сохранить в контрольном наборе, чтобы сравнивать результаты разбора и видеть, какая информация исчезла.
Проверьте границу полуночи, конец месяца, високосный день и пустое значение. Если проект использует зоны с сезонным переводом часов, добавьте их неоднозначные и отсутствующие местные времена; готовое правило должно принимать решение явно.
Если экспорт объединяет записи разных зон, не применяйте одно смещение ко всей таблице. Проверяйте смещение каждой timestamp-строки. Общая зона в настройках допустима только тогда, когда источник явно гарантирует единое местное время для всей колонки.
Перед основным импортом сверьте количество записей, тип каждой даты и ожидаемый UTC-результат для нескольких известных моментов. Не считайте красивый формат подтверждением календарной валидности.
Лимит CSV-парсера — 5 000 записей всего, включая заголовок, то есть до 4 999 записей данных при header=true; ещё действуют 256 колонок, 65 536 байт на поле и 262 144 байта запроса. Операция серверная; по контракту сырые входы и выходы не сохраняются и не логируются по умолчанию. Для настройки достаточно искусственных дат.