webentwicklung-frage-antwort-db.com.de

Wie kann man feststellen, ob heute ein NSDate ist?

Wie prüfe ich, ob heute ein NSDate gehört?

Ich habe es mit den ersten 10 Zeichen aus [aDate description] überprüft. [[aDate description] substringToIndex:10] gibt eine Zeichenfolge wie "YYYY-MM-DD" zurück, daher habe ich die Zeichenfolge mit der von [[[NSDate date] description] substringToIndex:10] zurückgegebenen Zeichenfolge verglichen.

Gibt es einen schnelleren und/oder ordentlicheren Weg zum Überprüfen?

Vielen Dank.

145
Seunghoon

In macOS 10.9+ und iOS 8+ gibt es eine Methode in NSCalendar/Calendar, die genau dies tut!

- (BOOL)isDateInToday:(NSDate *)date 

Du würdest es einfach tun

Ziel c:

BOOL today = [[NSCalendar currentCalendar] isDateInToday:date];

Swift 3:

let today = Calendar.current.isDateInToday(date)
291
Catfish_Man

Sie können Datumskomponenten vergleichen:

NSDateComponents *otherDay = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:aDate];
NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]];
if([today day] == [otherDay day] &&
   [today month] == [otherDay month] &&
   [today year] == [otherDay year] &&
   [today era] == [otherDay era]) {
    //do stuff
}

Bearbeiten:

Ich mag die Methode von stefan mehr, ich denke, es macht eine sauberere und verständlichere Aussage:

NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]];
NSDate *today = [cal dateFromComponents:components];
components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:aDate];
NSDate *otherDate = [cal dateFromComponents:components];

if([today isEqualToDate:otherDate]) {
    //do stuff
}

Chris, ich habe deinen Vorschlag aufgenommen. Ich musste nachsehen, was die Ära war, und für alle anderen, die es nicht wissen, unterscheidet es zwischen BC und AD. Dies ist wahrscheinlich für die meisten Leute nicht notwendig, aber es ist leicht zu überprüfen und gibt Gewissheit, daher habe ich es hinzugefügt. Wenn Sie auf Geschwindigkeit setzen, ist dies wahrscheinlich ohnehin keine gute Methode.


NOTEWie bei vielen Antworten zu SO, ist dies nach 7 Jahren völlig veraltet. In Swift benutze jetzt einfach .isDateInToday

192
David Kanarek

Dies ist ein Ableger Ihrer Frage, aber wenn Sie ein NSDate mit "Heute" oder "Gestern" drucken möchten, verwenden Sie die Funktion

- (void)setDoesRelativeDateFormatting:(BOOL)b

für NSDateFormatter

27
Jon

Ich würde versuchen, das heutige Datum auf Mitternacht und das zweite Datum zu normalisieren, auf Mitternacht zu normalisieren und dann zu vergleichen, ob es sich um dasselbe NSDate handelt.

Von einem Apple-Beispiel So normalisieren Sie das heutige Datum um Mitternacht, machen Sie dasselbe für das zweite Datum und vergleichen Sie es:

NSCalendar * gregorian = [[NSCalendar alloc]
                               initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents * components =
    [gregorian components:
                 (NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit)
                 fromDate:[NSDate date]];
NSDate * today = [gregorian dateFromComponents:components];
16
stefanB

Working Swift 3 & 4 extension des Vorschlags von Catfish_Man:

extension Date {

    func isToday() -> Bool {
        return Calendar.current.isDateInToday(self)
    }

}
13
Benno Kress

Keine Notwendigkeit, mit Komponenten, Epochen und Sachen zu jonglieren. 

NSCalendar bietet eine Methode, um den Beginn einer bestimmten Zeiteinheit für ein vorhandenes Datum abzurufen.

Dieser Code wird den Beginn des heutigen Tages und ein anderes Datum enthalten und das vergleichen. Wenn sie als NSOrderedSame ausgewertet wird, befinden sich beide Daten am selben Tag - also heute.

NSDate *today = nil;
NSDate *beginningOfOtherDate = nil;

NSDate *now = [NSDate date];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&today interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfOtherDate interval:NULL forDate:beginningOfOtherDate];

