SwiftDate和日期计算

时间:2018-01-10 21:24:36

标签: swift swiftdate

我正在尝试计算宠物活着的周数和天数。我正在使用SwiftDate。所以我让用户选择一个生日,并将其与当前日期进行比较。

我不想比较时间......所以生日和当前日期都应该有相同的时间。

我的代码是:

let greg = Calendar(identifier: .gregorian)
var date1 = birthday // from datepicker
var date2 = Date()
var components1 = greg.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date1)
var components2 = greg.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date2)
components1.hour = 15
components1.minute = 0
components1.second = 0
components2.hour = 15
components2.minute = 0
components2.second = 0
date1 = greg.date(from: components1)!
date2 = greg.date(from: components2)!

let daysAlive = (date2 - date1).in(.day)
let weeksAlive = Int(weeksAlive! / 7)
let restDays = daysAlive! - (weeksAlive * 7)
let aLive = "Age: \(weeksAlive) wk, \(restDays) d (\(daysAlive!) d)"

输出为“年龄:28周,3天(199天)”

代码有效......但我怎样才能重构呢?是否有更简单的方法为两个给定日期设置“同一时间”?

3 个答案:

答案 0 :(得分:2)

如果你不关心时差,为什么不把时间完全抛弃呢?它会为您提供相同的输出,并且只会使您无需输入默认时间值,然后在功能的其余部分忽略它们:

let greg = Calendar(identifier: .gregorian)
var date1 = birthday // from datepicker
var date2 = Date()
var components1 = greg.dateComponents([.year, .month, .day], from: date1)
var components2 = greg.dateComponents([.year, .month, .day], from: date2)
date1 = greg.date(from: components1)!
date2 = greg.date(from: components2)!

let daysAlive = (date2 - date1).in(.day)
let weeksAlive = Int(weeksAlive! / 7)
let restDays = daysAlive! - (weeksAlive * 7)
let aLive = "Age: \(weeksAlive) wk, \(restDays) d (\(daysAlive!) d)"

答案 1 :(得分:2)

要忽略时间,只需省略.hour.minute.second

的组件
let components1 = greg.dateComponents([.year, .month, .day], from: date1)
let components2 = greg.dateComponents([.year, .month, .day], from: date2)

date1 = greg.date(from: components1)!
date2 = greg.date(from: components2)!

这是一个没有任何第三方库的简单解决方案。它使用weekOfMonth方法daydayCalendar计算一次差异,为dateComponents(:from:to:计算一次差异let greg = Calendar(identifier: .gregorian) var date1 = greg.date(from: DateComponents(year: 2017, month: 6, day: 25))! var date2 = Date() var components1 = greg.dateComponents([.year, .month, .day], from: date1) var components2 = greg.dateComponents([.year, .month, .day], from: date2) let weeksAndDays = greg.dateComponents([.weekOfMonth, .day], from: components1, to: components2) let justDays = greg.dateComponents([.day], from: components1, to: components2) let aLive = "Age: \(weeksAndDays.weekOfMonth!) wk, \(weeksAndDays.day!) d (\(justDays.day!) d)" // "Age: 28 wk, 3 d (199 d)" 。不需要额外的数学。

{{1}}

答案 2 :(得分:2)

正如其他人所指出的那样,您可以从日历中抓取.year.month.day。您可能还会看到DateComponentsFormatter是否可以达到您想要的效果:

let formatter: DateComponentsFormatter = {
    let _formatter = DateComponentsFormatter()
    _formatter.allowedUnits = [.day, .weekOfMonth]
    _formatter.unitsStyle = .full
    return _formatter
}()

@IBAction func didValueChange(_ picker: UIDatePicker) {
    let calendar = Calendar.current

    let birthDate = calendar.date(from: calendar.dateComponents([.year, .month, .day], from: picker.date))!
    let now = calendar.date(from: calendar.dateComponents([.year, .month, .day], from: Date()))!
    label.text = formatter.string(from: birthDate, to: now)
}

虽然DateComponentsFormatter对结果有一点限制,但它已本地化,导致以下美国语言环境:

  

28周,3天

但是,如果您的应用配置为支持其他语言环境,例如德语,则会产生:

  

28 Wochen und 3 Tage