Представьте полный день, включив его начало и исключив начало следующего дня. Чтобы отметить публикацию в календаре Mac, создайте событие на весь день; в данных iCalendar явная дата окончания указывает на первый день, не входящий в событие.

В этом руководстве используется условная дата публикации — 18 июня 2027 года. Задача — добавить в календарь Mac один полный день публикации, экспортировать его и проверить границы. Та же логика поможет распознавать ошибки при переносе даты между календарём, электронной таблицей и автоматизацией.

Что означает исключительная граница на следующий день?

Для условного дня публикации включённая дата — 18 июня. 19 июня — первая исключённая дата. В виде полуоткрытого интервала диапазон записывается так: [2027-06-18, 2027-06-19): квадратная скобка включает начало, а круглая скобка исключает конец.

Стандарт iCalendar определяет DTSTART события как включительное, а DTEND — как не включительное. Для события на весь день оба значения задаются датами. Поэтому дата окончания, приходящаяся на следующий день, обозначает один полный день. Значения, содержащие только дату, не должны иметь параметр TZID. RFC 5545, компоненты событий и идентификаторы часовых поясов.

В этом иллюстративном фрагменте показаны только два свойства границ, а не полный файл календаря, готовый к импорту:

DTSTART;VALUE=DATE:20270618
DTEND;VALUE=DATE:20270619

В следующей таблице это правило применено к условным графикам публикаций. Последний столбец следует читать как первую исключённую дату, а не как ещё один день публикации.

Предполагаемый охват Включённая начальная дата Исключительная дата окончания
Только 18 июня 18 июня 2027 года 19 июня 2027 года
С 18 по 20 июня включительно 18 июня 2027 года 21 июня 2027 года
Только 30 июня 30 июня 2027 года 1 июля 2027 года

Создайте день публикации в календаре Mac

Начните с календаря, в котором можно создавать события. Для этой задачи понадобятся элементы управления событиями на весь день в приложении «Календарь»; инструменты программирования не требуются.

  1. Откройте приложение «Календарь» и перейдите к 18 июня 2027 года.
  2. В верхней части окна выберите День или Неделя.
  3. Дважды щёлкните область all-day над почасовой сеткой для 18 июня.
  4. Дайте событию нейтральное название Sample publication day.
  5. Убедитесь, что отметка занимает только 18 июня.

Apple указывает, что событие на весь день создаётся двойным щелчком по соответствующей области в режиме День или Неделя. Отдельно описано создание многодневного события перетаскиванием по датам. В этом примере используйте действие для одного дня. Настройка событий на весь день, на несколько дней или повторяющихся событий в приложении «Календарь» на Mac.

Сначала проверьте отображение в календаре: отметка должна охватывать нужную дату и не переходить на 19 июня. Исключительная граница описывает представление диапазона в данных. Она не означает, что видимую отметку нужно продлить ещё на один день.

Экспортируйте событие и проверьте границы дат

Выберите календарь события в списке календарей, затем нажмите Файл > Экспортировать > Экспортировать. Сохраните полученный файл .ics в удобном месте. При этой операции экспортируются события выбранного календаря, поэтому файл календаря с несколькими событиями будет содержать несколько записей событий. Apple указывает, что для такого экспорта используется формат .ics. Импорт и экспорт календарей на Mac.

В Finder выберите экспортированный файл и воспользуйтесь командой Файл > Открыть с помощью, чтобы открыть его в текстовом редакторе, например TextEdit. Apple описывает этот способ выбора приложения для однократного открытия файла. Выбор приложения для открытия файла на Mac.

Найдите Sample publication day, затем проверьте окружающую запись события. Сравните свойства начала и окончания с приведённым выше иллюстративным фрагментом. Другие свойства также могут присутствовать; сосредоточьтесь на значениях дат и их типах.

Если у события на весь день нет ни DTEND, ни DURATION, стандарт назначает ему длительность в один день. Поэтому отсутствие явной даты окончания само по себе не указывает на проблему. RFC 5545, компоненты событий.

Используйте экспортированную копию для диагностики. Если видимое событие охватывает неверные даты, исправьте его в приложении «Календарь» и экспортируйте заново. Так проверка останется связана с созданным вами событием.

Различайте календарные даты, моменты времени, смещения и именованные часовые пояса

