Как определить, есть ли NSDate сегодня? - PullRequest
147 голосов
/ 25 февраля 2010

Как проверить, принадлежит ли NSDate сегодня?

Я проверял это, используя первые 10 символов из [aDate description]. [[aDate description] substringToIndex:10] возвращает строку как "YYYY-MM-DD", поэтому я сравнил строку со строкой, возвращенной [[[NSDate date] description] substringToIndex:10].

Есть ли более быстрый и / или аккуратный способ проверки?

Спасибо.

Ответы [ 20 ]

295 голосов
/ 24 марта 2014

В macOS 10.9+ и iOS 8+ в NSCalendar / Calendar есть метод, который делает именно это!

- (BOOL)isDateInToday:(NSDate *)date 

Так что вы просто сделаете

Objective-C:

BOOL today = [[NSCalendar currentCalendar] isDateInToday:date];

Swift 3:

let today = Calendar.current.isDateInToday(date)
192 голосов
/ 25 февраля 2010

Вы можете сравнить компоненты даты:

NSDateComponents *otherDay = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:aDate];
NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]];
if([today day] == [otherDay day] &&
   [today month] == [otherDay month] &&
   [today year] == [otherDay year] &&
   [today era] == [otherDay era]) {
    //do stuff
}

Edit:

Мне больше нравится метод Стефана, я думаю, он делает более понятным и понятным утверждение if:

NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]];
NSDate *today = [cal dateFromComponents:components];
components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:aDate];
NSDate *otherDate = [cal dateFromComponents:components];

if([today isEqualToDate:otherDate]) {
    //do stuff
}

Крис, я включил ваше предложение. Мне пришлось посмотреть, какая была эпоха, поэтому для тех, кто не знает, она различает BC и AD. Это, вероятно, не нужно для большинства людей, но это легко проверить и добавить определенность, поэтому я включил его. Если вы идете на скорости, это, вероятно, не очень хороший метод в любом случае.


ПРИМЕЧАНИЕ Как и во многих ответах по SO, через 7 лет это полностью устарело. В Swift сейчас просто используйте .isDateInToday

27 голосов
/ 29 января 2011

Это ответ на ваш вопрос, но если вы хотите напечатать NSDate с «Сегодня» или «Вчера», используйте функцию

- (void)setDoesRelativeDateFormatting:(BOOL)b

для NSDateFormatter

16 голосов
/ 25 февраля 2010

Я бы попытался нормализовать сегодняшнюю дату до полуночи, а вторую - нормализовать до полуночи, а затем сравнить, если это тот же NSDate.до полуночи сегодняшней даты, сделайте то же самое для второй даты и сравните:

NSCalendar * gregorian = [[NSCalendar alloc]
                               initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents * components =
    [gregorian components:
                 (NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit)
                 fromDate:[NSDate date]];
NSDate * today = [gregorian dateFromComponents:components];
13 голосов
/ 06 сентября 2016

Работает Расширение Swift 3 & 4 предложения от Catfish_Man:

extension Date {

    func isToday() -> Bool {
        return Calendar.current.isDateInToday(self)
    }

}
12 голосов
/ 14 июля 2013

Не нужно жонглировать компонентами, эпохами и прочим.

NSCalendar предоставляет метод для получения начала определенной единицы времени для существующей даты.

Этот код получит начало сегодняшнего дня и другую дату и сравнит это. Если оно оценивается как NSOrderedSame, обе даты относятся к одному и тому же дню - так и сегодня.

NSDate *today = nil;
NSDate *beginningOfOtherDate = nil;

NSDate *now = [NSDate date];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&today interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfOtherDate interval:NULL forDate:beginningOfOtherDate];

if([today compare:beginningOfOtherDate] == NSOrderedSame) {
    //otherDate is a date in the current day
}
8 голосов
/ 03 ноября 2015
extension NSDate {
  func isToday() -> Bool {
    let cal = NSCalendar.currentCalendar()
    var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
    let today = cal.dateFromComponents(components)!

    components = cal.components([.Era, .Year, .Month, .Day], fromDate:self)
    let otherDate = cal.dateFromComponents(components)!

    return today.isEqualToDate(otherDate)
}

работал для меня на Swift 2.0

6 голосов
/ 09 апреля 2015

Свифт версия лучшего ответа:

let cal = NSCalendar.currentCalendar()
var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
let today = cal.dateFromComponents(components)!

components = cal.components([.Era, .Year, .Month, .Day], fromDate:aDate);
let otherDate = cal.dateFromComponents(components)!

if(today.isEqualToDate(otherDate)) {
    //do stuff
}
5 голосов
/ 25 февраля 2010

Вы также можете проверить интервал времени между вашей датой и текущей датой:

[myDate timeIntervalSinceNow]

Это даст вам интервал времени в секундах между myDate и текущей датой / временем.

Ссылка .

Редактировать: Примечание для всех: я хорошо знаю, что [myDate timeIntervalSinceNow] не однозначно определяет, является ли myDate сегодня.

Я оставляю этот ответ как есть, так что если кто-то ищет что-то подобное и [myDate timeIntervalSinceNow] полезен, он может найти его здесь.

5 голосов
/ 14 июля 2013

См. Запись в документации Apple, озаглавленную «Выполнение расчетов по календарю» [ссылка] .

Листинг 13 на этой странице предполагает, что для определения количества полудней между днями вы используете:

- (NSInteger)midnightsFromDate:(NSDate *)startDate toDate:(NSDate *)endDate
{
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSInteger startDay = [calendar ordinalityOfUnit:NSDayCalendarUnit
                                             inUnit:NSEraCalendarUnit
                                            forDate:startDate];
    NSInteger endDay = [calendar ordinalityOfUnit:NSDayCalendarUnit
                                           inUnit:NSEraCalendarUnit
                                          forDate:endDate];
    return endDay - startDay;
}

Затем вы можете определить, совпадают ли два дня, используя этот метод, и посмотреть, возвращает ли он 0 или нет.

...