如何为NSDate设置秒为零

deu*_*yun 15 iphone cocoa-touch objective-c nsdate ios

我想要NSDate离开UIDatePicker,但它不断给我一个约会时间20秒.如何手动将NSDate秒设置为零?

Nik*_*uhe 14

NSDate是不可变的,因此您无法修改其时间.但是您可以创建一个新的日期对象,该对象可以捕捉到最近的分钟:

NSTimeInterval time = floor([date timeIntervalSinceReferenceDate] / 60.0) * 60.0;
NSDate *minute = [NSDate dateWithTimeIntervalSinceReferenceDate:time];
Run Code Online (Sandbox Code Playgroud)

编辑以回答Uli的评论

参考日期为NSDate2001年1月1日,格林尼治标准时间0:00.从那以后增加了两个闰秒:2005年和2010年,所以返回的值[NSDate timeIntervalSinceReferenceDate]应该减去2秒.

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

在回答这个问题时,我并没有确定这是真的.我只是假设Mac OS的行为与UNIX时间(1970年代)一样:POSIX保证每天从86,400秒的倍数开始.

看看从NSDate这个假设返回的值似乎是正确的,但确定找到一个明确的(记录的)陈述是很好的.

  • 这不行.自参考日期起的时间间隔不保证为具有00秒的时间的60的偶数倍.这是自参考日期以来的秒数,因此偶尔插入的闰秒会让你失望.我想你必须使用NSCalendar找出你的日期有多少秒,然后从时间间隔中减去*那个*. (4认同)

uli*_*ess 11

您不能直接操作NSTimeInterval,因为这是自参考日期以来的秒数,不能保证在除以60时的00秒时间.毕竟,可能已插入闰秒以进行调整太阳时和UTC之间的差异.每一个闰秒都会让你失望1.我做的是将日期的秒数修改为0:

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

startDateTime = [NSDate dateWithTimeIntervalSinceReferenceDate: [startDateTime timeIntervalSinceReferenceDate] -[startSeconds second]];
Run Code Online (Sandbox Code Playgroud)

这照顾了闰秒.我想更清洁的方法是使用-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];
Run Code Online (Sandbox Code Playgroud)

这样你就可以保证,不管是什么特殊的东西-dateByAddingComponents:照顾的也是如此.

  • 我相信您关于影响`timeIntervalSinceReferenceDate` 的闰秒的说法是不正确的。虽然 Apple 的日期和时间编程指南没有明确定义行为,但 POSIX 针对 UNIX 时间这样做:忽略闰秒(参见 http://en.wikipedia.org/wiki/Unix_time)。Cocoa 似乎也是如此。 (2认同)
  • 另一个想法:您提出的两种解决方案都没有考虑几分之一秒。您计算(整数)秒数并从原始日期中减去它们。结果指的是零秒但非零毫秒的时间,这有点奇怪。 (2认同)

shi*_*him 5

这是一个 Swift 扩展,供感兴趣的人使用:

extension Date {
    public mutating func floorSeconds() {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: self)
        self = calendar.date(from: components) ?? self // you can handle nil however you choose, probably safe to force unwrap in most cases anyway
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

let date = Date()
date.floorSeconds()
Run Code Online (Sandbox Code Playgroud)

使用DateComponents比在日期中添加时间间隔要健壮得多。