使用Swift进行NSDate比较

Hen*_*ler 150 nsdate swift xcode6

我正在开发一个应用程序,需要检查作业的截止日期.我想知道截止日期是否在下周内,如果是,则执行操作.
我能找到的大部分文档都在Objective-C中,我无法弄清楚如何在Swift中完成它.谢谢您的帮助!!

Joh*_*pia 207

如果你想支持==,<,>,<=,或>=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 { }
Run Code Online (Sandbox Code Playgroud)

  • 这正是我所寻找的.这是最快捷的方式 (9认同)
  • @dVaffection在Objective-C(声明了NSDate和朋友)中,如果你使用`==`,`<`,`>`等进行比较,你会得到他们在内存中的地址比较结果,而不是他们实际价值的比较.在Swift中,它们仍被视为引用,因此我认为选择是(1)保持按指针比较,因为它们在ObjC中,或者(2)通过不提供比较实现来消除混淆. (3认同)
  • @Isuru`Comparable`是`Equatable`协议的后代,所以你不需要声明两者的一致性. (2认同)
  • 只是好奇为什么它默认不是内置的?! (2认同)
  • 这种方法的另一个好处是,`Array.maxElement()`等随后可以自动获得NSDates数组. (2认同)

小智 187

我喜欢使用扩展来使代码更具可读性.以下是一些NSDate扩展,可以帮助您清理代码并使其易于理解.我把它放在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
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你能做到这样的事情:

//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...
}
Run Code Online (Sandbox Code Playgroud)

  • 你应该简化你的代码.`return self.compare(dateToCompare)== NSComparisonResult.OrderedDescending` (28认同)
  • 这个答案很可怕,永远不应该被接受.不要**为您创建的日期添加时间间隔.这就是为什么存在`NSDateComponents`的原因.有很多边缘情况没有得到正确处理,没有必要不将"Comparable"的符合性添加到"NSDate".我建议使用[John的解决方案](http://stackoverflow.com/a/28109990/2305521). (9认同)
  • isEqualToDate也由Apple提供.它的声明与Apple定义的声明冲突. (5认同)
  • 不是每天都有24小时 (4认同)
  • 一个更好的解决方案是使NSDate Equatable,Comparable,然后你可以简单地做`date1 <date2` (3认同)
  • 我已经简化了你的代码......重构了它.正如@ShamasS已经指出的那样,`isEqualToDate`已经存在并且不需要.我的结果:https://gist.github.com/ppeelen/e71c4dd1c3070b3549be (2认同)

Und*_*ndo 54

这是你在Swift中比较两个NSDates的方法,我刚在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");
}
Run Code Online (Sandbox Code Playgroud)

因此,要检查日期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)");
}
Run Code Online (Sandbox Code Playgroud)

  • do ordered Descending意味着date1> date2? (2认同)

ReD*_*ion 46

我总是在一行中做到:

let greater = date1.timeIntervalSince1970 < date2.timeIntervalSince1970
Run Code Online (Sandbox Code Playgroud)

if块中仍然可读


Aec*_*Liu 12

在Swift3中,现在的Date结构Foundation实现了Comparable协议.因此,之前的Swift2 NSDate方法被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
}
Run Code Online (Sandbox Code Playgroud)

注意 ...

在Swift3 Datestruct,它意味着它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`.
Run Code Online (Sandbox Code Playgroud)


Yur*_*din 6

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
    }
}
Run Code Online (Sandbox Code Playgroud)


Sas*_*haZ 6

如果你想在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
 }
}
Run Code Online (Sandbox Code Playgroud)

对于其他日历比较,将.day更改为;

.year .day..hour .minute .second


Tru*_*han 5

Swift已经实现Date比较,只需使用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)
Run Code Online (Sandbox Code Playgroud)