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.
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
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))
}
}
}
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.
}
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
}
}
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.
}
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)
}
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")
}
pour Swift
var order = NSCalendar.current.compare(firstDate, to: secondDate, toGranularity: .hour)
if order == .orderedSame {
//Both the dates are same.
//Your Logic.
}
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
}
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
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
}
}
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
}
}
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.
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
.