Чтобы подсчитать календарные дни между датами публикации, сравните их календарные даты, а не делите прошедшее время в часах на 24. На Mac Numbers работает с датами без времени; временные метки сначала нужно интерпретировать в одном выбранном часовом поясе.
В этом руководстве используются искусственно созданные даты публикаций и григорианский календарь. Нужно ответить на вопрос: «Сколько календарных дней между этими двумя публикациями?» По умолчанию считается разность со знаком: для одной и той же даты результат равен нулю, а для следующей даты — единице.
Какую информацию о датах вы имеете?
Перед вычислением выберите тип исходных данных. Дата, указанная в публикации, и временная метка, фиксирующая момент её выхода, требуют разной предварительной обработки.
| Входные данные | Значение | Подготовка |
|---|---|---|
2025-03-09 |
Календарная дата: год, месяц и день | Сравните напрямую с другой календарной датой по григорианскому календарю |
2025-03-09T05:00:00Z |
Временная метка, указывающая на конкретный момент | Преобразуйте в дату в выбранном часовом поясе для отчётов |
-05:00 |
Смещение UTC | Описывает разницу местного времени с UTC в конкретный момент |
America/New_York |
Часовой пояс с названием | Предоставляет правила для интерпретации местных дат и изменений смещения |
Смещение и часовой пояс с названием содержат разную информацию. Смещение, указанное для одной временной метки, не описывает смещение в другую дату. Часовой пояс с названием задаёт правила этой зависимости, включая переходы на летнее время. Это различие явно отмечено в RFC 9557, «Дата и время в Интернете: временные метки с дополнительной информацией».
Для таблицы с датами публикаций установите такое правило: сохраняйте даты, уже заданные как календарные; даты из временных меток получайте в одном явно выбранном часовом поясе для отчётов. Не приписывайте дате без времени произвольные полночь и смещение только ради вычитания.
В стандартах календаря даты также отличаются от дат и времени. Стандарт iCalendar определяет отдельное значение DATE, содержащее компоненты календарной даты. В его сериализованной форме используются цифры без разделителей; даты с дефисами в этом руководстве приведены для удобства чтения. См. RFC 5545, раздел 3.3.4.
Почему нельзя делить прошедшее время в секундах на 86 400?
Разность календарных дат показывает продвижение по календарю. Разность прошедшего времени показывает интервал между двумя моментами. Во время перехода на летнее время эти величины не обязательно соответствуют 24 часам на каждый шаг календарной даты. В RFC 5545 прямо отмечено, что номинальный суточный повтор может длиться больше или меньше 24 часов при сдвиге часового пояса. См. обсуждение повторов в стандарте.
Рассмотрим две искусственно созданные пары дат публикаций в America/New_York. В следующих вычислениях для обеих границ используется местная полночь. Смещения соответствуют правилам часового пояса Нью-Йорка и переходам, описанным в базе данных часовых поясов IANA.
| Интервал искусственных дат публикаций | Смещение в начале | Смещение в конце | Прошедшее время, часы | Разность календарных дат |
|---|---|---|---|---|
| 9–10 марта 2025 года | -05:00 |
-04:00 |
23 | 1 |
| 2–3 ноября 2025 года | -04:00 |
-05:00 |
25 | 1 |
Для мартовской пары соответствующие моменты UTC — 2025-03-09T05:00:00Z и 2025-03-10T04:00:00Z; между ними 23 часа. Если разделить этот интервал на 24, получится приблизительно 0.9583. Для ноябрьской пары аналогичное вычисление даёт приблизительно 1.0417. Ни одно из этих десятичных значений не отвечает на вопрос о календарных днях.
Округление может скрыть ошибку в этих примерах, но не даёт надёжного правила подсчёта. Между публикациями в 23:55 и 00:05 в соседние календарные даты всего десять минут, но разность календарных дат всё равно равна единице. Сначала извлеките даты, затем вычислите их разность.
Как подсчитать даты публикаций в Numbers?
Используйте этот способ, если у вас уже есть нужные даты публикаций. Согласно документации Apple, DAYS(end-date, start-date) возвращает количество дней между аргументами, включая отрицательное значение, если конечная дата предшествует начальной. См. справочник по DAYS в Numbers.
Откройте таблицу Numbers с пустой таблицей. Используйте первую строку для описательных заголовков, а затем по очереди введите следующие формулы во второй строке. Чтобы ввести формулу, выберите ячейку, напечатайте начальный символ =, завершите выражение и нажмите Return. Это описанные Apple шаги ввода формулы в Numbers на Mac.
| Ячейка | Предлагаемый заголовок столбца | Формула для ввода | Ожидаемое значение |
|---|---|---|---|
A2 |
Дата более ранней публикации | =DATE(2025,3,9) |
9 марта 2025 года |
B2 |
Дата более поздней публикации | =DATE(2025,3,10) |
10 марта 2025 года |
C2 |
Разница в календарных днях | =DAYS(B2,A2) |
1 |
Функция DATE создаёт входные значения из года, месяца и дня, не полагаясь на то, как будет интерпретирована неоднозначная текстовая строка. Apple рекомендует эту функцию для единообразной интерпретации дат при разных настройках формата даты в списке функций даты и времени.
Повторите проверку в третьей строке: укажите =DATE(2025,11,2) в A3, =DATE(2025,11,3) в B3 и =DAYS(B3,A3) в C3. Ответ снова будет 1. Вы сравниваете заданные календарные даты, поэтому корректировать результат с учётом прошедших часов не нужно.
Чтобы быстро выполнить расчёт без вспомогательных ячеек, введите =DAYS(DATE(2025,3,10),DATE(2025,3,9)) в любую пустую ячейку. Вариант с отдельными столбцами проще проверить и использовать повторно для нескольких пар дат публикаций.
Вам нужна разница или включительный подсчёт дат?
Стандартная разность не включает начальную дату в подсчёт. Между 9 и 10 марта один день. Если же в задаче спрашивается, сколько дат включено в диапазон с 9 по 10 марта, ответ — две.
Для включительного диапазона, конечная дата которого совпадает с начальной или следует за ней, используйте =DAYS(B2,A2)+1. Перед применением этой формулы проверьте порядок дат. Отрицательная разность показывает, что записи могут быть переставлены; автоматическое взятие абсолютного значения скроет эту информацию.
То же различие относится к диапазону из одной даты. Разность дат равна нулю, а включительный подсчёт даёт одну дату. Решите, какой результат нужен в вашей таблице, и соответственно назовите столбец.
Что делать, если входные данные — временные метки?
Прежде чем отбрасывать время, преобразуйте временную метку в часовой пояс для отчётов. Например, 2025-03-10T00:30:00Z соответствует 20:30 9 марта в America/New_York, с учётом смещения -04:00 для этой даты. Если скопировать первые десять символов временной метки, получится дата UTC, а не дата публикации в Нью-Йорке.
Документированная сигнатура DAYS в Numbers принимает два аргумента даты; аргумента для часового пояса с названием у неё нет. Используйте её после определения нужных дат. Для повторяемого вычисления по временным меткам на Mac необходимые API календаря предоставляет Foundation.
Несмотря на название, Date в Foundation представляет момент, независимый от календаря или часового пояса. Apple предписывает выполнять календарную арифметику с помощью Calendar. См. официальную документацию Date.
Для обычных переходов на летнее время последовательность действий в Foundation такова: выберите григорианский календарь и часовой пояс для отчётов, найдите начало местных суток для каждой из двух граничных дат, затем запросите разность, указав только компонент дня. Apple описывает методы startOfDay(for:) и dateComponents(_:from:to:).
Запустите полный пример Foundation в Terminal
Этот необязательный способ требует установленного набора инструментов Swift. Откройте Terminal и выполните swift --version для проверки, как описано в руководстве Swift «Начало работы». При необходимости Apple описывает установку инструментов командной строки с помощью xcode-select --install; прежде чем продолжить, завершите установку в открывшемся диалоговом окне. См. «Установка инструментов командной строки».
Вставьте весь приведённый ниже блок в Terminal. Он содержит готовую программу и искусственные входные данные. Программа разбирает временные метки с явным смещением и без долей секунды. Apple описывает .withInternetDateTime для такого формата временных меток в справочнике параметров ISO8601DateFormatter.
swift - <<'SWIFT'
import Foundation
let zoneID = "America/New_York"
guard let zone = TimeZone(identifier: zoneID) else {
fatalError("Unknown reporting zone: \(zoneID)")
}
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = zone
let parser = ISO8601DateFormatter()
parser.formatOptions = [.withInternetDateTime]
let samples = [
("Spring", "2025-03-09T00:00:00-05:00",
"2025-03-10T00:00:00-04:00"),
("Autumn", "2025-11-02T00:00:00-04:00",
"2025-11-03T00:00:00-05:00")
]
for (label, startText, endText) in samples {
guard let start = parser.date(from: startText),
let end = parser.date(from: endText) else {
fatalError("Could not parse timestamps for \(label)")
}
let startDay = calendar.startOfDay(for: start)
let endDay = calendar.startOfDay(for: end)
guard let days = calendar.dateComponents(
[.day], from: startDay, to: endDay
).day else {
fatalError("Could not calculate civil days for \(label)")
}
let hours = end.timeIntervalSince(start) / 3600
print("\(label): \(days) civil day(s), \(hours) elapsed hours")
}
SWIFT
Ожидаемый вывод приведён ниже. Числовые примеры были независимо проверены с помощью арифметики дат; код Swift был проверен, но здесь не запускался на macOS.
Spring: 1 civil day(s), 23.0 elapsed hours
Autumn: 1 civil day(s), 25.0 elapsed hours
Чтобы изменить программу, замените строки временных меток и осознанно выберите часовой пояс для отчётов. Смещения временных меток указывают на соответствующие моменты; часовой пояс календаря определяет, каким местным датам соответствуют эти моменты. Если парсер сообщает об ошибке, программа останавливается, а не подставляет текущую дату и не пропускает запись.
Пример принимает указанный формат со смещением. Для дробных секунд нужны другие параметры парсера. Кроме того, он не обрабатывает аннотации часового пояса в квадратных скобках из RFC 9557: передавайте часовой пояс с названием отдельно, как показано в примере, а не исходите из того, что эта конфигурация парсера поддерживает такие аннотации.
Что проверить, если результат кажется неправильным?
Проводите проверки по порядку: каждая из них поможет выявить отдельный источник расхождений.
- Уточните, какой подсчёт требуется. Разность дат и включительный подсчёт дат для возрастающего диапазона отличаются на единицу.
- Проверьте входные данные. Для публикаций, заданных только датой, используйте фактические значения года, месяца и дня. Не считайте, что импортированные временные метки уже соответствуют нужным местным датам.
- Проверьте часовой пояс для отчётов. Преобразуйте оба момента в одну и ту же выбранную зону и лишь затем извлекайте даты.
- Проверьте операцию. После удаления влияния времени суток подсчитайте календарные дни. Деление интервала между моментами на
86,400отвечает на вопрос о прошедшем времени. - Проверьте направление. Сохраняйте отрицательный результат, пока не выясните, не перепутаны ли более ранняя и более поздняя записи.
В календарном коде используйте API начала суток, а не исходите из предположения, что каждые местные сутки начинаются в единственную полночь. Согласно документации Apple, startOfDay(for:) выбирает первую полночь, если их две, или первый существующий момент, если полуночи нет. Так обрабатывается граничный случай, который можно упустить, вручную устанавливая час в ноль. См. startOfDay(for:).
Пример с Foundation охватывает обычные переходы на летнее время. Для исторических изменений, при которых целая местная дата пропускается, сначала укажите, считает ли задача календарные даты по григорианскому календарю или местные дни, которые действительно существовали: это разные требования. Если требуется первое, сохраняйте даты без времени как календарные обозначения.
Для таблицы с датами публикаций оставьте итоговый расчёт простым: задайте две нужные даты по григорианскому календарю, сохраните их порядок и используйте DAYS, чтобы найти разницу. Если входные данные — конкретные моменты времени, перед вычислением явно укажите часовой пояс для отчётов. Тогда результат будет привязан к датам публикаций, даже если между ними перевели часы.
Источники
DAYS — Apple.
Вычисление значений по данным в ячейках таблицы в Numbers на Mac — Apple.
Список функций по категориям — Apple.
RFC 9557: Дата и время в Интернете: временные метки с дополнительной информацией — IETF.
RFC 5545: Спецификация базового объекта календаря и планирования в Интернете (iCalendar) — RFC Editor.
Date — Apple.
startOfDay(for:) — Apple.
dateComponents(_:from:to:) — Apple.
formatOptions — Apple.
Начало работы — Swift.org.