两个NSDates之间的快速日子

Nik*_*iko 96 date ios date-difference swift

我想知道是否有一些新的和令人敬畏的可能性来获得Swift /"新"可可中两个NSDates之间的天数?

就像在Ruby中我会这样做:

(end_date - start_date).to_i
Run Code Online (Sandbox Code Playgroud)

Emi*_*ral 211

接受的答案将不会在两个日期之间返回正确的日期编号.你也必须考虑时差.例如,如果您比较的日期2015-01-01 10:002015-01-02 09:00,这些日期之间的天将返回0(零),因为这些日期之间的差值小于24小时(这是23小时).

如果您的目的是获取两个日期之间的确切日期数,您可以解决此问题,如下所示:

// 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
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

  • 您实际上可能想要检查中午12点(中午)而不是startOfDayForDate - 由于调整时区和夏令时,应该不太可能出现问题. (11认同)
  • 将日期设置为中午可以这样做:`calendar.date(bySettingHour:12,minute:00,second:00,of:calendar.startOfDay(for:firstDate))` (8认同)
  • 设置中午的较短版本(`startOfDay()`似乎是不必要的):`calendar.date(bySettingHour: 12, 分钟: 0, Second: 0, of:firstDate)`。 (5认同)
  • 有人可以解释一下当 Calendar.current 的 timeZone 与 firstDate/secondDate 初始化时使用的时区(例如从时间格式化程序)不匹配时会发生什么吗?如果我们想要找到已知的给定时区(与当前不同)的日期与当前时区的当前日期之间的天数距离,我们应该怎么做 - 我们应该如何转换 Calendar ? (2认同)

iph*_*aaw 49

这是我对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
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我们比较“今天”和“明天”,则返回0。 (3认同)

tre*_*r-e 38

我看到一些Swift3的答案,所以我将添加自己的答案:

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

命名感觉更加Swifty,它是一行,并使用最新的dateComponents()方法.


Vik*_*ica 29

我翻译了我的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)
Run Code Online (Sandbox Code Playgroud)

结果

<NSDateComponents: 0x10280a8a0>
     Day: 4
Run Code Online (Sandbox Code Playgroud)

最难的部分是自动完成功能坚持从日期到日期NSDate?,但实际上它们必须NSDate!如参考文献中所示.

我不知道运算符的好解如何,因为你想在每种情况下以不同的方式指定单位.你可以返回时间间隔,但不会获得太多.

  • options现在是一个预期的参数 (2认同)
  • 运行Swift 2这对我有用:`let components = cal.components(.Day,fromDate:startDate,toDate:endDate,options:[])` (2认同)

Kru*_*nal 24

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

}
Run Code Online (Sandbox Code Playgroud)

  • 好答案。我只建议`func years(since date: Date) -&gt; Int? { return Calendar.current.dateComponents[.year], from: date, to: self).years }`,您可以将其称为`let y = date1.years(since: date2)`。这可能更符合现代命名约定。 (2认同)

Cha*_*der 18

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!
}
Run Code Online (Sandbox Code Playgroud)


kaz*_*tar 9

以下是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!
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以这样称呼它

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


Mik*_*iel 8

雨燕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
}
Run Code Online (Sandbox Code Playgroud)


Nor*_*man 7

斯威夫特3.感谢上面的EminBuğraSaralstartOfDay提出的建议.

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)!
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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
Run Code Online (Sandbox Code Playgroud)

  • ***将它们都移到中午,而不是 00:00*** 肯定会更好,以避免许多问题。 (2认同)