Перед переносом дня публикации в другой инструмент выясните, какой тип значения ему нужен. Метка календаря и временная отметка отвечают на разные вопросы.

Понятие Иллюстративное значение Что оно обозначает
Календарная дата 2027-06-18 Календарный день без указания времени
Момент времени 2027-06-18T10:00:00Z Одну точку на временной шкале
Числовое смещение UTC +02:00 Разницу между местным временем и UTC
Именованный часовой пояс Europe/Paris Часовой пояс, правила которого определяют применимые смещения

RFC 3339 определяет форматы временных отметок для моментов времени, в том числе числовые смещения и обозначение UTC Z. В описания интервалов стандарт прямо не входит. Поэтому для пары временных отметок RFC 3339 всё ещё требуется отдельное соглашение о том, включается ли конечная точка. RFC 3339, область действия и формат даты/времени.

Например, условные временные отметки 2027-06-18T12:00:00+02:00 и 2027-06-18T10:00:00Z обозначают один и тот же момент времени. Ни одна из них не выражает полный день публикации. Добавление времени и смещения к дате меняет записываемую информацию. RFC 3339, местные смещения.

Именованный часовой пояс содержит правила расчёта местного времени и применимого смещения. IANA поддерживает эти правила, включая изменения смещений и переходы на летнее время; поставщики операционных систем и программ распространяют обновления пользователям. При расчёте границ для разных дат одного числового смещения недостаточно, чтобы заменить этот набор правил. Часовые пояса IANA.

Для отметки в календаре сохраните календарную дату. Если позже потребуется определить, какие публикации с временными отметками относятся к этому дню, сначала выберите именованный часовой пояс, задающий день публикации, а затем рассчитайте в этом часовом поясе два граничных момента времени.

Как автоматизации на Mac рассчитать тот же диапазон?

Тип Date в Apple Foundation представляет момент времени независимо от календаря или часового пояса. Его название может ввести в заблуждение, если исходное значение — лишь 18 июня: чтобы календарная дата обозначила момент времени, ей нужен контекст календаря. Apple рекомендует использовать Calendar для календарной арифметики. Date.

В автоматизации явно задайте календарную систему и часовой пояс. Foundation предоставляет доступ к часовому поясу календаря через свойство timeZone, которому можно присвоить значение. Если задать его явно, определение дня публикации будет понятно тем, кто обслуживает автоматизацию. Calendar.timeZone.

Если известен момент времени, который приходится на нужный день, Calendar.dateInterval(of: .day, for:) получает время начала и длительность этого календарного компонента. Метод возвращает необязательный результат; автоматизация должна обработать ошибку, а не молча подставлять другую дату. dateInterval(of:for:).

Здесь есть важная особенность конечной точки: Apple описывает DateInterval как замкнутый интервал, включающий оба конца. Чтобы задать исключительную границу дня публикации, используйте рассчитанные границы и явное сравнение: start <= instant && instant < end. Это правило проверки принадлежности диапазону, а не готовая программа. DateInterval.

Не исходите из того, что каждый местный день начинается в обычную полночь. Метод Apple startOfDay(for:) возвращает первый существующий момент дня: если есть две полуночи, выбирается первая, а если полуночи нет — первый существующий момент. Границы, рассчитанные календарём, сохраняют это различие. startOfDay(for:).

Проверьте границу, прежде чем использовать дату повторно

Для рабочего процесса с временными отметками выполните эту трёхпунктовую проверку рассчитанного диапазона. Ожидаемые результаты напрямую следуют из явного сравнения с исключительной конечной границей.

Проверяемый момент времени Ожидаемая принадлежность диапазону
Точное начало дня Включён
Любой момент строго между границами Включён
Точное начало следующего дня Исключён

Эта проверка также показывает, почему не нужно придумывать последнее время, например 23:59:59. Если входные данные содержат доли секунды, значение позже выбранного отсечного времени всё ещё может предшествовать границе следующего дня. Сравнение с исключительной границей избавляет от необходимости выбирать точность временной отметки для «последнего момента».

Для задачи на компьютере Mac в завершение убедитесь, что Sample publication day занимает только 18 июня, а представление дат в экспортированном файле соответствует этому охвату. Если позднее день будет использоваться как фильтр временных отметок, сохраните выбранные календарь и часовой пояс, включите начало и исключите границу следующего дня.

Источники