【问题标题】:Unexpected value from NSDateNSDate 的意外值
【发布时间】:2013-06-22 01:41:22
【问题描述】:

我正在尝试将时间存储在日期中。 在这种情况下为 1.5 秒。 我将时间存储在日期中,如下所示:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];  
NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"];

但如果我查看调试区域,我可以看到 date1 的值设置为:

date1 = (NSDate *) 0x1dd32b30 2000-01-01 01:00:01 CET

谁能告诉我为什么会这样?

【问题讨论】:

  • NSDate 的描述不处理时区。您宁愿使用对 NSDateFormatter 的另一个调用将日期转换回字符串。
  • 是的,但我正在制作一款游戏,如果您完成关卡的时间低于 1.5 秒,您将获得 3 颗星。所以我还有另一个 NSDate,这是完成关卡所需的日期。而且我不知道如何检查玩家的时间是否低于我使用 NSStrings 的时间。
  • 你没有。你使用[date1 compare:date2]
  • 是的,我使用它,但我没有把它放在我将编辑我的帖子的问题中。
  • 那有什么问题呢?

标签: ios objective-c nsdate nsdateformatter


【解决方案1】:

因为SO上有很多NSDate相关的问题,而且都是一样的阴影,所以我给你一个更长的答案,可能这可以从其他问题中参考。

A.有一个常见的误解,日期是什么:日期是时间轴上的一个点。它处理小时或分钟,它处理天、月、年,它处理时区。

这是时间线上的一个点。期间。

(在内部它由一个浮点数表示。这是一个惊喜吗?)

B.还有另一个常见的误解,即日期是什么:两个日期,因此时间线上的点,如果它们具有相同的值,则它们是相等的。这意味着它们具有相同的表示。两次可以相等,即使它们的表示完全不同。 (这就是发生在你身上的事情。)为了进行比较,使用哪个时区、预期的、$whatever 都无关紧要。对于比较而言,使用哪个日历、预期的或 $whatever 都无关紧要。如果是德国科隆 (UTC+1) 的 11:11,则英国伦敦 (UTC+0) 是 10:11。这是同一时间

如果时间线上的日期早于另一个日期,则该日期较早。

C.那么这些有趣的东西是什么,比如天、月、时区等等? 由于在星际迷航情节之外,像 26,182,382,303.127373 这样的时间将难以理解和处理,因此人类开始在时间线上给出有趣的名字。此陈述不是日期。它们是日期的表示。数字也是同样的问题。你不开这个玩笑吗?

“有10种人:懂二进制的和不懂二进制的。”

这个笑话的精神是,10 可以是 10 的值,如果它是用十进制表示的,或者它可以是 2 的值,用二进制表示。除非他知道用于表示的数字系统,否则没有人可以说“10”表示什么值。大多数人认为它是十进制的,所以“10”表示十。这是一个流行的约定。这很好用,因为几乎全世界都采用了该约定。但是:“10”可以表示两个不同的值。反之亦然:相同的值可以用不同的“字符串”写入:十进制表示法中的 10 等于二进制表示法中的 1010(并且等于“2+8”,sqrt (100), ...也就是说,为什么允许在它们之间写=。)

不幸的是(不,不是真的,时间必须以一种简单的方式在本地工作)因为时间没有世界范围的约定。如果有人写“11:11”,你就不能说,什么时间(记住,它是时间线上的一个点)是什么意思。可能这个人含蓄地说,这是他所在时区的日历系统中的时间。但是你必须知道,他在世界上的哪个位置说这句话。考虑到日月等,你可能必须知道他的宗教信仰是什么,因为即使在一个国家,不同宗教信仰的人使用不同的日历。

由于一方面没有通用的全球惯例,而且 Mac OS 在全球计算机系统上运行,因此您不能假设打印出的时间是以您期望的符号编写的。

因此,通过字符串比较日期是完全的,嗯,不是很聪明。您不比较日期,而是比较字符串。

在比较时间(包括日期)之前,您必须将表示转换为“真实”时间的时间。您必须添加有关日历、表示形式和时区(包含在 Cocoa 中的日历中)的信息。

在 Cocoa 中,您使用 NSDateFormatter、NSCalendar、NSDateComponents 的实例来完成这项工作。如果您让 NSDateFormatter 将表示转换为时间,反之亦然,则必须设置日历。 (NSDateFormatter 假定选择了本地日历,如果您没有设置一个。)如果 NSDateFormatter 不知道要使用哪个日历,那么它根本不可能进行任何转换工作。而这对你来说根本不可能。

然后你可以用它做一些计算,日期,时间,NSDate 的实例,包括比较,至少你必须使用日历将它转换回人类可读的表示。

你得到的并让你认为这是一个错误的时间,只是正确的时间,但在你没有预料到的情况下。 (-description 始终提供 UTC+0)。

【讨论】:

  • 感谢您的回答!它帮助了我,我已经找到了比较日期的解决方案,多亏了你,我知道时间是正确的,因为我住在比利时而不是格林威治。非常感谢!
【解决方案2】:

在日期上尝试 NSLog 将仅返回 GMT 格式的日期。因此,如果您想检查您是否获得了正确的时间或日期,请将日期转换为字符串和 NSLog。

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];  
NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"];

NSString *dateString = [dateFormatter stringFromDate:date1];
NSlog(@"%@",dateString);

【讨论】:

    猜你喜欢
    • 2012-05-06
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2017-08-15
    • 2020-06-24
    • 1970-01-01
    相关资源
    最近更新 更多