2012-04-09 17 views
9

Ho bisogno di visualizzare la data dei post nella mia app per l'utente, ora lo faccio in questo formato: "Ven, 25 maggio". Come modifico un NSDate per leggere qualcosa come "2 ore fa"? Per renderlo più user friendly.iOS - Formato NSDate amichevole

+1

possibile duplicato del [intelligente formattazione del lasso di tempo] (http://stackoverflow.com/questions/5741952/smart-formatting-of-time-span) – dasblinkenlight

+0

di controllo [ questa risposta] (http://stackoverflow.com/a/34359788/1106035) che ha un link di esempio. –

risposta

8

NSDateFormatter non può fare cose del genere; avrai bisogno di stabilire le tue regole. Credo che qualcosa di simile:

- (NSString *)formattedDate:(NSDate *)date 
{ 
    NSTimeInterval timeSinceDate = [[NSDate date] timeIntervalSinceDate:date]; 

    // print up to 24 hours as a relative offset 
    if(timeSinceDate < 24.0 * 60.0 * 60.0) 
    { 
     NSUInteger hoursSinceDate = (NSUInteger)(timeSinceDate/(60.0 * 60.0)); 

     switch(hoursSinceDate) 
     { 
       default: return [NSString stringWithFormat:@"%d hours ago", hoursSinceDate]; 
       case 1: return @"1 hour ago"; 
       case 0: 
        NSUInteger minutesSinceDate = (NSUInteger)(timeSinceDate/60.0); 
        /* etc, etc */ 
       break; 
     } 
    } 
    else 
    { 
      /* normal NSDateFormatter stuff here */ 
    } 
} 

Ecco, questo è per la stampa 'x minuti fa' o 'x ore fa' fino a 24 ore dalla data, che di solito è un giorno.

35

Date un'occhiata a FormaterKit https://github.com/mattt/FormatterKit

Creato da mattt che ha anche creato AFNetworking.

+1

Questo dovrebbe ottenere upvotes, è un ottimo kit creato da un grande sviluppatore e la sua così facile da usare. –

3

ci sono circa un milione di modi che si potrebbe fare questo, ma ecco una rapida uno:

NSString* hoursAgo = [NSString stringWithFormat:@"%.0lf hours ago", fabs([date timeIntervalSinceNow]/3600.0)] 

Naturalmente, questo non verifica che date è in realtà dal passato, non fa nulla, ma ore, ecc. Ma probabilmente hai un'idea.

timeIntervalSinceNow restituisce quanti secondi sono trascorsi da una determinata data, con numeri positivi che rappresentano una data futura e numeri negativi che rappresentano una data nel passato. Quindi, otteniamo quanti secondi sono passati, lo dividiamo per 3600 secondi in un'ora per calcolare le ore che sono passate e poi mettiamo il suo valore assoluto nella stringa "n ore fa".

4

C'è anche SEHumanizedTimeDiff che fa/è in procinto di supportare più lingue, se questo è un problema per voi:

https://github.com/sarperdag/SEHumanizedTimeDiff

+1

Questa è una piccola libreria carina, e la localizzazione da sola merita un voto alto; poiché è qualcosa che nessuna delle altre soluzioni proposte fa. –

+1

Accetto con @CarlosP. Ci sono già un sacco di lingue fornite dagli sguardi. – djskinner

3

Ecco una buona risposta questo richiederà in secondi dall'epoca (1 gennaio, 1970) e ti restituisce una bella stringa formattata come "3 minuti fa". Basta chiamare con il vostro oggetto data in questo modo:

[timeAgoFromUnixTime:[myDateObject timeIntervalSince1970]]; 

+ (NSString *)timeAgoFromUnixTime:(double)seconds 
{ 
    double difference = [[NSDate date] timeIntervalSince1970] - seconds; 
    NSMutableArray *periods = [NSMutableArray arrayWithObjects:@"second", @"minute", @"hour", @"day", @"week", @"month", @"year", @"decade", nil]; 
    NSArray *lengths = [NSArray arrayWithObjects:@60, @60, @24, @7, @4.35, @12, @10, nil]; 
    int j = 0; 
    for(j=0; difference >= [[lengths objectAtIndex:j] doubleValue]; j++) 
    { 
     difference /= [[lengths objectAtIndex:j] doubleValue]; 
    } 
    difference = roundl(difference); 
    if(difference != 1) 
    { 
     [periods insertObject:[[periods objectAtIndex:j] stringByAppendingString:@"s"] atIndex:j]; 
    } 
    return [NSString stringWithFormat:@"%li %@%@", (long)difference, [periods objectAtIndex:j], @" ago"]; 
} 
+1

Se ti aiuta a votare per favore, –

+0

Bello, ha lavorato per me. –

+0

Funzionante perfetto, breve e dolce :) – iChirag

6

Volevo un formato di data come Facebook fa per le loro applicazioni mobili così ho incitato questa categoria NSDate - spero che sia utile per qualcuno (questo genere di cose dovrebbe davvero essere in una libreria standard!) :)

https://github.com/nikilster/NSDate-Time-Ago

+0

Ho esaminato la tua libreria ed è stato molto utile. Ma nella tua biblioteca, cose come "solo ora", "6 minuti fa", "7 ore fa" funzionano bene. Ma voglio anche cose come "3 giorni fa", "4 settimane fa", "2 anni fa". Come ottenere quello fatto? –

+0

