dateformat - swift get date in format
ComparaciĆ³n NSDate usando Swift (16)
Estoy trabajando en una aplicación que requiere verificar la fecha de vencimiento para la tarea. Quiero saber si hay una fecha de vencimiento dentro de la próxima semana y, si es así, realizar una acción.
La mayor parte de la documentación que pude encontrar está en Objective-C y no puedo entender cómo hacerlo en Swift. ¡¡Gracias por la ayuda!!
Así es como se comparan dos NSDates en Swift, acabo de probarlo en el patio de Xcode:
if date1.compare(date2) == NSComparisonResult.OrderedDescending
{
NSLog("date1 after date2");
} else if date1.compare(date2) == NSComparisonResult.OrderedAscending
{
NSLog("date1 before date2");
} else
{
NSLog("dates are equal");
}
Entonces, para verificar si una fecha dueDate
está dentro de una semana a partir de ahora:
let dueDate=...
let calendar = NSCalendar.currentCalendar()
let comps = NSDateComponents()
comps.day = 7
let date2 = calendar.dateByAddingComponents(comps, toDate: NSDate(), options: NSCalendarOptions.allZeros)
if dueDate.compare(date2!) == NSComparisonResult.OrderedDescending
{
NSLog("not due within a week");
} else if dueDate.compare(date2!) == NSComparisonResult.OrderedAscending
{
NSLog("due within a week");
} else
{
NSLog("due in exactly a week (to the second, this will rarely happen in practice)");
}
En Swift3, la Estructura de Date
en la Foundation
ahora implementa el protocolo Comparable
. Por lo tanto, los enfoques previos Swift2 NSDate
son reemplazados por Swift3 Date
.
/**
`Date` represents a single point in time.
A `Date` is independent of a particular calendar or time zone. To represent a `Date` to a user, you must interpret it in the context of a `Calendar`.
*/
public struct Date : ReferenceConvertible, Comparable, Equatable {
// .... more
/**
Returns the interval between the receiver and another given date.
- Parameter another: The date with which to compare the receiver.
- Returns: The interval between the receiver and the `another` parameter. If the receiver is earlier than `anotherDate`, the return value is negative. If `anotherDate` is `nil`, the results are undefined.
- SeeAlso: `timeIntervalSince1970`
- SeeAlso: `timeIntervalSinceNow`
- SeeAlso: `timeIntervalSinceReferenceDate`
*/
public func timeIntervalSince(_ date: Date) -> TimeInterval
// .... more
/// Returns true if the two `Date` values represent the same point in time.
public static func ==(lhs: Date, rhs: Date) -> Bool
/// Returns true if the left hand `Date` is earlier in time than the right hand `Date`.
public static func <(lhs: Date, rhs: Date) -> Bool
/// Returns true if the left hand `Date` is later in time than the right hand `Date`.
public static func >(lhs: Date, rhs: Date) -> Bool
/// Returns a `Date` with a specified amount of time added to it.
public static func +(lhs: Date, rhs: TimeInterval) -> Date
/// Returns a `Date` with a specified amount of time subtracted from it.
public static func -(lhs: Date, rhs: TimeInterval) -> Date
// .... more
}
Nota ...
En Swift3, Date
es struct
, significa que es un value type
. NSDate
es class
, es reference type
.
// Swift3
let a = Date()
let b = a //< `b` will copy `a`.
// So, the addresses between `a` and `b` are different.
// `Date` is some kind different with `NSDate`.
Esta función funcionó para mí para comparar si una fecha (fecha de inicio) era posterior a la fecha final donde ambas se definieron como variables NSDate:
if startDate.compare(endDate as Date) == ComparisonResult.orderedDescending
Me gusta usar extensiones para hacer que el código sea más legible. Aquí hay algunas extensiones de NSDate que pueden ayudarlo a limpiar su código y hacerlo más fácil de entender. Puse esto en un archivo sharedCode.swift:
extension NSDate {
func isGreaterThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending {
isGreater = true
}
//Return Result
return isGreater
}
func isLessThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isLess = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedAscending {
isLess = true
}
//Return Result
return isLess
}
func equalToDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isEqualTo = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedSame {
isEqualTo = true
}
//Return Result
return isEqualTo
}
func addDays(daysToAdd: Int) -> NSDate {
let secondsInDays: NSTimeInterval = Double(daysToAdd) * 60 * 60 * 24
let dateWithDaysAdded: NSDate = self.dateByAddingTimeInterval(secondsInDays)
//Return Result
return dateWithDaysAdded
}
func addHours(hoursToAdd: Int) -> NSDate {
let secondsInHours: NSTimeInterval = Double(hoursToAdd) * 60 * 60
let dateWithHoursAdded: NSDate = self.dateByAddingTimeInterval(secondsInHours)
//Return Result
return dateWithHoursAdded
}
}
Ahora si puedes hacer algo como esto:
//Get Current Date/Time
var currentDateTime = NSDate()
//Get Reminder Date (which is Due date minus 7 days lets say)
var reminderDate = dueDate.addDays(-7)
//Check if reminderDate is Greater than Right now
if(reminderDate.isGreaterThanDate(currentDateTime)) {
//Do Something...
}
Para extender en SashaZ
Swift iOS 8 en adelante Cuando necesita más que simples comparaciones de fechas más grandes o más pequeñas. Por ejemplo, es el mismo día o el día anterior, ...
Nota: Nunca olvides la zona horaria. La zona horaria del calendario tiene un valor predeterminado, pero si no le gusta el valor predeterminado, debe configurar la zona horaria usted mismo. Para saber qué día es, necesita saber en qué zona horaria está preguntando.
extension Date {
func compareTo(date: Date, toGranularity: Calendar.Component ) -> ComparisonResult {
var cal = Calendar.current
cal.timeZone = TimeZone(identifier: "Europe/Paris")!
return cal.compare(self, to: date, toGranularity: toGranularity)
}
}
Úselo así:
if thisDate.compareTo(date: Date(), toGranularity: .day) == .orderedDescending {
// thisDate is a previous day
}
De un ejemplo más complejo. Busque y filtre todas las fechas en una matriz, que son del mismo día que "findThisDay":
let formatter = DateFormatter()
formatter.timeZone = TimeZone(identifier: "Europe/Paris")
formatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
let findThisDay = formatter.date(from: "2018/11/05 08:11:08")!
_ = [
formatter.date(from: "2018/12/05 08:08:08")!,
formatter.date(from: "2018/11/05 08:11:08")!,
formatter.date(from: "2018/11/05 11:08:22")!,
formatter.date(from: "2018/11/05 22:08:22")!,
formatter.date(from: "2018/11/05 08:08:22")!,
formatter.date(from: "2018/11/07 08:08:22")!,
]
.filter{ findThisDay.compareTo(date: $0 , toGranularity: .day) == .orderedSame }
.map { print(formatter.string(from: $0)) }
Para swift 3, puede usar la función siguiente para comparar dos fechas.
func compareDate(dateInitial:Date, dateFinal:Date) -> Bool {
let order = Calendar.current.compare(dateInitial, to: dateFinal, toGranularity: .day)
switch order {
case .orderedSame:
return true
default:
return false
}
}
toGranularity se puede cambiar de acuerdo con las restricciones sobre las que desea aplicar su comparación.
Si desea comparar fechas con granularidad (solo el mismo día o año, etc.), agítese 3.
func compareDate(date1:NSDate, date2:NSDate, toUnitGranularity: NSCalendar.Unit) -> Bool {
let order = NSCalendar.current.compare(date1 as Date, to: date2 as Date, toGranularity: .day)
switch order {
case .orderedSame:
return true
default:
return false
}
}
Para otras comparaciones de calendario, cambie .day a;
.year .month .day .hour .minute .second
Si desea soportar ==
, <
, >
, <=
, o >=
para NSDate
s, solo tiene que declarar esto en alguna parte:
public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs === rhs || lhs.compare(rhs) == .OrderedSame
}
public func <(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedAscending
}
extension NSDate: Comparable { }
Siempre lo hice en una línea:
let greater = date1.timeIntervalSince1970 < date2.timeIntervalSince1970
Todavía legible en el bloque if
Swift ya implementa la comparación de fechas simplemente use date1> date2 y así sucesivamente.
/// Returns true if the two `Date` values represent the same point in time.
public static func ==(lhs: Date, rhs: Date) -> Bool
/// Returns true if the left hand `Date` is earlier in time than the right hand `Date`.
public static func <(lhs: Date, rhs: Date) -> Bool
/// Returns true if the left hand `Date` is later in time than the right hand `Date`.
public static func >(lhs: Date, rhs: Date) -> Bool
/// Returns a `Date` with a specified amount of time added to it.
public static func +(lhs: Date, rhs: TimeInterval) -> Date
/// Returns a `Date` with a specified amount of time subtracted from it.
public static func -(lhs: Date, rhs: TimeInterval) -> Date
/// Add a `TimeInterval` to a `Date`.
///
/// - warning: This only adjusts an absolute value. If you wish to add calendrical concepts like hours, days, months then you must use a `Calendar`. That will take into account complexities like daylight saving time, months with different numbers of days, and more.
public static func +=(lhs: inout Date, rhs: TimeInterval)
/// Subtract a `TimeInterval` from a `Date`.
///
/// - warning: This only adjusts an absolute value. If you wish to add calendrical concepts like hours, days, months then you must use a `Calendar`. That will take into account complexities like daylight saving time, months with different numbers of days, and more.
public static func -=(lhs: inout Date, rhs: TimeInterval)
Tenemos un escenario para verificar el tiempo actual miente dos veces (dos fechas). Por ejemplo, quiero verificar el tiempo actual entre el horario de apertura de la clínica (hospital) y el horario de cierre.
Usa el código simple.
NSDate * now = [NSDate date];
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:@"HH:mm:ss"];
//current time
NSString *currentTimeString = [outputFormatter stringFromDate:now];
NSDate *dateCurrent = [outputFormatter dateFromString:currentTimeString];
NSString *timeStart = @"09:00:00";
NSString *timeEnd = @"22:00:00";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"HH:mm:ss"];
NSDate *dateStart= [formatter timeStart];
NSDate *dateEnd = [formatter timeEnd];
NSComparisonResult result = [dateCurrent compare:dateStart];
NSComparisonResult resultSecond = [date2 compare:dateEnd];
if(result == NSOrderedDescending && resultSecond == NSOrderedDescending)
{
NSLog(@"current time lies in starting and end time");
}else {
NSLog(@"current time doesn''t lie in starting and end time");
}
en Swift 3, la fecha es comparable, por lo que podemos comparar fechas directamente como
let date1 = Date()
let date2 = Date()
let isGreater = date1 > date2
print(isGreater)
let isEqual = date1 == date2
print(isEqual)
o alternativamente
let result = date1.compare(date2)
switch result {
case .OrderedAscending : print("date 1 is earlier than date 2")
case .OrderedDescending : print("date 1 is later than date 2")
case .OrderedSame : print("two dates are the same")
}
mejor forma de crear extension
en la fecha
extension Date {
fun isGreater(than date: Date) -> Bool {
return self > date
}
func isSmaller(than date: Date) -> Bool {
return self < date
}
func isEqual(to date: Date) -> Bool {
return self == date
}
}
use let isGreater = date1.isGreater(than: date2)
implementación en Swift
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let files = NSFileManager.defaultManager().contentsOfDirectoryAtPath(documentsPath, error: nil)
let filesAndProperties = NSMutableArray()
for file in files! {
let filePath = documentsPath.stringByAppendingString(file as NSString)
let properties = NSFileManager.defaultManager().attributesOfItemAtPath(filePath, error: nil)
let modDate = properties![NSFileModificationDate] as NSDate
filesAndProperties.addObject(NSDictionary(objectsAndKeys: file, "path", modDate, "lastModDate"))
}
let sortedFiles = filesAndProperties.sortedArrayUsingComparator({
(path1, path2) -> NSComparisonResult in
var comp = (path1.objectForKey("lastModDate") as NSDate).compare(path2.objectForKey("lastModDate") as NSDate)
if comp == .OrderedDescending {
comp = .OrderedAscending
} else if comp == .OrderedAscending {
comp = .OrderedDescending
}
return comp
})
extension NSDate {
// MARK: - Dates comparison
func isGreaterThanDate(dateToCompare: NSDate) -> Bool {
return self.compare(dateToCompare) == NSComparisonResult.OrderedDescending
}
func isLessThanDate(dateToCompare: NSDate) -> Bool {
return self.compare(dateToCompare) == NSComparisonResult.OrderedAscending
}
func equalToDate(dateToCompare: NSDate) -> Bool {
return self.compare(dateToCompare) == NSComparisonResult.OrderedSame
}
}
someArray.sort({($0.dateAdded?.timeIntervalSinceReferenceDate)! < ($1.dateAdded?.timeIntervalSinceReferenceDate)!})
dateAdded es una variable NSDate en mi objeto
class MyClass {
let dateAdded: NSDate?
}
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateData: String = dateFormatter.stringFromDate(date1)
let testDate: String = dateFormatter.stringFromDate(date2)
print(dateData == testDate)