我想知道在Swift / “新”Cocoa中获取两个NSDate之间天数的新的、棒的方法是否存在?
例如,就像我在Ruby中会这样做:
(end_date - start_date).to_i
我想知道在Swift / “新”Cocoa中获取两个NSDate之间天数的新的、棒的方法是否存在?
例如,就像我在Ruby中会这样做:
(end_date - start_date).to_i
你还必须考虑时差。例如,如果你要比较日期2015-01-01 10:00
和2015-01-02 09:00
,那么这两个日期之间的时间跨度不到24小时(只有23小时),所以它们之间的天数差将被计算为0。
如果你的目的是获得两个日期之间的确切天数,你可以像这样解决这个问题:
// Assuming that firstDate and secondDate are defined
// ...
let calendar = NSCalendar.currentCalendar()
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)
let flags = NSCalendarUnit.Day
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: [])
components.day // This will return the number of day(s) between dates
let calendar = Calendar.current
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: firstDate)
let date2 = calendar.startOfDay(for: secondDate)
let components = calendar.dateComponents([.day], from: date1, to: date2)
calendar.date(bySettingHour: 12, minute: 00, second: 00, of: calendar.startOfDay(for: firstDate))
。 - MonsieurDartstartOfDay()
似乎是不必要的):calendar.date(bySettingHour: 12, minute: 0, second: 0, of: firstDate)
。 - jamix这里是关于 Swift 2 的答案:
func daysBetweenDates(startDate: NSDate, endDate: NSDate) -> Int
{
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
return components.day
}
我看到有几个关于Swift3的答案,所以我会补充我的:
public static func daysBetween(start: Date, end: Date) -> Int {
Calendar.current.dateComponents([.day], from: start, to: end).day!
}
命名感觉更Swifty,只需一行代码,使用最新的dateComponents()
方法。
这里有一个非常好用的Date
扩展,可以计算两个日期之间的年、月、日、小时、分钟和秒钟差。
extension Date {
func years(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.year], from: sinceDate, to: self).year
}
func months(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.month], from: sinceDate, to: self).month
}
func days(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.day], from: sinceDate, to: self).day
}
func hours(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.hour], from: sinceDate, to: self).hour
}
func minutes(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.minute], from: sinceDate, to: self).minute
}
func seconds(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.second], from: sinceDate, to: self).second
}
}
date
应该改为 sinceDate
。 - TheTiger几天
,它运行良好。 - TheTigerfunc years(since date: Date) -> Int? { return Calendar.current.dateComponents([.year], from: date, to: self).years }
,你可以像这样调用: let y = date1.years(since: date2)
。这样可能更符合现代命名规范。 - Rob我翻译了我的Objective-C答案
。let start = "2010-09-01"
let end = "2010-09-05"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let startDate:NSDate = dateFormatter.dateFromString(start)
let endDate:NSDate = dateFormatter.dateFromString(end)
let cal = NSCalendar.currentCalendar()
let unit:NSCalendarUnit = .Day
let components = cal.components(unit, fromDate: startDate, toDate: endDate, options: nil)
println(components)
结果
<NSDateComponents: 0x10280a8a0>
Day: 4
NSDate?
,但实际上它们必须像参考文献中所示的那样是NSDate!
。.DayCalendarUnit
已被弃用。我认为现在应该使用.CalendarUnitDay
。 - TaylorAllredlet components = cal.components(.Day, fromDate: startDate, toDate: endDate, options: [])
。 - Andrej.Day
。 - William GPSwift 3 iOS 10 Beta 4 的更新
func daysBetweenDates(startDate: Date, endDate: Date) -> Int {
let calendar = Calendar.current
let components = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)
return components.day!
}
感谢Emin Buğra Saral的建议,Swift 5现在包含了startOfDay
功能。
extension Date {
func daysBetween(date: Date) -> Int {
return Date.daysBetween(start: self, end: date)
}
static func daysBetween(start: Date, end: Date) -> Int {
let calendar = Calendar.current
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: start)
let date2 = calendar.startOfDay(for: end)
let a = calendar.dateComponents([.day], from: date1, to: date2)
return a.value(for: .day)!
}
}
使用方法:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let start = dateFormatter.date(from: "2017-01-01")!
let end = dateFormatter.date(from: "2018-01-01")!
let diff = Date.daysBetween(start: start, end: end) // 365
// or
let diff = start.daysBetween(date: end) // 365
以下是适用于 Swift 3(已在 iOS 10 Beta 上测试)的答案:
func daysBetweenDates(startDate: Date, endDate: Date) -> Int
{
let calendar = Calendar.current
let components = calendar.components([.day], from: startDate, to: endDate, options: [])
return components.day!
}
然后你可以这样调用它
let pickedDate: Date = sender.date
let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date())
print("Num of Days: \(NumOfDays)")
Swift 5
在工作中,你需要将时间设置为两天相同,如果误差超过几秒钟就会出现错误。
func daysBetween(start: Date, end: Date) -> Int {
let start = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: start)!
let end = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: end)!
return Calendar.current.dateComponents([.day], from: start, to: end).day ?? 0
}
Swift内置的东西仍然非常基础,这在早期阶段是应该的。但是,您可以添加自己的内容,风险就在于过载运算符和全局域函数。不过,它们将仅局限于您的模块。
let now = NSDate()
let seventies = NSDate(timeIntervalSince1970: 0)
// Standard solution still works
let days = NSCalendar.currentCalendar().components(.CalendarUnitDay,
fromDate: seventies, toDate: now, options: nil).day
// Flashy swift... maybe...
func -(lhs:NSDate, rhs:NSDate) -> DateRange {
return DateRange(startDate: rhs, endDate: lhs)
}
class DateRange {
let startDate:NSDate
let endDate:NSDate
var calendar = NSCalendar.currentCalendar()
var days: Int {
return calendar.components(.CalendarUnitDay,
fromDate: startDate, toDate: endDate, options: nil).day
}
var months: Int {
return calendar.components(.CalendarUnitMonth,
fromDate: startDate, toDate: endDate, options: nil).month
}
init(startDate:NSDate, endDate:NSDate) {
self.startDate = startDate
self.endDate = endDate
}
}
// Now you can do this...
(now - seventies).months
(now - seventies).days