如何使用Swift计算人生日的天数?

uce*_*lme -1 date ios swift

我有一个日期变量和一个人的生日。我想知道距离这个人下一个生日还有多少天。它应该从今天的日期计算到当年的生日日期。

如何用 Swift 做到这一点?考虑闰年的 2 月 29 日也很棒。

gna*_*729 6

致那些试图结束这件事的人:这是关于生日的,与几天有着完全不同的规则。

生日很复杂。你的生日是你出生的那一刻,在你出生的时区。考虑到萨摩亚 = UTC+14 和贝克岛 = UTC-12,同一时间出生的人的生日可能相差两天。

因此,要存储某人的生日,而不是出生的时刻,您可以存储年/月/日,或者如果您想将其存储为时间点,则将那天的开始存储在 UTC 中,并理解这是指定日期,且不得转换为当地时间。

现在你的生日什么时候重复?如果此人出生在 D/M/Y 并且 D/M 不是 2 月 29 日,那么下一个生日是 D/M/今年或 D/M/明年。如果该日期在未来,则为 D/M/当前年份,否则为 D/M/明年。

如果此人出生于 2 月 29 日,那么如果该年不是闰年,则您必须确定下一个正式生日的时间——这将是 2 月 28 日或 3 月 1 日,具体取决于适用的规则。

我们还需要澄清“天数”的含义。如果我的生日是 4 月 1 日,现在是 3 月 31 日,距离午夜一秒,我的生日就是从现在开始的一秒。但是,我会假设结果应该是“从现在开始的一天”。

所以这里是算法:

第 1 步:查找此人出生的日/月/年。

第二步:确定当前时间,转换为当地日/月/年。如果此计算在午夜前几纳秒完成,则确定当前时间一次以避免出现问题。

Step 3:确定生日重复的年份:如果生日的日期/月份大于当前的日期/月份,则生日重复的年份为当年,否则为下一年。如果生日是 2 月 29 日,这也是正确的。

步骤4:确定生日重复的日期/月份:这与生日的日期/月份相同,除非生日是2月29日并且生日重复的年份不是闰年。在这种情况下,生日会在 2 月 28 日或 3 月 1 日重复,具体取决于您决定应用的规则。

第 5 步:将当前日/月/年 + 12 小时转换为 UTC。将生日重复 + 12 小时的日期转换为 UTC。计算以秒为单位的差异(操作系统应该为您做的)。除以 86,400,然后四舍五入到最接近的整数。“+12 小时”和“四舍五入到最接近的整数”确保您没有夏令时、闰秒等问题。

用 Swift 或任何其他语言编写此代码应该没有问题。


Wik*_*own 5

这取决于您希望使用天数值做什么,但这里有一个小函数,它将返回描述Double直到给定的天数DateMartin R在这里给出了一个非常好的答案,我的答案主要基于他们的答案,并添加了一些文档。

/// This function takes a `Date` parameter and returns an `Int` describing how many days away the `Date` is into the future (accounting for leap years by making 2/29 dates land on 3/1 in non-leap years).
/// - Parameter date: The `Date` object to be evaluated.
func daysUntil(birthday: Date) -> Int {
    let cal = Calendar.current
    let today = cal.startOfDay(for: Date())
    let date = cal.startOfDay(for: birthday)
    let components = cal.dateComponents([.day, .month], from: date)
    let nextDate = cal.nextDate(after: today, matching: components, matchingPolicy: .nextTimePreservingSmallerComponents)
    return cal.dateComponents([.day], from: today, to: nextDate ?? today).day ?? 0
}
Run Code Online (Sandbox Code Playgroud)