Days between 2 NSDates in a calendar year swift

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-01 23:37:37

问题


I'm building a birthday reminder app. I want the user to be able to see how many days it is until somebody's next birthday.

Let's say I have an NSDate() = 2015-06-30 07:21:47 +0000

And the NSDate for the birthday = 1985-08-29 12:00:00 +0000

How would I get the number of days until the next birthday? I've used something like this which gives a negative number of days since the date's actual beginning (which are in the thousands with birthdates). Then with that I would add 365 to the numerical difference until it was positive but it still returns a wonky number. I'm assuming due to leap years or something.

Is there a method to this I can implement? Somehow equalize the year components so that it's always comparing from the next birthday and not the original birthdate?

Edit:

Here is the function I am using:

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
}

With the example dates I posted I would use it like this:

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

Whether positive or negative, the number is in the thousands. I'm looking to equalize that into number of days to the next calendar birthday.


回答1:


What you need is to compute the next occurrence of the (day and month component of the) birthday after today:

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

Remarks:

  • The purpose of the MatchNextTimePreservingSmallerUnits option is that if the birthday is on February 29 (in the Gregorian calendar), its next occurrence will be computed as March 1 if the year is not a leap year.

  • You might need to check first if the birthday is today, as it seems that nextDateAfterDate() would return the next birthday in that case.

Then you can compute the difference in days as usual:

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

Update for 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)

Update for 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!)



回答2:


Btw, in case anyone needs here is the @Aaron function in Swift 3:

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
}


来源:https://stackoverflow.com/questions/31132159/days-between-2-nsdates-in-a-calendar-year-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!