Questo è stato creato per imitare lo stile di formato della data di Facebook. È pensato per essere leggibile e facilmente comprensibile (hanno pensato molto a come rappresentare al meglio la data e penso che sia abbastanza chiaro quando lo si utilizza che questo è un buon formato Cose come 4 settimane fa Ti darò abbastanza informazioni specifiche quando guardi ad intervalli di tempo passati Se vuoi ottenere qualcosa del genere, modifica le stringhe che vengono emesse dall'istruzione if –

+0

Ma quello era il requisito della mia azienda e anche io pensavo di visualizzare "3 ottobre alle 12.42am", potrebbe consumare molto spazio, se scrivo "1 w" (una settimana fa) –

3

nelle versioni più recenti di iOS in quanto a questa domanda è stato chiesto, NSDateFormatter ha avuto questa capacità aggiunto. Ora può farlo usando la proprietà doesRelativeDateFormatting.

+0

Non riesco a farlo funzionare. Documenti controllati e non sono sicuro di quello che sto facendo male. Se eseguo la formattazione in una data normale ottengo una stringa, tuttavia se non riesco a impostareDoesRelativeDateFormatting non riesco a ottenere nulla indietro. Idee? Esempio di codice? – lostintranslation

+0

Puoi trovarlo in alcune esercitazioni utilizzando Google, ma penso che dovresti pubblicare la tua domanda come una nuova domanda SO in modo da poter vedere il tuo codice! È difficile dare consigli senza di essa. –

0

aggiungendo alla soluzione provare questo metodo più semplificato

NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:passed toDate:[NSDate date] options:0]; 
    NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date]; 

    if (interval < 60) timestampString = [NSString stringWithFormat:@"%d seconds ago" ,today.second]; 
    else if (interval < 60 * 60) timestampString = [NSString stringWithFormat:@"%d minutes ago" ,today.minute]; 
    else if (interval < 60 * 60 * 24) timestampString = [NSString stringWithFormat:@"%d hours ago" ,today.hour]; 
    else timestampString = [NSString stringWithFormat:@"%d days ago" ,today.day]; 
2
+(NSString*)HourCalculation:(NSString*)PostDate 

{ 
    NSLog(@"postdate=%@",PostDate); 
    // [email protected]"2014-04-02 01:31:04"; 
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
    NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; 
    [dateFormat setTimeZone:gmt]; 
    NSDate *ExpDate = [dateFormat dateFromString:PostDate]; 
    NSLog(@"expdate=%@",ExpDate); 
    NSLog(@"expdate=%@",[NSDate date ]); 
    NSCalendar *calendar = [NSCalendar currentCalendar]; 

    NSDateComponents *components = [calendar components:(NSDayCalendarUnit|NSWeekCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit|NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:ExpDate toDate:[NSDate date] options:0]; 

// NSLog(@"year=%d",components.year); 
//  
// NSLog(@"month=%d",components.month); 
//  
// NSLog(@"week=%d",components.week); 
//  
// NSLog(@"day=%d",components.day); 
//  
// NSLog(@"hour=%d",components.hour); 
//  
// NSLog(@"min=%d",components.minute); 
//  
// NSLog(@"sce=%d",components.second); 
//  

    NSString *time; 

    if(components.year!=0) 
    { 
     if(components.year==1) 
     { 
      time=[NSString stringWithFormat:@"%ld year",(long)components.year]; 
     } 
     else{ 
      time=[NSString stringWithFormat:@"%ld years",(long)components.year]; 
     }  
    } 
    else if(components.month!=0) 
    { 
     if(components.month==1) 
     { 
      time=[NSString stringWithFormat:@"%ld month",(long)components.month]; 
     } 
     else{ 
      time=[NSString stringWithFormat:@"%ld months",(long)components.month]; 
     } 
     // NSLog(@"%@",time); 
    } 
    else if(components.week!=0) 
    { 
     if(components.week==1) 
     { 
      time=[NSString stringWithFormat:@"%ld week",(long)components.week]; 
     } 
     else{ 
      time=[NSString stringWithFormat:@"%ld weeks",(long)components.week]; 
     } 
     // NSLog(@"%@",time); 
    } 
    else if(components.day!=0) 
    { 
     if(components.day==1) 
     { 
      time=[NSString stringWithFormat:@"%ld day",(long)components.day]; 
     } 
     else{ 
      time=[NSString stringWithFormat:@"%ld days",(long)components.day]; 
     } 
    } 
    else if(components.hour!=0) 
    { 
     if(components.hour==1) 
     { 
      time=[NSString stringWithFormat:@"%ld hour",(long)components.hour]; 
     } 
     else{ 
      time=[NSString stringWithFormat:@"%ld hours",(long)components.hour]; 
     } 
    } 
    else if(components.minute!=0) 
    { 
     if(components.minute==1) 
     { 
      time=[NSString stringWithFormat:@"%ld min",(long)components.minute]; 
     } 

     else{ 
      time=[NSString stringWithFormat:@"%ld mins",(long)components.minute]; 
     } 
     // NSLog(@"time=%@",time); 
    } 
    else if(components.second>=0){ 

     // NSLog(@"postdate=%@",PostDate); 

     // NSLog(@"expdate=%@",[NSDate date ]); 

     if(components.second==0) 
     { 
      time=[NSString stringWithFormat:@"1 sec"]; 
     } 
     else{ 
      time=[NSString stringWithFormat:@"%ld secs",(long)components.second]; 
     } 
    } 
    return [NSString stringWithFormat:@"%@ ago",time]; 

} 

Questo codice vi mostrerà il tempo in ------------ sec come 2 secondi fa - ----------- min come 2 minuti fa ------------ ore come 2 ore fa ------------ giorni come 2 giorni fa ------------ settimana come 2 settimane fa ------------ month like 2 months ago Infine .... anni come 2 anni fa :) provare questo