如果零小时,我怎样才能使NSDateFormatter不包含小时数?

时间:2012-09-02 19:22:51

标签: objective-c ios time nsdate nsdateformatter

我正在使用NSDateFormatter格式化一段时间(see here)。

我想使用这样的格式:“3小时15分钟” 这是我正在使用的格式字符串:@"H' hours, 'm' minutes'"

问题在于,对于持续时间不足一小时,结果类似于“0小时35分钟”。
我只想在这样的情况下显示“35分钟”。

有没有办法告诉NSDateFormatter根本没有显示小时数,或者我应该只使用if语句并手动构造字符串?

修改
我很清楚这很容易用一些额外的线条手动完成,这就是我过去的做法。我只是想知道格式化程序是否有足够的智能来处理它本身,因为它似乎是一个常见的问题。

6 个答案:

答案 0 :(得分:3)

从iOS 8.0和Mac OS X 10.10(Yosemite)开始,您可以使用NSDateComponentsFormatter。因此,让我们将小时和分钟用作allowedUnits(如您的示例中)和NSDateComponentsFormatterZeroFormattingBehaviorDropLeading作为zeroFormattingBehavior来减少零小时。例如:

NSTimeInterval intervalWithHours = 11700; // 3:15:00
NSTimeInterval intervalWithZeroHours = 2100; // 0:35:00
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.allowedUnits = NSCalendarUnitHour | NSCalendarUnitMinute;
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropLeading;
NSString *string = [formatter stringFromTimeInterval:intervalWithHours];
NSString *stringWithoutHours = [formatter stringFromTimeInterval:intervalWithZeroHours];
NSLog(@"%@ / %@", string, stringWithoutHours);
// output: 3 hours, 15 minutes / 35 minutes

答案 1 :(得分:2)

一旦你有了日期字符串(让我们称之为 foo ),只需通过发送stringByReplacingOccurencesOfString:withString:来创建另一个字符串。例如:

NSString* foo = @"0 hours, 35 minutes";
NSString* bar = [foo stringByReplacingOccurrencesOfString:@"0 hours, " withString:@"" options:0 range:NSMakeRange(0,9)];
NSLog(@"%@",bar);

输出是:

35 minutes

我怀疑与其他可能的方法相比,这是非常有效的,但除非你必须对数百个字符串进行操作,否则它可能无关紧要。

编辑:此外,如果您希望能够获得没有0小时的日期,并假设您正在使用stringFromDate:您可以添加一个类别来添加如下方法:

- (NSString *)stringFromDateWithoutZeroHours:(NSDate *)date{
    result = [self stringFromDate:date];
    return [result stringByReplacingOccurrencesOfString:@"0 hours, " withString:@"" options:0 range:NSMakeRange(0,9)];
}

答案 2 :(得分:1)

为什么不创建自己的NSDateFormatter子类并覆盖stringFromDate(如果这就是你要调用的)这个案例?

答案 3 :(得分:1)

以下是使用NSCalendar和NSDateComponents进行此操作的一种方法:

static NSString *stringWithTimeInterval (NSTimeInterval interval)
{
    NSDate *referenceDate = [NSDate dateWithTimeIntervalSince1970:0];
    NSDate *intervalDate = [NSDate dateWithTimeIntervalSince1970:interval];

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit fromDate:referenceDate toDate:intervalDate options:0];

    NSMutableArray *stringComponents = [NSMutableArray array];

    NSInteger hours = [components hour];
    NSInteger minutes = [components minute];

    if (hours > 0) {
        [stringComponents addObject:[NSString stringWithFormat:@"%ld hours", hours]];
    }
    [stringComponents addObject:[NSString stringWithFormat:@"%ld minutes", minutes]];

    return [stringComponents componentsJoinedByString:@" "];
}

答案 4 :(得分:0)

好的,我要从Rob Mayoff窃取一些代码:

他的原创(稍加修改):

-(NSString*) doit:(NSTimeInterval)timeInterval {
    NSUInteger seconds = (NSUInteger)round(timeInterval);
    NSString *result = [NSString stringWithFormat:@"%u hours, %u minutes", seconds / 3600, (seconds / 60) % 60];
    return result;
}

有/无“小时”返回的简单修改:

-(NSString*) doit:(NSTimeInterval)timeInterval {
    NSString* result = nil;
    NSUInteger seconds = (NSUInteger)round(timeInterval);
    NSUInteger hours = seconds / 3600;
    NSUInteger minutes = (seconds / 60) % 60;
    if (hours > 0) {
        result = [NSString stringWithFormat:@"%u hours, %u minutes", hours, minutes];
    }
    else {
        result = [NSString stringWithFormat:@"%u minutes", minutes];
    }
    return result;
}

再次,但取消了if

-(NSString*) doit:(NSTimeInterval)timeInterval {
    NSUInteger seconds = (NSUInteger)round(timeInterval);
    NSUInteger hours = seconds / 3600;
    NSUInteger minutes = (seconds / 60) % 60;
    NSString* result = hours ? [NSString stringWithFormat:@"%u hours, %u minutes", hours, minutes] : [NSString stringWithFormat:@"%u minutes", minutes];
    return result;
}

现在,我可以使用,将其归结为荒谬的单线程,但这有点愚蠢,并且不会使代码更清晰。

(请注意,由于iOS 12/24“fechure”,所有使用NSDateFormatter的方案都被破坏了。)

答案 5 :(得分:0)

根据@ matt的回答,我已成功使用他的方法进行条件日期格式化。我的情况我只是希望每个月的第一天,也就是一天。我需要为CorePlot提供一个日期格式化程序来进行轴格式化,它必须是有条件的。

@interface MyNSDateFormatter : NSDateFormatter
@property (nonatomic) NSDateFormatter *dateFormatterFirstDay;
@property (nonatomic) NSDateFormatter *dateFormatterTheRest;
@end

@implementation MyNSDateFormatter
-(id)init
{
    self = [super init];
    if(self != nil)
        {
        _dateFormatterFirstDay = [[NSDateFormatter alloc] init];
        _dateFormatterTheRest = [[NSDateFormatter alloc] init];

        [_dateFormatterFirstDay setDateFormat:@"MMM"];
        [_dateFormatterTheRest setDateFormat:@"d"];
    }
    return self;
}

-(NSString *)stringFromDate:(NSDate *)date
{
    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSDayCalendarUnit fromDate:date];
    if ([dateComponents day] == 1) return [_dateFormatterFirstDay stringFromDate:date];
    else return [_dateFormatterTheRest stringFromDate:date];
}
@end