Рассчитать разницу между 2 NSDate в год, месяц, день игнорировать время? - PullRequest
0 голосов
/ 30 июня 2019

Например, у меня есть 2 NSDate в одном и том же часовом поясе UTC

NSDate *date1 = [NSDate dateWithString:@"2019-05-31 22:00:00 +0000"];
NSDate *date2 = [NSDate dateWithString:@"2019-06-01 01:00:00 +0000"];

Я хочу создать функцию для вычисления разницы между ними в части год, месяц и день, игнорируя время.Ожидаемый результат выше

Год: 0

Месяц: 1

День: 1

Или другой пример с

NSDate *date1 = [NSDate dateWithString:@"2019-02-28 22:00:00 +0000"];
NSDate *date2 = [NSDate dateWithString:@"2020-03-01 01:00:00 +0000"];

Получит результат

Год: 1

Месяц: 13

День: 367

Я пробовалответы на этот вопрос Как рассчитать разницу между двумя датами?

Но подход, использующий NSTimeInterval, кажется ненадежным из-за 365 или 366 дней в году и не игнорирует время.Отвечайте как

NSDateComponents *components;
NSInteger days;

components = [[NSCalendar currentCalendar] components: NSDayCalendarUnit 
    fromDate: date1 toDate: date2 options: 0];
days = [components day];

Дайте также неверный результат.

1 Ответ

1 голос
/ 30 июня 2019

Вы можете преобразовать каждое значение NSDate в значение NSDateComponents, используя метод NSCalendar componentsInTimeZone:fromDate:. Это даст вам значения года, месяца и дня для ваших двух дат, теперь реализуйте алгоритм разницы, который может быть:

  • вычтите более раннюю дату из большего - вы можете определить это на основе сравнения двух NSDate значений
  • разница в году - это просто вычитание составляющих года из значений NSDateComponents
  • разница в месяце - это разница между компонентами месяца, если она отрицательная, добавьте 12
  • разница в днях аналогична, но в отрицательном случае вы должны добавить длину месяца, которая равна 28, 29, 30 или 31 - вычисление, которое оставлено в качестве упражнения :-) (NSCalendar / NSDate Методы должны помочь здесь)

Хотя это предположение о вашем требуемом алгоритме может быть неверным, каким бы ни был ваш алгоритм, вы сможете реализовать его на основе компонентов года, месяца и дня. НТН

Update

Итак, мое первое предположение о вашем алгоритме было неверным, второе - о ваших трех различиях; годы, месяцы, дни; все они должны быть независимыми приближениями разницы в соответствующей единице. Таким образом, разница в году игнорирует месяцы, дни и время; разница месяцев игнорирует дни и время; и разница в днях игнорирует время. Вот почему 31 мая и 1 июня разделены на «1 месяц» - день игнорируется. Это предположение также может быть неверным, но вот как это сделать:

  • закажите две даты, чтобы разница была положительной.
  • получить только компоненты года, месяца и дня (или получить их все, а затем отбросить остальные) - это отбросит компонент времени. Используйте для этого один из методов NSCalendar.
  • разница между годами - это разница между компонентами года
  • разница в месяце - это разница между компонентами месяца (которая может быть отрицательной) плюс 12-кратная разница в году
  • разницу в днях можно найти с помощью components:fromDateComponents:toDateComponents:options:, запрашивая только компонент дня

[Примечание: будьте осторожны, используя тот же часовой пояс, что и исходные даты - это немного сложно, поскольку вам может понадобиться извлечь его из строк даты самостоятельно (извлеките + hhmm и создайте часовой пояс). Вы должны помнить, что NSDate не хранит часовой пояс, это просто абсолютный момент времени (поэтому эквивалентное время в разных часовых поясах дает одинаковое значение NSDate), и для ваших расчетов вы хотите, чтобы они основывались на исходном времени Зона, как два раза один и тот же день в одном часовом поясе, может быть в разные дни в другом часовом поясе ...). Вы можете установить часовой пояс экземпляра NSCalendar или использовать методы, которые принимают часовые пояса при преобразовании из NSDate в NSDateComponents]

...