我正试图从NSDate
获取UIDatePicker
,但它会不断地返回一个约会时间为20秒的日期时间。如何手动将NSDate
的秒设置为零?
答案 0 :(得分:13)
NSDate是不可变的,因此您无法修改其时间。但是您可以创建一个新的日期对象,该对象可以捕捉到最近的分钟:
NSTimeInterval time = floor([date timeIntervalSinceReferenceDate] / 60.0) * 60.0;
NSDate *minute = [NSDate dateWithTimeIntervalSinceReferenceDate:time];
编辑以回答Uli的评论
NSDate
的参考日期是2001年1月1日格林尼治标准时间0:00。从那时起,已经有两个闰秒:2005年和2010年,因此[NSDate timeIntervalSinceReferenceDate]
返回的值应该关闭两秒钟。
情况并非如此:timeIntervalSinceReferenceDate
与墙上时间完全同步。
在回答这个问题时,我并没有确定这是真的。我只是假设Mac OS会behave as UNIX time(1970年代)这样做:POSIX保证每天从86,400秒的倍数开始。
查看从NSDate
返回的值,这个假设似乎是正确的,但确定找到明确的(有文件证明的)陈述是很好的。
答案 1 :(得分: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]];
这会照顾闰秒。我想更简洁的方法是使用-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];
这样你就可以保证--dateByAddingComponents:处理的任何特殊事情都会被考虑在内。
答案 2 :(得分:2)
虽然这是一个老问题而且Uli已经给出了正确的#34;回答,最简单的解决方案恕我直言,只是从日历中减去从日期获得的秒数。请注意,这可能仍会留下毫秒。
NSDate *date = [NSDate date];
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSCalendarUnitSecond
fromDate:date];
date = [date dateByAddingTimeInterval:-comp.second];
答案 3 :(得分:2)
以下是感兴趣的任何人的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
}
}
使用示例:
let date = Date()
date.floorSeconds()
使用DateComponents
比向日期添加时间间隔要强大得多。
答案 4 :(得分:1)
NSDate
记录一个时刻。如果您要执行的操作是存储特定日期,请不要使用NSDate
。你会得到许多与时区相关的意想不到的头痛,夏令时e.tc.
另一种解决方案是将日期作为准ISO标准格式的整数存储,例如2011年9月15日的20110915.这保证按照与NSDate
排序相同的方式进行排序。 / p>
答案 5 :(得分:1)
这是在Swift中执行此操作的扩展:
extension NSDate {
func truncateSeconds() -> NSDate {
let roundedTime = floor(self.timeIntervalSinceReferenceDate / 60) * 60
return NSDate(timeIntervalSinceReferenceDate: roundedTime)
}
}
答案 6 :(得分:0)
也很快...
extension Date {
func floored() -> Date {
let flooredSeconds = DateComponents(second: 0, nanosecond: 0)
return Calendar.current.nextDate(after: self,
matching: flooredSeconds,
matchingPolicy: .strict,
direction: Calendar.SearchDirection.backward)!
}
}