来自NSDate的意外值

Mat*_*sDS 2 objective-c nsdate nsdateformatter ios

我想把时间存放在约会中.在这种情况下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"];
Run Code Online (Sandbox Code Playgroud)

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

date1 = (NSDate *) 0x1dd32b30 2000-01-01 01:00:01 CET
Run Code Online (Sandbox Code Playgroud)

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

Ami*_*wad 5

因为在SO上存在大量与NSDate相关的问题并且它们都有相同的阴影,我会给你一个更长的答案,可能这可以从其他问题中提及.

A.存在一个常见的误解,即日期是什么:日期是时间轴上的一个点.它并没有处理数小时或数分钟,它并不能对付天,月,年,它并不能处理时区.

这是时间表上的一点.期.

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

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

如果日期在另一个日期之前的时间线上,则日期更早.

那么这些有趣的东西,比如日,月,时区等,这些是什么?由于外面一个星际迷航的插曲时间如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).