【问题标题】:Problem calculating relative time in Objective-C在 Objective-C 中计算相对时间的问题
【发布时间】:2011-09-04 18:25:53
【问题描述】:

我有以下数据:

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

【问题讨论】:

  • 你如何定义SECONDS_IN_MIN等?
  • 你做了什么来尝试自己调试这个?
  • @omz #define SECONDS_IN_MIN 60
  • 我认为你没有向我们展示什么。此外,如果您设置断点并使用调试器单步执行它,您应该能够在短时间内找出它。

标签: iphone objective-c cocoa-touch nsdate nsdateformatter


【解决方案1】:

我建议使用NSCalendar- (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts 方法来获取从现在到您的日期之间的相对时间单位,使用如下内容:

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 会给您一个更可靠的答案。

【讨论】:

    【解决方案2】:

    顺便说一句——如果interval-2517.0,你应该检查(interval < -60)。如果你所有的时间都过去了,你所有的宏都应该被定义为负数,你的比较应该是<,而不是>。考虑到这一点,不确定您的小时时间是如何格式化的...

    如果您的时间可以是未来或过去,您可能希望在所有比较中都使用(fabs(interval) > SECONDS_IN_UNIT)(并将它们定义为正面)。

    【讨论】:

    • 这不应该是您其他答案的补充,而不是单独的帖子吗?
    • 是的 Ben,如果您有补充,只需更新/编辑到您的原始答案。
    • 啊。如果我把它分成两个不同的方向(a la'现在完全不同的东西'),我通常会把它分成两部分。但是如果社区认为这个禁忌,我可以从这里开始做一个。
    猜你喜欢
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2014-09-29
    相关资源
    最近更新 更多