Pergunta

Como verificar se um NSDate pertence hoje?

Eu costumava verificar usando os primeiros 10 caracteres de [aDate description]. [[aDate description] substringToIndex:10] retorna string como "YYYY-MM-DD" então comparei a string com a string retornada por [[[NSDate date] description] substringToIndex:10].

Existe uma maneira mais rápida e/ou simples de verificar?

Obrigado.

Foi útil?

Solução

No MacOS 10.9+ e iOS 8+, há um método no NSCalendar/Calendário que faz exatamente isso!

- (BOOL)isDateInToday:(NSDate *)date 

Então você simplesmente faria

Objective-C:

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

Swift 3:

let today = Calendar.current.isDateInToday(date)

Outras dicas

Você pode comparar os componentes da data:

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
}

Editar:

Eu gosto mais do método de Stefan, acho que é uma instrução mais limpa e compreensível se:

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
}

Chris, eu incorporei sua sugestão. Eu tive que procurar o que era a época, então, para qualquer outra pessoa que não saiba, ele distingue entre BC e AD. Provavelmente, isso é desnecessário para a maioria das pessoas, mas é fácil verificar e acrescenta alguma certeza, então eu o incluí. Se você está indo para a velocidade, provavelmente não é um bom método.


NOTA Como em muitas respostas, depois de 7 anos, isso está totalmente desatualizado. Em Swift agora apenas use .isDateInToday

Esta é uma ramificação para sua pergunta, mas se você quiser imprimir um nsdate com "hoje" ou "ontem", use a função

- (void)setDoesRelativeDateFormatting:(BOOL)b

para nsdateFormatter

Eu tentaria obter a data de hoje normalizada até a meia -noite e a segunda data, normalizando para a meia -noite e compare se é o mesmo nsdate.

A partir de Um exemplo da Apple Veja como você normaliza para a data de hoje da meia -noite, faça o mesmo para o segundo encontro e compare:

NSCalendar * gregorian = [[NSCalendar alloc]
                               initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents * components =
    [gregorian components:
                 (NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit)
                 fromDate:[NSDate date]];
NSDate * today = [gregorian dateFromComponents:components];

Trabalhando Extensão Swift 3 e 4 da sugestão de Catfish_man:

extension Date {

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

}

Não há necessidade de fazer malabarismos com componentes, épocas e outras coisas.

O NSCalendar fornece um método para obter o início de uma determinada unidade de tempo para uma data existente.

Este código terá o início de hoje e outra data e comparará isso. Se avaliar para NSOrderedSame, ambas as datas estão no mesmo dia - então hoje.

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
}
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)
}

Trabalhou para mim no Swift 2.0

Versão rápida da melhor resposta:

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
}

Consulte a entrada de documentação da Apple, intitulada "Cálculos de calendário de execução" link.

A lista 13 nessa página sugere que, para determinar o número de meia -noite entre os dias, você usa:

- (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;
}

Você pode determinar se dois dias são iguais usando esse método e vendo se ele retorna 0 ou não.

Eu descobri o problema.Então, quando eu crio um link de menu para a visualização do meu componente, ele duplica os parâmetros do componente na lista de parâmetros do item de menu.Por isso, substitui os principais parâmetros do componente.É por isso que, se eu alterar o valor de parâmetro na janela de parâmetros dos componentes (na zona de administração), obtenho somente os valores de parâmetros que estão na janela de itens de menu.Também encontrou mais algumas informações sobre isso no Fórum Joomla: http://forum.joomla.org / viewtopic.php? f= 304 & t= 485837

Extensão rápida com base nas melhores respostas:

extension NSDate {
    func isToday() -> Bool {
        let cal = NSCalendar.currentCalendar()
        if cal.respondsToSelector("isDateInToday:") {
            return cal.isDateInToday(self)
        }
        var components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:NSDate())
        let today = cal.dateFromComponents(components)!

        components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:self);
        let otherDate = cal.dateFromComponents(components)!
        return today.isEqualToDate(otherDate)
    }
}

Se você tem muitas dessas comparações de data, as chamadas para calendar:components:fromDate Comece a demorar muito tempo. De acordo com alguns perfis que fiz, eles parecem muito caros.

Diga que você está tentando determinar qual de alguma variedade de datas, digamos NSArray *datesToCompare, são o mesmo dia que um dado dia, digamos NSDate *baseDate, então você pode usar algo como o seguinte (parcialmente adaptado de uma resposta acima):

NSDate *baseDate = [NSDate date];

NSArray *datesToCompare = [NSArray arrayWithObjects:[NSDate date], 
                           [NSDate dateWithTimeIntervalSinceNow:100],
                           [NSDate dateWithTimeIntervalSinceNow:1000],
                           [NSDate dateWithTimeIntervalSinceNow:-10000],
                           [NSDate dateWithTimeIntervalSinceNow:100000],
                           [NSDate dateWithTimeIntervalSinceNow:1000000],
                           [NSDate dateWithTimeIntervalSinceNow:50],
                           nil];

// determine the NSDate for midnight of the base date:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) 
                                       fromDate:baseDate];
NSDate* theMidnightHour = [calendar dateFromComponents:comps];

// set up a localized date formatter so we can see the answers are right!
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];

