Với Swift 3, theo nhu cầu của bạn, bạn có thể chọn một trong hai cách sau để giải quyết vấn đề của mình.
1. Hiển thị sự khác biệt giữa hai ngày cho người dùng
Bạn có thể sử dụng a DateComponentsFormatter
để tạo chuỗi cho giao diện của ứng dụng. DateComponentsFormatter
có một maximumUnitCount
tài sản với tuyên bố sau:
var maximumUnitCount: Int { get set }
Sử dụng thuộc tính này để giới hạn số lượng đơn vị được hiển thị trong chuỗi kết quả. Ví dụ: với thuộc tính này được đặt thành 2, thay vì 1 giờ 10m, 30 giây, chuỗi kết quả sẽ là 1 giờ 10 phút. Sử dụng thuộc tính này khi bạn bị hạn chế về không gian hoặc muốn làm tròn các giá trị cho đơn vị lớn gần nhất.
Bằng cách đặt maximumUnitCount
giá trị thành 1
, bạn được đảm bảo hiển thị mức chênh lệch chỉ trong một DateComponentsFormatter
đơn vị (năm, tháng, ngày, giờ hoặc phút).
Mã Playground bên dưới hiển thị cách hiển thị sự khác biệt giữa hai ngày:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
Lưu ý rằng làm DateComponentsFormatter
tròn kết quả. Do đó, chênh lệch 4 giờ và 30 phút sẽ được hiển thị là 5 giờ .
Nếu bạn cần lặp lại thao tác này, bạn có thể cấu trúc lại mã của mình:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. Nhận sự khác biệt giữa hai ngày mà không cần định dạng
Nếu bạn không cần hiển thị với định dạng chênh lệch giữa hai ngày cho người dùng, bạn có thể sử dụng Calendar
. Calendar
có một phương thức dateComponents(_:from:to:)
có khai báo sau:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Trả về sự khác biệt giữa hai ngày.
Mã Playground bên dưới sử dụng dateComponents(_:from:to:)
cho thấy cách lấy lại sự khác biệt giữa hai ngày bằng cách trả lại chênh lệch chỉ trong một loại Calendar.Component
(năm, tháng, ngày, giờ hoặc phút).
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
Nếu bạn cần lặp lại thao tác này, bạn có thể cấu trúc lại mã của mình:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}
NSDateComponentsFormatter
. Nó rất có thể cấu hình, cho phép bạn có được kết quả ngắn gọn phù hợp (ví dụ.maximumUnitCount = 1
).