因为 SO 上有大量与 NSDate 相关的问题,而且它们都有相同的阴影,所以我会给你一个更长的答案,可能这可以从其他问题中引用。
A. 有一个常见的误解,即日期是什么:日期是时间轴上的一个点。它不处理小时或分钟,不处理日、月、年,也不处理时区。
这是时间线上的一个点。时期。
(在内部它由一个浮点数表示。这是一个惊喜吗?)
B. 还有一个常见的误解,日期是什么:两个日期,因此时间线上的点,如果它们具有相同的值,则它们是相等的。这并不意味着它们具有相同的表示。两次可以相等,即使它们的表示完全不同。(这就是发生在你身上的事情。)为了进行比较,使用哪个时区、预期的、$whatever 都无关紧要。对于比较而言,使用哪个日历、预期的或 $whatever 都无关紧要。如果是德国科隆 (UTC+1) 的 11:11,则英国伦敦 (UTC+0) 是 10:11。这是同一时间。
如果时间线上的日期早于另一个日期,则该日期较早。
C. 那么这些有趣的东西是什么,比如天、月、时区等等?由于在星际迷航情节之外,像 26,182,382,303.127373 这样的时间将难以理解和处理,人类开始在时间线上给出有趣的名字。此陈述不是日期。它们是日期的表示。数字也是同样的问题。你不开这个玩笑吗?
“有 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)。