在日历年中两个NSDate之间的天数(Swift)

4

我正在开发一个生日提醒应用。我希望用户能够看到距离下一个人的生日还有多少天。

假设我的 NSDate() = 2015-06-30 07:21:47 +0000

而生日的 NSDate = 1985-08-29 12:00:00 +0000

如何获得距离下一个生日的天数?我已经使用了类似这样的方法,它给出了自日期实际开始以来的负天数(这些天数是成千上万的出生日期)。然后我将365天添加到数字差异中,直到它变为正数,但它仍然返回一个奇怪的数字。我认为这可能是由于闰年或其他原因造成的。

我可以实现一种方法吗?以某种方式使年份组件相等,以便始终从下一个生日进行比较,而不是从最初的出生日期进行比较?

编辑:

这是我正在使用的函数:

func daysBetween(date1: NSDate, date2: NSDate) -> Int {

    var calendar: NSCalendar = NSCalendar.currentCalendar()

    let date1 = calendar.startOfDayForDate(date1)
    let date2 = calendar.startOfDayForDate(date2)

    let flags = NSCalendarUnit.CalendarUnitDay
    let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)

    return components.day
}

根据我发表的日期示例,我会像这样使用它:

// sampleDate = 1985-08-29 12:00:00 +0000
daysBetween(sampleDate, date2: NSDate())
// --> 10897

无论是正数还是负数,这个数字都是以千计的。我想把它转化为距离下一个生日的天数。


如果第二天在第一天之前,那就是负数。要改变顺序。而且如果你有错误的代码,请记得发布它! - vikingosegundo
感谢@vikingosegundo的提示。 - Aaron
2个回答

11

你需要做的是计算出从今天开始,生日(包括日和月)下一次出现的时间:

let cal = NSCalendar.currentCalendar()
let today = cal.startOfDayForDate(NSDate())
let dayAndMonth = cal.components(.CalendarUnitDay | .CalendarUnitMonth,
    fromDate: birthday)
let nextBirthDay = cal.nextDateAfterDate(today,
    matchingComponents: dayAndMonth,
    options: .MatchNextTimePreservingSmallerUnits)!

备注:

  • MatchNextTimePreservingSmallerUnits选项的目的是,如果生日落在公历二月二十九日,则在不是闰年的情况下,其下一个出现日期将被计算为三月一日。

  • 您可能需要先检查生日是否是今天,因为在这种情况下,nextDateAfterDate()会返回下一个生日。

然后您可以像往常一样计算天数差异:

let diff = cal.components(.CalendarUnitDay,
    fromDate: today,
    toDate: nextBirthDay,
    options: nil)
println(diff.day)

Swift 2.2(Xcode 7.3)更新:

let cal = NSCalendar.currentCalendar()
let today = cal.startOfDayForDate(NSDate())
let dayAndMonth = cal.components([.Day, .Month],
                                 fromDate: birthday)
let nextBirthDay = cal.nextDateAfterDate(today,
                                         matchingComponents: dayAndMonth,
                                         options: .MatchNextTimePreservingSmallerUnits)!

let diff = cal.components(.Day,
                          fromDate: today,
                          toDate: nextBirthDay,
                          options: [])
print(diff.day)

Swift 3更新(Xcode 8 GM):

let cal = Calendar.current
let today = cal.startOfDay(for: Date())
let dayAndMonth = cal.dateComponents([.day, .month], from: birthday)
let nextBirthDay = cal.nextDate(after: today, matching: dayAndMonth,
                                matchingPolicy: .nextTimePreservingSmallerComponents)!

let diff = cal.dateComponents([.day], from: today, to: nextBirthDay)
print(diff.day!)

4

顺便提一下,如果有人需要,在Swift 3中这是@Aaron函数:

func daysBetween(date1: Date, date2: Date) -> Int {
    let calendar = Calendar.current

    let date1 = calendar.startOfDay(for: date1)
    let date2 = calendar.startOfDay(for: date2)

    let components = calendar.dateComponents([Calendar.Component.day], from: date1, to: date2)

    return components.day ?? 0
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接