在 Obj-C 中显示负时间

Display a negative time in Obj-C

这听起来很简单,但我不确定该怎么做。如何按以下格式显示时间?:

-00:00:00

我曾尝试使用 float 和 int 值来表示两次之间的间隔差,但是在 00:00:00 格式中都没有给出一致的显示。我也试过将时差转换为日期,然后显示为字符串。

这是我用来转换间隔的代码:

NSDate * now = [NSDate date];
NSTimeInterval totalTime1 = [now timeIntervalSinceDate: timeEntry1];
NSTimeInterval totalTime2 = [now timeIntervalSinceDate: timeEntry2];

//must always be this way
int adjustedTime = totalTime1 - totalTime2;

int hours = adjustedTime / 3600;
int minutes = (adjustedTime / 60) % 60;
int seconds = adjustedTime % 60;

NSString * newTime = [NSString stringWithFormat:@"%02u:%02u:%02u", hours, minutes, seconds];

上面的方法可以很好地显示正时差。但是,当它在 NSLog 和标签中都变为负数时,会出现各种 00:423456:978098 等。

当我转换并保存为 NSDate 类型时,我在 NSLog 中得到 (null) 而在我的 Label 中什么也没有。

当我使用 float 时,它可以工作,但不能始终以 00:00:00 格式显示。

注意

我使用的代码完美无缺地处理正时差。我还需要显示负时差。

我还需要能够将负时间保存到CoreData。如果这不可能,那么我会解决,但显示格式正确的负时间是主要问题。

编辑

我新修改的代码:

NSDate * now = [NSDate date];
NSTimeInterval totalTime1 = [now timeIntervalSinceDate: timeEntry1];
NSTimeInterval totalTime2 = [now timeIntervalSinceDate: timeEntry2];

//must always be this way
int adjustedTime = (int) (totalTime1 - totalTime2);
NSLog (@"What is the adjustedTime? %d", adjustedTime);

int hours = adjustedTime / 3600;
int minutes = (adjustedTime / 60) % 60;
int seconds = adjustedTime % 60;

NSString * newTime = [NSString stringWithFormat:@"%@%02d:%02d:%02d", adjustedTime < 0 ?@"-":@"", hours, minutes, seconds];
NSLog(@"What is the newTime? %@", newTime);

它更近了,因为现在它显示负数,但负数时显示仍然不正确。

编辑 2

下面回答的人建议我尝试检查是否为布尔值。显示没有变化。下面是更多的日志语句来演示。 注意 我停止使用更新的秒数是为了确定它是否影响显示和存储的秒数分开测试,这就是为什么没有 - 标志或更改的原因秒。

2015-01-09 09:30:14.526 App2.0[8398:498707] What is time 2 : 720
2015-01-09 09:30:14.526 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:14.526 App2.0[8398:498707] What is the adjusted time? 51
2015-01-09 09:30:14.527 App2.0[8398:498707] New Time: 00:00:51

2015-01-09 09:30:18.249 App2.0[8398:498707] What is time 2 : 900
2015-01-09 09:30:18.249 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:18.249 App2.0[8398:498707] What is the adjusted time? -129
2015-01-09 09:30:18.249 App2.0[8398:498707] New Time: -00:-2:51

2015-01-09 09:30:20.281 App2.0[8398:498707] What is time 2 : 840
2015-01-09 09:30:20.281 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:20.281 App2.0[8398:498707] What is the adjusted time? -69
2015-01-09 09:30:20.281 App2.0[8398:498707] New Time: -00:-1:51

2015-01-09 09:30:21.725 App2.0[8398:498707] What is time 2 : 780
2015-01-09 09:30:21.726 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:21.726 App2.0[8398:498707] What is the adjusted time? -9
2015-01-09 09:30:21.726 App2.0[8398:498707] New Time: -00:00:51

2015-01-09 09:30:30.161 App2.0[8398:498707] What is time 2 : 1080
2015-01-09 09:30:30.161 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:30.162 App2.0[8398:498707] What is the adjusted time? -309
2015-01-09 09:30:30.162 App2.0[8398:498707] New Time: -00:-5:51

2015-01-09 09:30:33.389 App2.0[8398:498707] What is time 2 : 4680
2015-01-09 09:30:33.389 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:33.390 App2.0[8398:498707] What is the adjusted time? -3909
2015-01-09 09:30:33.390 App2.0[8398:498707] New Time: --1:-5:51

2015-01-09 09:30:36.186 App2.0[8398:498707] What is time 2 : 8280
2015-01-09 09:30:36.187 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:36.187 App2.0[8398:498707] What is the adjusted time? -7509
2015-01-09 09:30:36.187 App2.0[8398:498707] New Time: --2:-5:51

2015-01-09 09:30:43.918 App2.0[8398:498707] What is time 2 : 660
2015-01-09 09:30:43.918 App2.0[8398:498707] What is time 1 : 771
2015-01-09 09:30:43.919 App2.0[8398:498707] What is the adjusted time? 111
2015-01-09 09:30:43.919 App2.0[8398:498707] New Time: 00:01:51

由于您要单独显示时间组件,因此您可能需要一些条件逻辑来根据 totalTime2 是在 totalTime1 之前还是之后来调整显示 :

NSString *newTime = nil;

