我正在使用NSDateFormatter格式化一段时间(see here)。
我想使用这样的格式:“3小时15分钟”
这是我正在使用的格式字符串:@"H' hours, 'm' minutes'"
。
问题在于,对于持续时间不足一小时,结果类似于“0小时35分钟”。
我只想在这样的情况下显示“35分钟”。
有没有办法告诉NSDateFormatter根本没有显示小时数,或者我应该只使用if语句并手动构造字符串?
修改
我很清楚这很容易用一些额外的线条手动完成,这就是我过去的做法。我只是想知道格式化程序是否有足够的智能来处理它本身,因为它似乎是一个常见的问题。
答案 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