[英]SwiftDate and date calculation
I'm trying to calculate the number of weeks and days that a pet is alive. 我正在尝试计算宠物存活的周数和天数。 I'm using SwiftDate for that.
我为此使用SwiftDate。 So I let the user select a birthdate and compare it to the current date.
因此,我让用户选择一个生日并将其与当前日期进行比较。
I don't want to compare the time... so both the birthdate and current date should have the same time. 我不想比较时间...所以生日和当前日期应该有相同的时间。
My code is: 我的代码是:
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)"
Output is "Age: 28 wk, 3 d (199 d)" 输出为“年龄:28周,3天(199天)”
The code works... but how can I refactor it? 该代码有效...但是如何重构它? And is there an easier way to set the 'same time' for two given dates?
有没有更简单的方法来设置两个给定日期的“相同时间”?
If you don't care about the time difference, why not just leave the time out completely? 如果您不关心时差,为什么不完全将时间留在外面呢? It would give you the same output, and would just save you from putting in default time values and then ignoring them for the rest of your function:
它将为您提供相同的输出,并且只会使您免于放入默认时间值,然后在其余功能中忽略它们:
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)"
To ignore the time just omit the components for .hour
, .minute
and .second
要忽略时间,只需省略
.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)!
This is a simpler solution without any third party library. 这是一个没有任何第三方库的简单解决方案。 It calculates the difference once for
weekOfMonth
and day
and once for day
with the Calendar
method dateComponents(:from:to:
. Extra math is not needed. 它计算的差异一次
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)"
As others have pointed out, you can just grab .year
, .month
, .day
from your calendar. 正如其他人指出的那样,您只需从日历中获取
.year
, .month
, .day
。 You might also see if DateComponentsFormatter
can achieve what you want: 您可能还会看到
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)
}
While the DateComponentsFormatter
is a little constrained regarding the results, it is localized, resulting in the following in US locale: 尽管
DateComponentsFormatter
在结果方面有所限制,但它已本地化,在美国语言环境中导致以下情况:
28 weeks, 3 days
28周3天
But if your app is configured to support other locales, for example German, it results in: 但是,如果您的应用配置为支持其他语言环境,例如德语,则会导致:
28 Wochen und 3 Tage
28月和3击
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.