web-dev-qa-db-fra.com

Comparer les dates NSD sans composante horaire

Dans un Swift terrain de jeu, j’utilise

NSDate.date() 

Mais, cela apparaît toujours avec l'élément time ajouté. Pour mon application, je dois ignorer l'élément de temps. Est-ce possible à Swift? Comment ceci peut être fait? Même si je pouvais définir l’heure comme étant la même heure à chaque date qui fonctionnerait aussi.

De plus, j'essaie de comparer deux dates et pour le moment, j'utilise le code suivant:

var earlierDate:NSDate = firstDate.earlierDate(secondDate)

Est-ce le seul moyen ou puis-je le faire d'une manière qui ignore l'élément temporel? Par exemple, je ne veux pas de résultat s'ils sont le même jour, mais à des moments différents.

52
agf119105

Utilisez cette fonction Calendar pour comparer les dates dans iOS 8.0+

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


qui passe .day comme unité

Utilisez cette fonction comme suit:

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
109
Ashley Mills

Il existe plusieurs méthodes utiles dans NSCalendar dans iOS 8.0+:

startOfDayForDate, isDateInToday, isDateInYesterday, isDateInTomorrow

Et même pour comparer les jours:

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

Pour ignorer l'élément time, vous pouvez utiliser ceci:

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

Mais si vous devez également supporter iOS 7, vous pouvez toujours écrire une extension.

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

J'ai écrit la méthode suivante pour comparer deux dates en empruntant la solution Ashley Mills. Il compare deux dates et renvoie true si les deux dates sont identiques (sans le temps).

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

Et ça s'appelle comme ça:

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

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

Comparaison de deux dates dans 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.
    }
6
abhi

Vous pouvez comparer deux dates en utilisant sa 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)
}

Si vous souhaitez définir l’heure de vos dates sur une heure différente, procédez comme suit:

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

ou vous pouvez aussi le faire en utilisant 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

Une autre option (iOS8 +) consiste à utiliser la méthode du calendrier 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
Leo Dabus

Pour le support 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")
}
4
Loganathan

pour Swift

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

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

Swift

        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
        }
2
Maciek z Wrocławia

J'ai écrit une extension Swift 4 pour comparer deux dates:

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

Usage:

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

2
Adrian

Rapide:

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
Alexander Volkov

Swift 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
    }
}
0
Asad Jamil

D'après mon expérience, les problèmes rencontrés par la plupart des gens lors de l'utilisation de NSDate proviennent de l'hypothèse erronée selon laquelle un NSDate peut être utilisé pour représenter une date dans le sens "normal" (c'est-à-dire une période de 24 heures commençant à minuit dans le fuseau horaire local). En utilisation normale (tous les jours/sans programmation), le 1er janvier 2014 à Londres est la même date que le 1er janvier à Beijing ou à New York même s'ils couvrent des périodes différentes en temps réel. À l'extrême, l'heure sur l'île Christmas est l'heure UTC + 14, tandis que l'heure sur l'île Midway est l'heure UTC-11. Donc, le 1er janvier 2014 sur ces deux îles a la même date, même si l’une ne commence pas avant que l’autre ne soit complétée depuis une heure.

Si c'est le genre de date que vous enregistrez (et si vous n'enregistrez pas le composant heure, ce l'est probablement), n'utilisez pas NSDate (qui stocke uniquement les secondes après 2001-01-01 00:00 UTC, rien d'autre) mais stockez l'année mois et le jour sous forme d'entiers - peut-être en créant votre propre classe CivilDate qui englobe ces valeurs - et utilisez-la à la place.

Plongez uniquement dans NSDate pour comparer les dates, puis assurez-vous de déclarer explicitement le fuseau horaire en tant que "UTC" sur les deux NSDates à des fins de comparaison.

0
Vince O'Sullivan

Lorsque vous NSDate.date() dans la cour de récréation, le description par défaut est imprimé. Utilisez NSDateFormatter pour imprimer une description localisée de l’objet date, éventuellement avec uniquement la partie date.

Pour mettre à zéro des parties spécifiques d'une date (à des fins de comparaison), utilisez NSDateComponents conjointement avec NSCalendar.

0
Leo Natan