Задача расчета относительного времени в Objective-C - PullRequest
0 голосов
/ 04 сентября 2011

У меня есть следующие данные:

 ----
ORIGINAL TIME 2011-09-04 12:04:36
FORMATTED TIME 2011-09-04T12:04:36-0700
RELATIVE TIME: 2517s ago
 ----
ORIGINAL TIME 2011-09-04 11:40:17
FORMATTED TIME 2011-09-04T11:40:17-0700
 RELATIVE TIME: 1058s ago
 ----
ORIGINAL TIME 2011-09-04 08:05:00
FORMATTED TIME 2011-09-04T08:05:00-0700
RELATIVE TIME: 3h ago
----
ORIGINAL TIME 2011-09-04 07:16:00
FORMATTED TIME 2011-09-04T07:16:00-0700
RELATIVE TIME: 4h ago

У меня есть код для вычисления относительного времени (я передаю в отформатированном времени):

+(NSString*)toShortTimeIntervalString:(NSString*)sDate  
{ 
    NSDateFormatter* df = [[NSDateFormatter alloc]init];
    [df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
    NSDate* date = [df dateFromString:[sDate stringByReplacingOccurrencesOfString:@"Z" withString:@"-0000"]];
    [df release];

    NSDate* today = [[NSDate alloc] init];
    NSDate *d = date; //[_twitter_dateFormatter dateFromString:sDate];
    NSTimeInterval interval = [today timeIntervalSinceDate:d];
    [today release];

    //TODO: added ABS wrapper
    double res = 0;
    NSString* result;
    if(interval > SECONDS_IN_WEEK)
    {
        res = fabs(interval / SECONDS_IN_WEEK);
        result = [NSString stringWithFormat:@"%1.0fw ago", res];
    }
    else if(interval > SECONDS_IN_DAY)
    {
        res = fabs(interval / SECONDS_IN_DAY);
        result = [NSString stringWithFormat:@"%1.0fd ago", res];
    }
    else if (interval > SECONDS_IN_HOUR){
        res = fabs(interval / SECONDS_IN_HOUR);
        result = [NSString stringWithFormat:@"%1.0fh ago", res];
    }
    else if (interval > SECONDS_IN_MIN) {
        res = fabs(interval / SECONDS_IN_MIN);
        result = [NSString stringWithFormat:@"%1.0fm ago", res];
    }
    else
    {
        interval = fabs(interval);
        result = [NSString stringWithFormat:@"%1.0fs ago", interval];
    }
    return result;
}

Почему я получаю2517s ago когда он действительно не должен выводить это как секунды.Это должно быть 41m ago

Интервал в этом случае составляет -2517.0

Ответы [ 2 ]

0 голосов
/ 04 сентября 2011

Кстати - если interval равно -2517.0, вы должны проверить (interval < -60).Если все ваши времена в прошлом, все ваши макросы должны быть определены как отрицательные, и ваши сравнения должны быть <, а не >.Не уверен, как ваши часы были отформатированы таким образом, учитывая это ...

Вы можете захотеть сделать (fabs(interval) > SECONDS_IN_UNIT) (и определить их положительные значения) во всех ваших сравнениях, если ваши времена могут быть в будущем или прошлом.

0 голосов
/ 04 сентября 2011

Я бы рекомендовал использовать - (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts метод NSCalendar, чтобы получить относительные единицы времени между сейчас и вашими датами, используя что-то вроде этого:

NSDate *dateToCompare = pointerToYourDatePulledFromTheStringRep;
NSInteger numberOfUnits;
NSString *unitString;
NSDateComponents *comps = [[NSCalendar currentCalendar] 
                          components:(NSWeekCalendarUnit | 
                                       NSDayCalendarUnit | 
                                      NSHourCalendarUnit | 
                                    NSMinuteCalendarUnit | 
                                    NSSecondCalendarUnit) 
                           fromDate:dateToCompare 
                             toDate:[NSDate date]
                            options:0];
if ([comps week] > 0) {
   numberOfUnits = [comps week];
   unitString = @"week";
} else if ([comps day] > 0) {
   numberOfUnits = [comps day];
   unitString = @"day";
} else if... // hour, minute, second

result = [NSString stringWithFormat:@"%d %@%@",
                                    numberOfUnits,
                                    unitString,
                                    (numberOfUnits != 1 ? @"s" : @"")]; 
                                    // last bit deals with plurality

Таким образом, функции ОС работаютсо всей математикой для фиников, и вы получаете преимущества точности и совместимости с несколькими календарями.

Что касается вашего вопроса (технически) о том, почему ваши секунды выходят НЕ как минуты, я бы предположилчто SECONDS_IN_MIN определено неправильно.Но, опять же, использование NSCalendar дает более надежный ответ.

...