比较没有时间组件的NSDates

时间:2014-07-04 15:06:51

标签: ios time swift nsdate foundation

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

NSDate.date() 

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

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

var earlierDate:NSDate = firstDate.earlierDate(secondDate)

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

18 个答案:

答案 0 :(得分:105)

使用此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

答案 1 :(得分:16)

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

startOfDayForDate, isDateInToday, isDateInYesterday, isDateInTomorrow

甚至比较日子:

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

要忽略时间元素,您可以使用它:

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

答案 2 :(得分:8)

我写了以下方法,通过借用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.
}

答案 3 :(得分:6)

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

答案 4 :(得分:6)

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

答案 5 :(得分:4)

Xcode 11.2.1,Swift 5及更高版本

检查日期是否具有同一天部分。

Calendar.current.isDate(date1, equalTo: date2, toGranularity: .day)

根据需要调整粒度。

答案 6 :(得分: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")
}

答案 7 :(得分:4)

您可以使用它的描述比较两个日期。

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

如果您想将日期的时间元素设置为不同的时间,您可以执行以下操作:

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

或者你也可以使用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)
}

答案 8 :(得分:3)

适用于Swift3

var order = NSCalendar.current.compare(firstDate, to: secondDate, toGranularity: .hour)

if order == .orderedSame {
    //Both the dates are same. 
    //Your Logic.
}

答案 9 :(得分:2)

我写了一个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

答案 10 :(得分:1)

夫特:

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

答案 11 :(得分: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
        }

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

雨燕4

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

答案 14 :(得分:0)

根据我的经验,大多数人使用NSDate的问题来自于错误的假设,即NSDate可用于表示“正常”意义上的日期(即从当地时区午夜开始的24个时段)。在正常(日常/非编程)使用中,2014年1月1日在伦敦的日期与1月1日在北京或纽约的日期相同,即使它们实时涵盖不同时期。为了达到极限,圣诞岛上的时间是UTC + 14,而中途岛上的时间是UTC-11。因此,2014年1月1日在这两个岛上的日期是相同的日期,即使一个岛屿在另一个岛屿完工一小时之前甚至没有开始。

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

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

答案 15 :(得分:-1)

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

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

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

答案 16 :(得分:-1)

如果您只需要比较日期是否与其他日期在同一天,请使用以下命令:

Calendar.current.isDate(date1, inSameDayAs: date2)

答案 17 :(得分:-2)

回答你的问题:

  

这可以在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。