// determine which dates in an array are on the same day as the base date:
for (NSDate *date in datesToCompare) {
    NSTimeInterval interval = [date timeIntervalSinceDate:theMidnightHour];
    if (interval >= 0 && interval < 60*60*24) {
        NSLog(@"%@ is on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]);
    }
    else {
        NSLog(@"%@ is NOT on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]);
    }
}

Resultado:

Nov 23, 2011 1:32:00 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:33:40 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:48:40 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 10:45:20 AM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 24, 2011 5:18:40 PM is NOT on the same day as Nov 23, 2011 1:32:00 PM
Dec 5, 2011 3:18:40 AM is NOT on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:32:50 PM is on the same day as Nov 23, 2011 1:32:00 PM

Há uma maneira mais fácil do que muitas das respostas acima!

NSDate *date = ... // The date you wish to test
NSCalendar *calendar = [NSCalendar currentCalendar];

if([calendar isDateInToday:date]) {
    //do stuff
}

Provavelmente isso poderia ser reformulado como uma categoria NSDATE, mas eu usei:

// Seconds per day (24h * 60m * 60s)
#define kSecondsPerDay 86400.0f

+ (BOOL) dateIsToday:(NSDate*)dateToCheck
{
    // Split today into components
    NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents* comps = [gregorian components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit) 
                                        fromDate:[NSDate date]];

    // Set to this morning 00:00:00
    [comps setHour:0];
    [comps setMinute:0];
    [comps setSecond:0];
    NSDate* theMidnightHour = [gregorian dateFromComponents:comps];
    [gregorian release];

    // Get time difference (in seconds) between date and then
    NSTimeInterval diff = [dateToCheck timeIntervalSinceDate:theMidnightHour];
    return ( diff>=0.0f && diff<kSecondsPerDay );
}

(No entanto, comparar as duas seqüências de data como na pergunta original quase parece 'mais limpa' ..)

para iOS7 e antes:

//this is now => need that for the current date
NSDate * now = [NSDate date];

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];

NSDateComponents * components = [calendar components:( NSYearCalendarUnit|    NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate: now];

[components setMinute:0];
[components setHour:0];
[components setSecond:0];

//this is Today's Midnight
NSDate *todaysMidnight = [calendar dateFromComponents: components];



//now timeIntervals since Midnight => in seconds
NSTimeInterval todayTimeInterval = [now timeIntervalSinceDate: todaysMidnight];

//now timeIntervals since OtherDate => in seconds
NSTimeInterval otherDateTimeInterval = [now timeIntervalSinceDate: otherDate];

if(otherDateTimeInterval > todayTimeInterval) //otherDate is not in today
{
    if((otherDateTimeInterval - todayTimeInterval) <= 86400) //86400 == a day total seconds
    {
        @"yesterday";
    }
    else
    {
        @"earlier";
    }
}
else
{
    @"today";
}


now = nil;
calendar = nil;
components = nil;
todaysMidnight = nil;

NSLog("Thank you :-)");

Verifique o nosso Erica Sadun é ótimo NSDate extension. Muito simples de usar. Bem aqui:

http://github.com/erica/nsdate-extensions

Já está lá neste post: https://stackoverflow.com/a/4052798/362310

A solução correta e segura sem a torneira de força, trabalhando no Swift 2.2 e antes do iOS 8:

func isToday() -> Bool {
    let calendar = NSCalendar.currentCalendar()
    if #available(iOS 8.0, *) {
        return calendar.isDateInToday(self)
    }

    let todayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
    let dayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:self)

    guard let today = calendar.dateFromComponents(todayComponents),
        day = calendar.dateFromComponents(dayComponents) else {
        return false
    }

    return today.compare(day) == .OrderedSame
}

Aqui está minha resposta de 2 centavos com a resposta aceita, mas também apoia a API mais recente. Nota: Eu uso o calendário gregoriano como a maioria dos carimbos de hora é GMT, mas mude o seu como você achar adequado

func isDateToday(date: NSDate) -> Bool {
    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    if calendar.respondsToSelector("isDateInToday:") {
        return calendar.isDateInToday(date)
    }
    let dateComponents = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay
    let today = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: NSDate()))!
    let dateToCompare = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: date))!

    return dateToCompare == today
}

Minha solução é calcular quantos dias se passaram desde 1970 por divisão e comparar a parte inteira

#define kOneDay (60*60*24)
- (BOOL)isToday {
  NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];

  NSInteger days =[self timeIntervalSince1970] + offset;
  NSInteger currentDays = [[NSDate date] timeIntervalSince1970] + offset;
  return (days / kOneDay == currentDays / kOneDay);
}

Registre o serviço selecionando um dos seus aplicativos da Web conforme o exemplo fornecido acima.Depois de registrá-lo (neste caso, para "Collab"), você deve ser capaz de verificar se os fluxos de trabalho de 2013 agora funcionam no SharePoint Designer 2013 para qualquer site que reside dentro do aplicativo da Web "Collab".

Se você tiver outros aplicativos da Web onde você personalizou os aplicativos de serviço, então você precisará ativá-los como qualquer outro serviço compartilhado.Se você tiver outros aplicativos da Web com os serviços padrão, o serviço de fluxo de trabalho de 2013 deve estar funcionando.Então não, você não executa o comando várias vezes.Apenas uma vez.Em seguida, gerencie o serviço no Admin Central do SharePoint.

Eu resumi isso no meu post do blog aqui:

http://forde-design.com/?p=1

Chuck Laforte Projeto Forte

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top