xcode 一个日历年中 2 个 NSDates 之间的天数 swift

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31132159/
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-09-15 07:23:46  来源:igfitidea点击:

Days between 2 NSDates in a calendar year swift

iosxcodeswiftdatensdate

提问by Aaron

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

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

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

NSDate对于生日=1985-08-29 12:00:00 +0000

How would I get the number of days until the next birthday? I've used something like thiswhich 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.

我如何获得下一个生日的天数?我用像这样赋予因为日期的实际开始(这是在数以千计的出生日期)的天负数。然后我会将 365 添加到数字差异中,直到它为正数,但它仍然返回一个不稳定的数字。我假设是由于闰年或其他原因。

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.

无论是正数还是负数,这个数字都以千计。我希望将其平衡为到下一个日历生日的天数。

回答by Martin R

What you need is to compute the next occurrenceof 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 MatchNextTimePreservingSmallerUnitsoption 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 nextbirthday in that case.

  • MatchNextTimePreservingSmallerUnits选项的目的是,如果生日是 2 月 29 日(在公历中),那么如果该年不是闰年,那么它的下一次出现将被计算为 3 月 1 日。

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

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

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

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

回答by Ricardo Barroso

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

顺便说一句,如果有人需要这里是 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
}