Con Swift 3, de acuerdo con sus necesidades, puede elegir una de las dos formas siguientes para resolver su problema.
1. Mostrar la diferencia entre dos fechas para el usuario
Puede usar a DateComponentsFormatter
para crear cadenas para la interfaz de su aplicación. DateComponentsFormatter
tiene una maximumUnitCount
propiedad con la siguiente declaración:
var maximumUnitCount: Int { get set }
Use esta propiedad para limitar el número de unidades que se muestran en la cadena resultante. Por ejemplo, con esta propiedad establecida en 2, en lugar de "1h 10m, 30s", la cadena resultante sería "1h 10m". Use esta propiedad cuando tenga limitaciones de espacio o desee redondear los valores a la unidad grande más cercana.
Al establecer maximumUnitCount
el valor en 1
, tiene la garantía de mostrar la diferencia en una sola DateComponentsFormatter
unidad (años, meses, días, horas o minutos).
El siguiente código de Playground muestra cómo mostrar la diferencia entre dos fechas:
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")
Tenga en cuenta que DateComponentsFormatter
redondea el resultado. Por lo tanto, una diferencia de 4 horas y 30 minutos se mostrará como 5 horas .
Si necesita repetir esta operación, puede refactorizar su 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. Obtenga la diferencia entre dos fechas sin formatear
Si no necesita mostrar con el formato la diferencia entre dos fechas para el usuario, puede usar Calendar
. Calendar
tiene un método dateComponents(_:from:to:)
que tiene la siguiente declaración:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Devuelve la diferencia entre dos fechas.
El siguiente código de Playground que se usa dateComponents(_:from:to:)
muestra cómo recuperar la diferencia entre dos fechas devolviendo la diferencia en un solo tipo de Calendar.Component
(años, meses, días, horas o 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
}
}
Si necesita repetir esta operación, puede refactorizar su 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
. Es muy configurable, lo que le permite obtener resultados concisos (p.maximumUnitCount = 1
. Ej .).