if([today compare:beginningOfOtherDate] == NSOrderedSame) {
    //otherDate is a date in the current day
}
12
vikingosegundo
extension NSDate {
  func isToday() -> Bool {
    let cal = NSCalendar.currentCalendar()
    var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
    let today = cal.dateFromComponents(components)!

    components = cal.components([.Era, .Year, .Month, .Day], fromDate:self)
    let otherDate = cal.dateFromComponents(components)!

    return today.isEqualToDate(otherDate)
}

Arbeitete für mich an Swift 2.0

8
Omar Albeik

Schnelle Version der besten Antwort:

let cal = NSCalendar.currentCalendar()
var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
let today = cal.dateFromComponents(components)!

components = cal.components([.Era, .Year, .Month, .Day], fromDate:aDate);
let otherDate = cal.dateFromComponents(components)!

if(today.isEqualToDate(otherDate)) {
    //do stuff
}
6
Vojtech Vrbka

Sie können auch das Zeitintervall zwischen Ihrem Datum und dem aktuellen Datum überprüfen:

[myDate timeIntervalSinceNow]

Dadurch wird das Zeitintervall (in Sekunden) zwischen myDate und dem aktuellen Datum/der aktuellen Uhrzeit angezeigt.

Verknüpfung .

Edit: Hinweis an alle: Mir ist bekannt, dass [myDate timeIntervalSinceNow] nicht eindeutig bestimmt, ob myDate heute ist.

Ich lasse diese Antwort so, dass, wenn jemand nach etwas Ähnlichem sucht und [myDate timeIntervalSinceNow] nützlich ist, sie es hier finden können.

5
alesplin

Weitere Informationen finden Sie in der Dokumentation von Apple unter "Durchführen von Kalenderberechnungen" [Link] .

Listing 13 dieser Seite legt nahe, dass Sie zur Ermittlung der Mitternacht zwischen den Tagen Folgendes verwenden:

- (NSInteger)midnightsFromDate:(NSDate *)startDate toDate:(NSDate *)endDate
{
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSInteger startDay = [calendar ordinalityOfUnit:NSDayCalendarUnit
                                             inUnit:NSEraCalendarUnit
                                            forDate:startDate];
    NSInteger endDay = [calendar ordinalityOfUnit:NSDayCalendarUnit
                                           inUnit:NSEraCalendarUnit
                                          forDate:endDate];
    return endDay - startDay;
}

Sie können dann feststellen, ob zwei Tage gleich sind, indem Sie diese Methode verwenden und sehen, ob sie 0 zurückgibt oder nicht.

5
ArtOfWarfare

Swift Extension basierend auf den besten Antworten:

extension NSDate {
    func isToday() -> Bool {
        let cal = NSCalendar.currentCalendar()
        if cal.respondsToSelector("isDateInToday:") {
            return cal.isDateInToday(self)
        }
        var components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:NSDate())
        let today = cal.dateFromComponents(components)!

        components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:self);
        let otherDate = cal.dateFromComponents(components)!
        return today.isEqualToDate(otherDate)
    }
}
4
ZiggyST

Es gibt einen einfacheren Weg als viele der oben genannten Antworten! 

NSDate *date = ... // The date you wish to test
NSCalendar *calendar = [NSCalendar currentCalendar];

if([calendar isDateInToday:date]) {
    //do stuff
}
2
aryland

Wenn Sie viele dieser Datumsvergleiche haben, nehmen die Aufrufe von calendar:components:fromDate viel Zeit in Anspruch. Nach einigen Profilierungen, die ich gemacht habe, scheinen sie recht teuer zu sein.

Angenommen, Sie versuchen zu ermitteln, welche Daten aus einem bestimmten Bereich von Datumsangaben stammen, beispielsweise NSArray *datesToCompare, die am selben Tag wie ein bestimmter Tag liegen, beispielsweise NSDate *baseDate. Dann können Sie Folgendes verwenden (teilweise aus einer Antwort oben)

NSDate *baseDate = [NSDate date];

