用户可以销售商品并添加自当前日期起1-3周的有效期。
这就是我将过期日期存储为Double
的方式。我是否需要明确其他日期组件,如年,月等?
enum Weeks: Int {
case one
case two
case three
}
extension Weeks {
var timeInterval: Double? {
let currentDate = Date()
let calendar = Calendar.current
let calendarComponents: Set<Calendar.Component> = Set(arrayLiteral: Calendar.Component.year, Calendar.Component.month, Calendar.Component.day, Calendar.Component.hour, Calendar.Component.minute, Calendar.Component.second)
var components = calendar.dateComponents(calendarComponents, from: currentDate)
switch self {
case .one: components.weekOfMonth = 1
case .two: components.weekOfMonth = 2
case .three: components.weekOfMonth = 3
}
if let expirationDate = calendar.date(from: components) {
return expirationDate.timeIntervalSince1970 as Double
} else {
return nil
}
}
}
这就是我计算Date
扩展名中的倒计时的方式:
func countdown(to date: Date) -> CountdownResponse {
let difference = Calendar.current.dateComponents([.day, .hour, .minute, .second], from: self, to: date)
guard let day = difference.day, let hour = difference.hour, let minute = difference.minute, let second = difference.second else {
return .error(message: "One or more date components are nil.")
}
if day <= 0 && hour <= 0 && minute <= 0 && second <= 0 {
return .isFinished
}
let days = displayableText(from: difference.day)
let hours = displayableText(from: difference.hour)
let minutes = displayableText(from: difference.minute)
let seconds = displayableText(from: difference.second)
let timeRemaining = "\(days) : \(hours) : \(minutes) : \(seconds)"
return .result(time: timeRemaining)
}
这就是我想要倒计时的方式,然后检查错误或结果的响应枚举。但这给了我不正确的时间。
let expirationDate = Date(timeIntervalSince1970: self.item.expirationDate)
let response = currentDate.countdown(to: expirationDate)
当我手动创建日期并进行如下测试时,它会按预期工作。
var comp = calendar.dateComponents(calendarComponents, from: Date())
comp.year = 2017
comp.month = 8
comp.day = 24
comp.minute = 50
comp.second = 30
我做错了什么?我是否将日期作为时间间隔错误地保留,或者从timeInterval创建日期不正确?
当我查看代码时,我意识到我可能正在计算错误的一周。如果它是该月的第二周并且用户选择项目在3周内过期,则每周的周数不应为3,则需要从当月的当周开始的3周。有关如何修复此逻辑的任何指导都表示赞赏。
答案 0 :(得分:0)
为什么你的代码如此复杂? Foundation框架提供您所需的一切,从日历计算(添加和减去日期)到输出格式(x天,y小时,z分钟等)。
以下是如何缩短它的示例:
enum Week: Int {
case one = 7, two = 14, three = 21
}
enum CountdownResponse {
case isFinished
case result(time: String)
}
struct ProductListing {
// Customize this if you want to change timeRemaining's format
// It automatically take care of singular vs. plural, i.e. 1 hr and 2 hrs
private static let dateComponentFormatter: DateComponentsFormatter = {
var formatter = DateComponentsFormatter()
formatter.allowedUnits = [.day, .hour, .minute, .second]
formatter.unitsStyle = .short
return formatter
}()
var listingDate: Date
var duration: Week
var expirationDate: Date {
return Calendar.current.date(byAdding: .day, value: duration.rawValue, to: listingDate)!
}
var timeRemaining: CountdownResponse {
let now = Date()
if expirationDate <= now {
return .isFinished
} else {
let timeRemaining = ProductListing.dateComponentFormatter.string(from: now, to: expirationDate)!
return .result(time: timeRemaining)
}
}
}
// Usage
let august01 = DateComponents(calendar: .current, year: 2017, month: 8, day: 1).date!
let august19 = DateComponents(calendar: .current, year: 2017, month: 8, day: 19).date!
let listing1 = ProductListing(listingDate: august01, duration: .three)
let listing2 = ProductListing(listingDate: august19, duration: .one)
print(listing1.timeRemaining) // .isFinished
print(listing2.timeRemaining) // .result("2 days, 4 hrs, 9 min, 23 secs")
但是请注意,随着时间的变化,计算在时钟变化时间内变得非常毛茸茸。我没有使用上面的代码测试这些边缘情况。