Com o Swift 3, de acordo com suas necessidades, você pode escolher uma das duas maneiras a seguir para resolver seu problema.
1. Exiba a diferença entre duas datas para o usuário
Você pode usar a DateComponentsFormatter
para criar strings para a interface do seu aplicativo. DateComponentsFormatter
possui uma maximumUnitCount
propriedade com a seguinte declaração:
var maximumUnitCount: Int { get set }
Use esta propriedade para limitar o número de unidades exibidas na sequência resultante. Por exemplo, com essa propriedade definida como 2, em vez de "1h 10m, 30s", a sequência resultante seria "1h 10m". Use essa propriedade quando estiver com restrições de espaço ou desejar arredondar valores para a unidade grande mais próxima.
Ao definir maximumUnitCount
o valor como 1
, você garante a exibição da diferença em apenas uma DateComponentsFormatter
unidade (anos, meses, dias, horas ou minutos).
O código do Playground abaixo mostra como exibir a diferença entre duas datas:
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")
Observe que DateComponentsFormatter
arredonda o resultado. Portanto, uma diferença de 4 horas e 30 minutos será exibida como 5 horas .
Se precisar repetir esta operação, você pode refatorar seu código:
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. Obtenha a diferença entre duas datas sem formatação
Se você não precisar exibir com formatação a diferença entre duas datas para o usuário, poderá usar Calendar
. Calendar
possui um método dateComponents(_:from:to:)
que possui a seguinte declaração:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Retorna a diferença entre duas datas.
O código do Playground abaixo que usa dateComponents(_:from:to:)
mostra como recuperar a diferença entre duas datas retornando a diferença em apenas um tipo de Calendar.Component
(anos, meses, dias, horas ou minutos).
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
}
}
Se precisar repetir esta operação, você pode refatorar seu código:
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
. É muito configurável, permitindo obter resultados adequadamente concisos (por exemplo.maximumUnitCount = 1
).