Je travaille sur une application qui nécessite de vérifier la date d'échéance des devoirs. Je veux savoir si une date d'échéance est dans la semaine prochaine, et si c'est alors effectuer une action.
La plupart de la documentation que j'ai pu trouver se trouve dans Objective-C et je ne vois pas comment le faire dans Swift. Merci pour l'aide!!
J'aime utiliser des extensions pour rendre le code plus lisible. Voici quelques extensions NSDate qui peuvent vous aider à nettoyer votre code et à le rendre facile à comprendre. Je mets cela dans un fichier sharedCode.Swift:
extension NSDate {
func isGreaterThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare as Date) == ComparisonResult.orderedDescending {
isGreater = true
}
//Return Result
return isGreater
}
func isLessThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isLess = false
//Compare Values
if self.compare(dateToCompare as Date) == ComparisonResult.orderedAscending {
isLess = true
}
//Return Result
return isLess
}
func equalToDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isEqualTo = false
//Compare Values
if self.compare(dateToCompare as Date) == ComparisonResult.orderedSame {
isEqualTo = true
}
//Return Result
return isEqualTo
}
func addDays(daysToAdd: Int) -> NSDate {
let secondsInDays: TimeInterval = Double(daysToAdd) * 60 * 60 * 24
let dateWithDaysAdded: NSDate = self.addingTimeInterval(secondsInDays)
//Return Result
return dateWithDaysAdded
}
func addHours(hoursToAdd: Int) -> NSDate {
let secondsInHours: TimeInterval = Double(hoursToAdd) * 60 * 60
let dateWithHoursAdded: NSDate = self.addingTimeInterval(secondsInHours)
//Return Result
return dateWithHoursAdded
}
}
Maintenant, si vous pouvez faire quelque chose comme ça:
//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...
}
Si vous voulez prendre en charge ==
, <
, >
, <=
ou >=
pour NSDate
s, il vous suffit de le déclarer quelque part:
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 { }
Voici comment vous comparez deux NSDates dans Swift, je viens de le tester sur le terrain de jeu 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");
}
Donc, pour vérifier si une date dueDate
est dans une semaine:
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)");
}
Je l'ai toujours fait en une seule ligne:
let greater = date1.timeIntervalSince1970 < date2.timeIntervalSince1970
Toujours lisible dans le bloc if
Dans Swift3, la structure Date
de la Foundation
implémente désormais le protocole Comparable
. Ainsi, les approches précédentes de Swift2 NSDate
sont remplacées par 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
}
Dans Swift3, Date
est struct
, cela signifie que c'est value type
. NSDate
est class
, c'est 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`.
Si vous souhaitez comparer des dates avec une granularité (le même jour ou la même année, etc.) le Swift 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
}
}
Pour les autres comparaisons de calendrier, changez .day en;
.année .mois. jour. heure. minute. seconde
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
}
}
Swift a déjà implémenté la comparaison de Date, utilisez simplement date1> date2 et ainsi de suite.
/// 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)
dans Swift 3, la date est comparable afin que nous puissions comparer directement les dates comme
let date1 = Date()
let date2 = Date()
let isGreater = date1 > date2
print(isGreater)
let isEqual = date1 == date2
print(isEqual)
ou bien
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")
}
meilleure façon de créer extension
sur Date
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
}
}
usage let isGreater = date1.isGreater(than: date2)
Cette fonction m'a permis de comparer si une date (startDate) était postérieure à endDate où les deux étaient définies en tant que variables NSDate:
if startDate.compare(endDate as Date) == ComparisonResult.orderedDescending
implémentation dans 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
})
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateData: String = dateFormatter.stringFromDate(date1)
let testDate: String = dateFormatter.stringFromDate(date2)
print(dateData == testDate)
Étendre SashaZ
SwiftiOS 8 et plus Lorsque vous avez besoin de plus que des comparaisons de dates plus grandes ou plus petites. Par exemple, est-ce le même jour ou le jour précédent, ...
Note: N'oubliez jamais le fuseau horaire. Le fuseau horaire de calendrier a une valeur par défaut, mais si vous n'aimez pas la valeur par défaut, vous devez le définir vous-même. Pour savoir de quel jour il s’agit, vous devez savoir dans quel fuseau horaire vous demandez.
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)
}
}
Utilisez-le comme ceci:
if thisDate.compareTo(date: Date(), toGranularity: .day) == .orderedDescending {
// thisDate is a previous day
}
D'un exemple plus complexe. Recherchez et filtrez toutes les dates d'un tableau datant du même jour 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)) }
Pour Swift 3, vous pouvez utiliser la fonction ci-dessous pour comparer deux dates.
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
}
}
la granularité peut être modifiée en fonction des contraintes sur lesquelles vous souhaitez appliquer votre comparaison.
Nous avons un scénario pour vérifier l’heure actuelle se trouve n/b deux fois (deux dates) .Par exemple, je souhaite vérifier le mensonge actuel entre l’heure d’ouverture de la clinique (Hôpital) et l’heure de fermeture.
Utilisez le code 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");
}
someArray.sort({($0.dateAdded?.timeIntervalSinceReferenceDate)! < ($1.dateAdded?.timeIntervalSinceReferenceDate)!})
dateAdded est une variable NSDate dans mon objet
class MyClass {
let dateAdded: NSDate?
}