if (adjustedTime < 0) {
    newTime = [NSString stringWithFormat:@"-%02d:%02d:%02d", hours, minutes, seconds];
} 
else {
    newTime = [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds];
}

或者如果您喜欢更紧凑的东西:

NSString *newTime = adjustedTime < 0 ? @"-" : @"";
newTime = [newTime stringByAppendingFormat:@"%02d:%02d:%02d", hours, minutes, seconds];

此外,正如 Wain 在评论中指出的那样,在使用它显示之前,您需要获取每个组件的绝对值:

int hours = abs(adjustedTime / 3600);
int minutes = abs((adjustedTime / 60) % 60);
int seconds = abs(adjustedTime % 60);

这应该可以解决问题:

  NSDate *now = [NSDate date];
  NSTimeInterval totalTime1 = [now timeIntervalSinceDate: timeEntry1];
  NSTimeInterval totalTime2 = [now timeIntervalSinceDate: timeEntry2];

  NSLog(@"totalTime1: %f", totalTime1); // =>  -60.00;
  NSLog(@"totalTime2: %f", totalTime2); // => 6023.00;

  //must always be this way
  int timeOffset = (int) (totalTime1 - totalTime2);
  NSLog(@"timeOffset: %d", timeOffset); // => -6083;

  BOOL showNegativePrefix = timeOffset < 0;

  int hours   = abs(timeOffset / 3600);       // => 01
  int minutes = abs((timeOffset / 60 ) % 60); // => 41
  int seconds = abs(timeOffset % 60);         // => 23

  NSString * newTime = [NSString stringWithFormat:@"%@%02d:%02d:%02d", showNegativePrefix ? @"-" : @"", hours, minutes, seconds];
  NSLog(@"%@", newTime); // => -01:41:23

你就快完成了,如果值为负,你所需要的只是一个标志,然后在需要时格式化 差异,前面有一个符号。先设置一个flag,让差值一直为正:

int adjustedTime = ...;

BOOL isNeg;
if (adjustedTime < 0)
{
   isNeg = YES;
   adjustedTime = -adjustedTime; // make value +ve
}
else
   isNeg = NO;

然后像以前一样做数学并将格式行更改为:

NSString *newTime = [NSString stringWithFormat:@"%@%02d:%02d:%02d", (isNeg ? @"-" : @""), hours, minutes, seconds];

注意:您需要使用 %d,因为您的值是 int 而不是 unsigned int

HTH

附录

再次提供代码,包括我跳过的部分代码 ("do your math as before"),并添加注释:

int adjustedTime = totalTime1 - totalTime2;

// At this point adjustedTime may be negative, use the standard approach
// test if it is -ve, and if so set a flag and make the value +ve

BOOL isNeg;
if (adjustedTime < 0)
{
   // we are here if -ve, set flag
   isNeg = YES;
   // and make the value +ve
   adjustedTime = -adjustedTime;
}
else
   isNeg = NO;

// at this point adjustedValue is ALWAYS +ve, isNeg is set if it was originally -ve

int hours = adjustedTime / 3600;
int minutes = (adjustedTime / 60) % 60;
int seconds = adjustedTime % 60;

// at this point hours, minutes & seconds MUST BE +VE as adjustedTime is +ve

// format the values, an optional sign based on isNeg followed by three POSITIVE numbers
NSString *newTime = [NSString stringWithFormat:@"%@%02d:%02d:%02d", (isNeg ? @"-" : @""), hours, minutes, seconds];

这只能在字符串的开头打印最多一个减号。

这种方法(虽然对最小负整数进行了测试,因为它不能被否定)是处理这个问题的标准方法。

Sebastian Keller 和 CRD 提出的解决方案在从负值滚动到正值时都会遇到问题,例如在显示以负值开始的倒计时时:

-1.896893 -00:00:01
-1.498020 -00:00:01
-1.099442 -00:00:01
-0.996686 00:00:00
-0.896971 00:00:00
-0.195021 00:00:00
-0.095020 00:00:00
0.004988 00:00:00
0.104940 00:00:00
0.504980 00:00:00
0.904981 00:00:00
1.000516 00:00:01
1.104926 00:00:01

可以看出,两种方案实际上都显示了00:00:002秒。 下面的代码反而会产生正确的输出:

-1.899441 -00:00:02
-1.499838 -00:00:02
-1.095019 -00:00:02
-0.994941 -00:00:01
-0.899903 -00:00:01
-0.195743 -00:00:01
-0.097564 -00:00:01
0.001758  00:00:00
0.100495  00:00:00
0.503691  00:00:00
0.904986  00:00:00
1.004998  00:00:01
1.103652  00:00:01
2.004936  00:00:02

其实是我在NSNumber上写的一个分类,但是原理应该也适用于任何浮点数:

- (NSString *)ut_hmsString {
    NSString *sign  = (self.floatValue < 0.0f) ? @"-" : @" ";
    float corr      = (self.floatValue < 0.0f) ? 1.0000001f : 0;
    int seconds     = fmodf(fabsf(floorf(self.floatValue)), 60.0f);
    int fakesec     = fabsf(self.floatValue - corr);
    int minutes     = fakesec / 60 % 60;
    int hours       = fakesec / 3600;
    return [NSString stringWithFormat:@"%@%02i:%02i:%02i", sign, hours, minutes, seconds];
}