首页 文章

比较没有时间组件的NSDates

提问于
浏览
47

在一个快速的操场上,我一直在使用

NSDate.date()

但是,这总是会附加时间元素 . 对于我的应用程序,我需要忽略时间元素 . 这在Swift中可能吗?怎么做到呢?即使我可以将时间元素设置为每个日期也同时工作 .

此外,我正在尝试比较两个日期,目前我正在使用以下代码:

var earlierDate:NSDate = firstDate.earlierDate(secondDate)

这是唯一的方法,还是可以忽略时间元素的方式?例如,如果他们是同一天,但不同的时间,我不想要结果 .

15 回答

  • 1

    在Swift 4中:

    func compareDate(date1:Date, date2:Date) -> Bool {
        let order = NSCalendar.current.compare(date1, to: date2, toGranularity: .day)
        switch order {
        case .orderedSame:
            return true
        default:
            return false
        }
    }
    
  • 4

    适用于iOS7支持

    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    let date1String = dateFormatter.stringFromDate(date1)
    let date2String = dateFormatter.stringFromDate(date2)
    if date1String == date2String {
        println("Equal date")
    }
    
  • -2

    使用此 Calendar 函数来比较iOS 8.0中的日期

    func compare(_ date1: Date, to date2: Date, toGranularity component: Calendar.Component) -> ComparisonResult
    

    .day 为单位

    使用此功能如下:

    let now = Date()
    // "Sep 23, 2015, 10:26 AM"
    let olderDate = Date(timeIntervalSinceNow: -10000)
    // "Sep 23, 2015, 7:40 AM"
    
    var order = Calendar.current.compare(now, to: olderDate, toGranularity: .hour)
    
    switch order {
    case .orderedDescending:
        print("DESCENDING")
    case .orderedAscending:
        print("ASCENDING")
    case .orderedSame:
        print("SAME")
    }
    
    // Compare to hour: DESCENDING
    
    var order = Calendar.current.compare(now, to: olderDate, toGranularity: .day)
    
    
    switch order {
    case .orderedDescending:
        print("DESCENDING")
    case .orderedAscending:
        print("ASCENDING")
    case .orderedSame:
        print("SAME")
    }
    
    // Compare to day: SAME
    
  • 100

    iOS 8.0中的NSCalendar有几种有用的方法:

    startOfDayForDate, isDateInToday, isDateInYesterday, isDateInTomorrow
    

    甚至比较日子:

    func isDate(date1: NSDate!, inSameDayAsDate date2: NSDate!) -> Bool
    

    要忽略time元素,可以使用:

    var toDay = Calendar.current.startOfDay(for: Date())
    

    但是,如果你还必须支持iOS 7,你总是可以写一个扩展名

    extension NSCalendar {
        func myStartOfDayForDate(date: NSDate!) -> NSDate!
        {
            let systemVersion:NSString = UIDevice.currentDevice().systemVersion
            if systemVersion.floatValue >= 8.0 {
                return self.startOfDayForDate(date)
            } else {
                return self.dateFromComponents(self.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: date))
            }
        }
    }
    
  • 6

    我写了以下方法,通过借用Ashley Mills解决方案来比较两个日期 . 它比较两个日期,如果两个日期相同,则返回true(剥离时间) .

    func compareDate(date1:NSDate, date2:NSDate) -> Bool {
        let order = NSCalendar.currentCalendar().compareDate(date1, toDate: date2,
            toUnitGranularity: .Day)
        switch order {
        case .OrderedSame:
            return true
        default:
            return false
        }
    }
    

    它被称为这样:

    if compareDate(today, date2: anotherDate) {
        // The two dates are on the same day.
    }
    
  • 15

    两个日期在swift中的比较 .

    // Date comparision to compare current date and end date.
        var dateComparisionResult:NSComparisonResult = currentDate.compare(endDate)
    
        if dateComparisionResult == NSComparisonResult.OrderedAscending
        {
            // Current date is smaller than end date.
        }
        else if dateComparisionResult == NSComparisonResult.OrderedDescending
        {
            // Current date is greater than end date.
        }
        else if dateComparisionResult == NSComparisonResult.OrderedSame
        {
            // Current date and end date are same.
        }
    
  • 0

    You can compare two dates using it's description.

    let date1 = NSDate()
    let date2 = NSDate(timeIntervalSinceNow: 120)
    if date1.description == date2.description {
        print(true)
    } else {
        print(false)   // false (I have added 2 seconds between them)
    }
    

    If you want set the time element of your dates to a different time you can do as follow:

    extension NSDate {
        struct Calendar {
            static let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        }
        var day:    Int { return Calendar.gregorian.component(.Day,    fromDate: self)   }
        var month:  Int { return Calendar.gregorian.component(.Month,  fromDate: self)  }
        var year:   Int { return Calendar.gregorian.component(.Year,   fromDate: self)  }
    
        var noon: NSDate {
            return Calendar.gregorian.dateWithEra(1, year: year, month: month, day: day, hour: 12, minute: 0, second: 0, nanosecond: 0)!
        }
    }
    
    let date1 = NSDate()
    let date2 = NSDate(timeIntervalSinceNow: 120)
    print(date1.noon == date2.noon)   // true
    

    or you can also do it using NSDateFormatter:

    extension NSDate {
        struct Date {
            static let formatterYYYYMMDD: NSDateFormatter = {
                let formatter = NSDateFormatter()
                formatter.dateFormat = "yyyyMMdd"
                return formatter
            }()
        }
        var yearMonthDay: String {
            return Date.formatterYYYYMMDD.stringFromDate(self)
        }
        func isSameDayAs(date:NSDate) -> Bool {
            return yearMonthDay == date.yearMonthDay
        }
    }
    
    let date1 = NSDate()
    let date2 = NSDate(timeIntervalSinceNow: 120)
    print(date1.yearMonthDay == date2.yearMonthDay)   // true
    
    print(date1.isSameDayAs(date2))    // true
    

    另一个选项(iOS8)是使用日历方法isDate(inSameDayAsDate :):

    extension NSDate {
        struct Calendar {
            static let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        }
        func isInSameDayAs(date date: NSDate) -> Bool {
            return Calendar.gregorian.isDate(self, inSameDayAsDate: date)
        }
    }
    let date1 = NSDate()
    let date2 = NSDate(timeIntervalSinceNow: 120)
    if date1.isInSameDayAs(date: date2 ){
        print(true)   // true
    } else {
        print(false)
    }
    
  • 4

    For Swift3

    var order = NSCalendar.current.compare(firstDate, to: secondDate, toGranularity: .hour)
    
    if order == .orderedSame {
        //Both the dates are same. 
        //Your Logic.
    }
    
  • 6

    我写了一个Swift 4扩展来比较两个日期:

    import Foundation
    
    extension Date {      
      func isSameDate(_ comparisonDate: Date) -> Bool {
        let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
        return order == .orderedSame
      }
    
      func isBeforeDate(_ comparisonDate: Date) -> Bool {
        let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
        return order == .orderedAscending
      }
    
      func isAfterDate(_ comparisonDate: Date) -> Bool {
        let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
        return order == .orderedDescending
      }
    }
    

    用法:

    startDate.isSameDateAs(endDate) // returns a true or false

  • 2

    迅速:

    extension NSDate {
    
        /**
        Compares current date with the given one down to the seconds.
        If date==nil, then always return false
    
        :param: date date to compare or nil
    
        :returns: true if the dates has equal years, months, days, hours, minutes and seconds.
        */
        func sameDate(date: NSDate?) -> Bool {
            if let d = date {
                let calendar = NSCalendar.currentCalendar()
                if NSComparisonResult.OrderedSame == calendar.compareDate(self, toDate: d, toUnitGranularity: NSCalendarUnit.SecondCalendarUnit) {
                    return true
                }
    
            }
            return false
        }
    }
    
  • -1

    Swift 3

    let order = NSCalendar.current.compare(date1, to: date2, toGranularity: .day)
    
            if order == .orderedAscending { 
              // date 1 is older
            }
            else if order == .orderedDescending { 
              // date 1 is newer
            }
            else if order == .orderedSame { 
              // same day/hour depending on granularity parameter
            }
    
  • 8

    当你在操场上 NSDate.date() 时,你会看到 default description 已打印出来 . 使用 NSDateFormatter 打印日期对象的本地化描述,可能只包含日期部分 .

    要将日期的特定部分清零(为了进行比较),请将 NSDateComponentsNSCalendar 结合使用 .

  • 3

    根据我的经验,大多数人都是正常的感觉(即在当地时区的午夜开始的24个时期) . 在正常(日常/非编程)用法中,2014年1月1日在伦敦的日期与1月1日在北京或纽约的日期相同 even though they cover different periods in real time . 为了达到极限,圣诞岛上的时间是UTC 14,而中途岛上的时间是UTC-11 . 所以2014年1月1日在这两个岛上是相同的日期,即使一个人甚至没有开始,直到另一个完成了一个小时 .

    如果那是您正在录制的日期(如果您没有录制时间组件,则可能是),则不要使用NSDate(仅存储2001-01-01 00:00 UTC之后的秒数,没有其他内容)但是将年月和日存储为整数 - 也许通过创建包含这些值的CivilDate类 - 并使用它来代替 .

    仅进入NSDate以比较日期,然后确保在两个NSDates上明确声明时区为“UTC”以进行比较 .

  • 1

    Swift iOS 8 and up 当您需要的不仅仅是更大或更小的日期比较时 . 例如,它是在同一天或前一天,......

    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)
            }
        }
    

    有关如何在过滤器中使用此示例,请参阅以下答案:

    https://stackoverflow.com/a/45746206/4946476

  • 0

    回答你的问题:

    这在Swift中可行吗?

    对的,这是可能的


    啊,你现在也想要

    let cal = NSCalendar.currentCalendar()
    cal.rangeOfUnit(.DayCalendarUnit, startDate: &d1, interval: nil, forDate: d1) // d1 NSDate?
    cal.rangeOfUnit(.DayCalendarUnit, startDate: &d2, interval: nil, forDate: d2) // d2 NSDate?
    

    现在d1和d2将包含他们日期开始的日期 .

    d1!.compare(d2!) 比较

    为了显示它们没有时间部分,我们使用NSDateFormatter .

相关问题