如何将秒设置为零的NSDate

我试图从UIDatePicker获取NSDate ,但它不断地返回我一个20秒的date时间。 我如何手动设置NSDate的第二个零?

NSDate是不可变的,所以你不能修改它的时间。 但是,您可以创build一个新的date对象,并将其捕捉到最近的分钟:

 NSTimeInterval time = floor([date timeIntervalSinceReferenceDate] / 60.0) * 60.0; NSDate *minute = [NSDate dateWithTimeIntervalSinceReferenceDate:time]; 

编辑回答Uli的评论

NSDate的参考date为2001年1月1日,格林威治时间0:00。 从那以后,又增加了两个闰秒:2005和2010,所以[NSDate timeIntervalSinceReferenceDate]返回的值应该是两秒。

情况并非如此: timeIntervalSinceReferenceDate与墙的时间完全同步。

在回答这个问题时,我并没有确定这是真的。 我只是假设Mac OS会像UNIX时间 (1970年代)那样工作:POSIX保证每天的启动时间是86,400秒的倍数。

看看从NSDate返回的值这个假设似乎是正确的,但肯定会很高兴find一个明确(logging)的说法。

你不能直接操纵NSTimeInterval,因为那是从参考date算起的距离(以秒为单位),不能保证是60秒除以00秒。毕竟,可能已经插入了闰秒来调整太阳时间和UTC之间的差异。 每一个闰秒都会把你抛出1.我把我的date秒数修改为0是:

 NSDate * startDateTime = [NSDate date]; NSDateComponents * startSeconds = [[NSCalendar currentCalendar] components: NSSecondCalendarUnit fromDate: startDateTime]; startDateTime = [NSDate dateWithTimeIntervalSinceReferenceDate: [startDateTime timeIntervalSinceReferenceDate] -[startSeconds second]]; 

这照顾闰秒。 我想更简洁的方法是使用-dateByAddingComponents:

 NSDate * startDateTime = [NSDate date]; NSDateComponents * startSeconds = [[NSCalendar currentCalendar] components: NSSecondCalendarUnit fromDate: startDateTime]; [startSeconds setSecond: -[startSeconds second]]; startDateTime = [[NSCalendar currentCalendar] dateByAddingComponents: startSeconds toDate: startDateTime options: 0]; 

这样,你可以保证,无论什么特殊的东西 – 日记加成组件:照顾也是如此。

虽然这是一个古老的问题,Uli给出了“正确”的答案,但最简单的解决scheme恕我直言,就是从日历中减去date中的秒数。 请注意,这可能仍然会保持毫秒。

 NSDate *date = [NSDate date]; NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSCalendarUnitSecond fromDate:date]; date = [date dateByAddingTimeInterval:-comp.second]; 

NSDatelogging一个时刻。 如果你想要做的是存储特定的一天,不要使用NSDate 。 你会得到很多与时区,夏时制e.tc相关的意想不到的头痛。

一种替代的解决scheme是以准ISO标准格式存储整天,如2011年9月15日的20110915.这保证按照与NSDatesorting相同的方式进行sorting。

这是Swift中的一个扩展:

 extension NSDate { func truncateSeconds() -> NSDate { let roundedTime = floor(self.timeIntervalSinceReferenceDate / 60) * 60 return NSDate(timeIntervalSinceReferenceDate: roundedTime) } }