我正在尝试计算宠物活着的周数和天数。我正在使用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天)”
代码有效......但我怎样才能重构呢?是否有更简单的方法为两个给定日期设置“同一时间”?
答案 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
方法day
为day
和Calendar
计算一次差异,为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