2011-02-08 18 views
13

Qualcuno sa di una libreria o qualcosa che convertirà un NSDate in stringhe come gli esempi seguenti?Stringa relativa da NSDate

1 hour ago 
yesterday 
last Thursday 
2 days ago 
last month 
6 months ago 
last year 

risposta

16

NSDateFormatter farà una grande quantità di ciò che viene detto sopra utilizzando setDoesRelativeDateFormatting: su un'istanza. Da lì, puoi controllare la formattazione usando lo stile della data e lo stile temporale per adattarlo alle tue esigenze.

Se ciò non ti dà quello che ti serve, controlla SORelativeDateTransformer, è una sottoclasse NSValueTransformer che tenta di fornire lo stesso comportamento che vedi con date relative su SO.

Infine, se si desidera eseguire da soli o effettuare ulteriori ricerche, ecco la (probabile) domanda originale sull'argomento ... yes it is question 11.

+1

Divertente, ho * mai * visto quel metodo su 'NSDateFormatter' prima, e giuro di averlo cercato ... –

+0

Risposta impressionante e molto accurata! SORelativeDateTransformer è esattamente quello che sto cercando e anche conoscere NSDateFormatter è utile. – keegan3d

+4

Vale la pena notare che 'NSDateFormatter' ha solo una manciata di queste stringhe relative. È praticamente solo "Domani", "Oggi" e "Ieri". –

16

Ai posteri, ecco un metodo di categoria NSDate ho buttato insieme che utilizza il calcolo relatività Stack Overflow legati da David così come altri suggerimenti acciottolato da altre simili SO domande:

- (NSString *)relativeDateString 
{ 
    const int SECOND = 1; 
    const int MINUTE = 60 * SECOND; 
    const int HOUR = 60 * MINUTE; 
    const int DAY = 24 * HOUR; 
    const int MONTH = 30 * DAY; 

    NSDate *now = [NSDate date]; 
    NSTimeInterval delta = [self timeIntervalSinceDate:now] * -1.0; 

    NSCalendar *calendar = [NSCalendar currentCalendar]; 
    NSUInteger units = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit); 
    NSDateComponents *components = [calendar components:units fromDate:self toDate:now options:0]; 

    NSString *relativeString; 

    if (delta < 0) { 
     relativeString = @"!n the future!"; 

    } else if (delta < 1 * MINUTE) { 
     relativeString = (components.second == 1) ? @"One second ago" : [NSString stringWithFormat:@"%d seconds ago",components.second]; 

    } else if (delta < 2 * MINUTE) { 
     relativeString = @"a minute ago"; 

    } else if (delta < 45 * MINUTE) { 
     relativeString = [NSString stringWithFormat:@"%d minutes ago",components.minute]; 

    } else if (delta < 90 * MINUTE) { 
     relativeString = @"an hour ago"; 

    } else if (delta < 24 * HOUR) { 
     relativeString = [NSString stringWithFormat:@"%d hours ago",components.hour]; 

    } else if (delta < 48 * HOUR) { 
     relativeString = @"yesterday"; 

    } else if (delta < 30 * DAY) { 
     relativeString = [NSString stringWithFormat:@"%d days ago",components.day]; 

    } else if (delta < 12 * MONTH) { 
     relativeString = (components.month <= 1) ? @"one month ago" : [NSString stringWithFormat:@"%d months ago",components.month]; 

    } else { 
     relativeString = (components.year <= 1) ? @"one year ago" : [NSString stringWithFormat:@"%d years ago",components.year]; 

    } 

    return relativeString; 
} 
1

DateTools è una fantastica struttura completa per l'esecuzione di tutti i tipi di funzioni relative alla data. https://github.com/MatthewYork/DateTools

Come categoria NSDate, è più semplice da utilizzare rispetto a SORelativeDateTransformer.

Tuttavia, c'è un problema con ottenere valori di giorno precisi. (Ad esempio, se oggi è Lunedi mattina, Sabato sera verrà segnalato come "Yesterday", dovrebbe essere "Due giorni fa")

Questo dovrebbe funzionare meglio (utilizzando DateTools):

- (NSString *)relativeDateStringForDate:(NSDate *)d 
{ 
    if ([d daysAgo] < 1) { 
     //Return as is 
     return [d timeAgoSinceNow]; 
    } 
    else { //More than 24 hours ago. The default implementation will underreport (round down) day durations. 
      //We should modify the reference date we're using to midnight on the current day. 

     NSDate *date = [NSDate date]; 
     date = [date dateByAddingDays:1]; 
     NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar]; 
     NSUInteger preservedComponents = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit); 
     NSDate *todayAtMidnight = [calendar dateFromComponents:[calendar components:preservedComponents fromDate:date]]; 

     return [d timeAgoSinceDate:todayAtMidnight]; 

    } 
} 
5

non utilizzare la tua traduzione di stringhe personalizzata. Scrivere la tua traduzione che fa qualcosa come "3 secondi fa" non ha solo il problema di dover essere aggiornato costantemente, ma non si localizza anche in altre lingue.

Al contrario, utilizzare Apple integrato in NSDateFormatter:

Questa volontà di uscita qualcosa come "Oggi, 23:10", oppure "7/17/14, 05:44".