NSArray *datesToCompare = [NSArray arrayWithObjects:[NSDate date], 
                           [NSDate dateWithTimeIntervalSinceNow:100],
                           [NSDate dateWithTimeIntervalSinceNow:1000],
                           [NSDate dateWithTimeIntervalSinceNow:-10000],
                           [NSDate dateWithTimeIntervalSinceNow:100000],
                           [NSDate dateWithTimeIntervalSinceNow:1000000],
                           [NSDate dateWithTimeIntervalSinceNow:50],
                           nil];

// determine the NSDate for midnight of the base date:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) 
                                       fromDate:baseDate];
NSDate* theMidnightHour = [calendar dateFromComponents:comps];

// set up a localized date formatter so we can see the answers are right!
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];

// determine which dates in an array are on the same day as the base date:
for (NSDate *date in datesToCompare) {
    NSTimeInterval interval = [date timeIntervalSinceDate:theMidnightHour];
    if (interval >= 0 && interval < 60*60*24) {
        NSLog(@"%@ is on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]);
    }
    else {
        NSLog(@"%@ is NOT on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]);
    }
}

Ausgabe:

Nov 23, 2011 1:32:00 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:33:40 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:48:40 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 10:45:20 AM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 24, 2011 5:18:40 PM is NOT on the same day as Nov 23, 2011 1:32:00 PM
Dec 5, 2011 3:18:40 AM is NOT on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:32:50 PM is on the same day as Nov 23, 2011 1:32:00 PM
2

für iOS7 und früher:

//this is now => need that for the current date
NSDate * now = [NSDate date];

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];

NSDateComponents * components = [calendar components:( NSYearCalendarUnit|    NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate: now];

[components setMinute:0];
[components setHour:0];
[components setSecond:0];

//this is Today's Midnight
NSDate *todaysMidnight = [calendar dateFromComponents: components];



//now timeIntervals since Midnight => in seconds
NSTimeInterval todayTimeInterval = [now timeIntervalSinceDate: todaysMidnight];

//now timeIntervals since OtherDate => in seconds
NSTimeInterval otherDateTimeInterval = [now timeIntervalSinceDate: otherDate];

if(otherDateTimeInterval > todayTimeInterval) //otherDate is not in today
{
    if((otherDateTimeInterval - todayTimeInterval) <= 86400) //86400 == a day total seconds
    {
        @"yesterday";
    }
    else
    {
        @"earlier";
    }
}
else
{
    @"today";
}


now = nil;
calendar = nil;
components = nil;
todaysMidnight = nil;

NSLog("Thank you :-)");
0
user3744424

Dies könnte wahrscheinlich als NSDate-Kategorie überarbeitet werden, aber ich habe verwendet:

// Seconds per day (24h * 60m * 60s)
#define kSecondsPerDay 86400.0f

+ (BOOL) dateIsToday:(NSDate*)dateToCheck
{
    // Split today into components
    NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents* comps = [gregorian components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit) 
                                        fromDate:[NSDate date]];

    // Set to this morning 00:00:00
    [comps setHour:0];
    [comps setMinute:0];
    [comps setSecond:0];
    NSDate* theMidnightHour = [gregorian dateFromComponents:comps];
    [gregorian release];

    // Get time difference (in seconds) between date and then
    NSTimeInterval diff = [dateToCheck timeIntervalSinceDate:theMidnightHour];
    return ( diff>=0.0f && diff<kSecondsPerDay );
}

(Der Vergleich der beiden Datumsfolgen wie in der ursprünglichen Frage fühlt sich jedoch "sauberer" an.) 

0
LeoN

Überprüfen Sie unseren Erica Sadun NSDate extension. Sehr einfach zu bedienen Fein hier es:

http://github.com/erica/NSDate-Extensions

Es ist bereits in diesem Beitrag vorhanden: https://stackoverflow.com/a/4052798/362310

0
Vaibhav Saran

Die richtige und sichere Lösung ohne Zwangstrennung, die unter Swift 2.2 und vor iOS 8 funktioniert

func isToday() -> Bool {
    let calendar = NSCalendar.currentCalendar()
    if #available(iOS 8.0, *) {
        return calendar.isDateInToday(self)
    }

    let todayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
    let dayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:self)

    guard let today = calendar.dateFromComponents(todayComponents),
        day = calendar.dateFromComponents(dayComponents) else {
        return false
    }

    return today.compare(day) == .OrderedSame
}
0
fpg1503