ios 两个 NSDates 之间的 Swift 天数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24723431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:22:28  来源:igfitidea点击:

Swift days between two NSDates

iosswiftdatedate-difference

提问by Linus

I'm wondering if there is some new and awesome possibility to get the amount of days between two NSDates in Swift / the "new" Cocoa?

我想知道是否有一些新的和很棒的可能性来获得 Swift/“新”可可中两个 NSDates 之间的天数?

E.g. like in Ruby I would do:

例如,在 Ruby 中我会这样做:

(end_date - start_date).to_i

回答by Emin Bugra Saral

You have to consider the time difference as well. For example if you compare the dates 2015-01-01 10:00and 2015-01-02 09:00, days between those dates will return as 0 (zero) since the difference between those dates is less than 24 hours (it's 23 hours).

您还必须考虑时差。例如,如果您比较日期2015-01-01 10:002015-01-02 09:00,则这些日期之间的天数将返回 0(零),因为这些日期之间的差异小于 24 小时(即 23 小时)。

If your purpose is to get the exact day number between two dates, you can work around this issue like this:

如果您的目的是获取两个日期之间的确切天数,您可以像这样解决这个问题:

// 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

Swift 3 and Swift 4 Version

Swift 3 和 Swift 4 版本

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)

回答by iphaaw

Here is my answer for Swift 2:

这是我对 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
}

回答by trevor-e

I see a couple Swift3 answers so I'll add my own:

我看到了几个 Swift3 的答案,所以我会添加我自己的答案:

public static func daysBetween(start: Date, end: Date) -> Int {
    return Calendar.current.dateComponents([.day], from: start, to: end).day!
}

The naming feels more Swifty, it's one line, and using the latest dateComponents()method.

命名感觉更Swifty,一行一行,并且使用了最新的dateComponents()方法。

回答by vikingosegundo

I translated my Objective-C answer

我翻译了我的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)

result

结果

<NSDateComponents: 0x10280a8a0>
     Day: 4

The hardest part was that the autocompletion insists fromDate and toDate would be NSDate?, but indeed they must be NSDate!as shown in the reference.

最难的部分是自动完成坚持 fromDate 和 toDate will be NSDate?,但实际上它们必须NSDate!如参考中所示。

I don't see how a good solution with an operator would look like, as you want to specify the unit differently in each case. You could return the time interval, but than won't you gain much.

我看不出有操作员的好的解决方案会是什么样子,因为您想在每种情况下以不同的方式指定单位。你可以返回时间间隔,但你不会得到太多。

回答by Krunal

Here is very nice, Dateextension to get difference between dates in years, months, days, hours, minutes, seconds

这是非常好的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
    }

}

回答by ChaosSpeeder

Update for Swift 3 iOS 10 Beta 4

Swift 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!
}

回答by kazantatar

Here is the answer for Swift 3 (tested for IOS 10 Beta)

这是 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!
}

Then you can call it like this

然后你可以这样称呼它

let pickedDate: Date = sender.date
let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date())
    print("Num of Days: \(NumOfDays)")

回答by Norman

Swift 3. Thanks to Emin Bu?ra Saralabove for the startOfDaysuggestion.

Swift 3. 感谢上面Emin Bu?ra SaralstartOfDay建议。

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)!
    }
}

Usage:

用法:

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

回答by Daniel Schlaug

The things built into swift are still very basic. As they should be at this early stage. But you can add your own stuff with the risk that comes with overloading operators and global domain functions. They will be local to your module though.

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

回答by Alen Liang

Here is my answer for Swift 3:

这是我对 Swift 3 的回答:

func daysBetweenDates(startDate: NSDate, endDate: NSDate, inTimeZone timeZone: TimeZone? = nil) -> Int {
    var calendar = Calendar.current
    if let timeZone = timeZone {
        calendar.timeZone = timeZone
    }
    let dateComponents = calendar.dateComponents([.day], from: startDate.startOfDay, to: endDate.startOfDay)
    return dateComponents.day!
}