Сравнение NSDate с помощью Swift
Я работаю над приложением, которое требует проверки срока выполнения домашнего задания. Я хочу знать, если срок в течение следующей недели, и если затем выполнить действие.
Большая часть документации, которую я смог найти, находится в Objective-C, и я не могу понять, как это сделать в Swift.
Спасибо за помощь!!
16 ответов:
мне нравится использовать расширения, чтобы сделать код более читабельным. Вот несколько расширений NSDate, которые могут помочь очистить ваш код и сделать его легким для понимания. Я положил это в sharedCode.swift file:
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 } }теперь, если вы можете сделать что-то вроде этого:
//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... }
если вы хотите поддержать
==,<,>,<=или>=наNSDates, вы просто должны объявить это где-то: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 { }
вот как вы сравниваете два NSDates в Swift, я только что протестировал его на игровой площадке 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"); }чтобы проверить, если дата
dueDateв течение недели отныне: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)"); }
Я всегда делал это в одну строку:
let greater = date1.timeIntervalSince1970 < date2.timeIntervalSince1970все еще читается в
ifблок
в Swift3, the
Datestruct вFoundationТеперь реализующийComparableпротокол. Итак, предыдущий Swift2NSDateподходы заменяются Swift3Date./** `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 }Примечание ...
В Swift3,
Dateиstruct, это значит, что этоvalue type.NSDateиclass, это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`.
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 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 } }для других сравнений календаря изменить .день до;
.год .месяц .день .час .минута .второй
Swift уже реализовать сравнение дат просто использовать date1 > date2 и так далее.
/// 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)
в Swift 3 Дата сопоставима, поэтому мы можем напрямую сравнивать даты, такие как
let date1 = Date() let date2 = Date() let isGreater = date1 > date2 print(isGreater) let isEqual = date1 == date2 print(isEqual)или
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") }лучший способ создания
extensionна дату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 } }использование
let isGreater = date1.isGreater(than: date2)
эта функция работала для меня для сравнения, была ли одна дата (startDate) после endDate, где оба были определены как переменные NSDate:
if startDate.compare(endDate as Date) == ComparisonResult.orderedDescending
реализации в
Swiftlet 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)
у нас есть сценарий для проверки текущего времени лежит ч/б два раза (две даты).Например, я хочу проверить текущую ложь между временем открытия клиники(больницы) и временем закрытия.
использовать простой код.
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"); }
для swift 3, Вы можете использовать функцию ниже, чтобы сравнить между двумя датами.
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 может быть изменен в соответствии с ограничениями, на которые вы хотите применить сравнение.
продлить на SashaZ
СвифтiOS 8 и до когда вам нужно больше, чем просто большие или меньшие сравнения даты. Например, это тот же день или предыдущий день,...
Примечание: никогда не забывайте о часовом поясе. Календарь часовой пояс по умолчанию, но если вам не нравится по умолчанию, вы должны установить часовой пояс самостоятельно. Чтобы узнать, какой сегодня день, вам нужно знать, в каком часовом поясе вы находитесь расспрашивать.
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) } }используйте его так:
if thisDate.compareTo(date: Date(), toGranularity: .day) == .orderedDescending { // thisDate is a previous day }более сложный пример. Найдите и отфильтруйте все даты в массиве, которые относятся к тому же дню, что и "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: , toGranularity: .day) == .orderedSame } .map { print(formatter.string(from: )) }
someArray.sort({(.dateAdded?.timeIntervalSinceReferenceDate)! < (.dateAdded?.timeIntervalSinceReferenceDate)!})dateAdded-это переменная NSDate в моем объекте
class MyClass { let dateAdded: NSDate? }
Comments