दो NSDates की तुलना कैसे करें: हाल ही में कौन सा है?


244

मैं एक ड्रॉपबॉक्स सिंक हासिल करने की कोशिश कर रहा हूं और दो फाइलों की तारीखों की तुलना करने की जरूरत है। एक मेरे ड्रॉपबॉक्स खाते पर है और एक मेरे iPhone पर है।

मैं निम्नलिखित के साथ आया था, लेकिन मुझे अप्रत्याशित परिणाम मिले। मुझे लगता है कि दो तारीखों की तुलना करते समय मैं मौलिक रूप से कुछ गलत कर रहा हूं। मैंने बस> <ऑपरेटरों का इस्तेमाल किया, लेकिन मुझे लगता है कि यह अच्छा नहीं है क्योंकि मैं दो एनएसडी के तार की तुलना कर रहा हूं। ये रहा:

NSLog(@"dB...lastModified: %@", dbObject.lastModifiedDate); 
NSLog(@"iP...lastModified: %@", [self getDateOfLocalFile:@"NoteBook.txt"]);

if ([dbObject lastModifiedDate] < [self getDateOfLocalFile:@"NoteBook.txt"]) {
    NSLog(@"...db is more up-to-date. Download in progress...");
    [self DBdownload:@"NoteBook.txt"];
    NSLog(@"Download complete.");
} else {
    NSLog(@"...iP is more up-to-date. Upload in progress...");
    [self DBupload:@"NoteBook.txt"];
    NSLog(@"Upload complete.");
}

इसने मुझे निम्न (यादृच्छिक और गलत) आउटपुट दिया:

2011-05-11 14:20:54.413 NotePage[6918:207] dB...lastModified: 2011-05-11 13:18:25 +0000
2011-05-11 14:20:54.414 NotePage[6918:207] iP...lastModified: 2011-05-11 13:20:48 +0000
2011-05-11 14:20:54.415 NotePage[6918:207] ...db is more up-to-date.

या यह जो सही होता है:

2011-05-11 14:20:25.097 NotePage[6903:207] dB...lastModified: 2011-05-11 13:18:25 +0000
2011-05-11 14:20:25.098 NotePage[6903:207] iP...lastModified: 2011-05-11 13:19:45 +0000
2011-05-11 14:20:25.099 NotePage[6903:207] ...iP is more up-to-date.

11
डुप्लिकेट: 1 2 3 4 5 6 और सी।
jscs

1
@JoshCaswell अगर यह एक वास्तविक डुप्लिकेट है, तो उन्हें मर्ज क्यों नहीं किया जाता है? आप इसे पहले कर चुके हैं ...
दान रोसेनस्टार्क

1
केवल हीरा मध्यस्थ ही मर्ज कर सकते हैं, @ यार।
jscs

जवाबों:


658

मान लेते हैं दो तारीखें:

NSDate *date1;
NSDate *date2;

फिर निम्नलिखित तुलना बताएगी जो पहले / बाद में / समान है:

if ([date1 compare:date2] == NSOrderedDescending) {
    NSLog(@"date1 is later than date2");
} else if ([date1 compare:date2] == NSOrderedAscending) {
    NSLog(@"date1 is earlier than date2");
} else {
    NSLog(@"dates are the same");
}

अधिक जानकारी के लिए कृपया NSDate वर्ग के दस्तावेज़ देखें।


लवली! बीट्स के साथ खिलवाड़ करने के बारे में [तारीख 1 तारीख: तारीख 2] आदि ... धन्यवाद - किसी कारण के लिए मैंने तुलना का उपयोग करने के बारे में कभी नहीं सोचा होगा: पहले।
सोमामन

11
मैं इस तथ्य पर भरोसा करना पसंद करता हूं कि NSOrderedAscending <0 और NSOrderedDescending> 0., जो पढ़ने की तुलना को आसान बनाता है: [date1 तुलना: date2] <0 / * date1 <date2 * / और (बनाने में आसान) गलती @albertamg से बचा जाता है बताया। ;-)
jpap

वैसे - तुलना विधि ऑफ-द-वन त्रुटियों के रूप में त्रुटि-प्रवण है। इस प्रकार, आपको (NSDate *) laterDate का उपयोग करना चाहिए: (NSDate *) एक और डीटेट जो दोनों की बाद की तारीख को लौटाएगा। तो आप बस अपने अपेक्षित परिणाम की तुलना करें और आपका काम हो गया! "वाइट उतरते / चढ़ते हुए?"
मासी

@ जपप ने मुझे भी गड़बड़ कर दिया; ऐसा लगता है कि Apple चाहता है कि आप उस परिणाम के बारे में सोचें जो date1 -> date2आरोही / अवरोही है (और इसलिए date1 बाद में या बाद में क्रमशः है)।
जेक

@ जेक मैजिक नंबर (-1,0,1) के बिना एल्गोरिदम को क्रम में रखने के लिए एल्गोरिदम को क्रमबद्ध करने के लिए यह अधिक सार तरीका है। आप एक अधिक पठनीय नाम के साथ उन स्थिरांक को फिर से परिभाषित कर सकते हैं। मेरा जवाब काम कर रहा है लेकिन पठनीय कोड का पुरस्कार विजेता नहीं है। नीचे स्क्रॉल करें, अन्य अच्छे हैं।
निक वीवर

50

पार्टी में देर से, लेकिन NSDate वस्तुओं की तुलना करने का एक और आसान तरीका उन्हें आदिम प्रकारों में बदलना है जो '>' '<' '==' आदि का आसान उपयोग करने की अनुमति देता है।

जैसे।

if ([dateA timeIntervalSinceReferenceDate] > [dateB timeIntervalSinceReferenceDate]) {
    //do stuff
}

timeIntervalSinceReferenceDateसंदर्भ तिथि (1 जनवरी 2001, GMT) के बाद से तारीखों को सेकंड में परिवर्तित करता है। timeIntervalSinceReferenceDateरिटर्न के रूप में एक NSTimeInterval (जो एक डबल टाइपडिफ़ है), हम आदिम तुलनात्मक का उपयोग कर सकते हैं।


4
(NSComparisonResult)compare:(NSDate *)इस सरल ऑपरेशन की तुलना में थोड़ा अधिक सहज लेकिन अभी भी काफी क्रियात्मक ... (हमेशा की तरह)
पियरे डे लेसिन

1
भी कर सकते हैं[dateA timeIntervalSinceDate:dateB] > 0
स्कॉट फिस्टर

14

स्विफ्ट में, आप मौजूदा ऑपरेटरों को अधिभारित कर सकते हैं:

func > (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.timeIntervalSinceReferenceDate > rhs.timeIntervalSinceReferenceDate
}

func < (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.timeIntervalSinceReferenceDate < rhs.timeIntervalSinceReferenceDate
}

उसके बाद, आप के साथ सीधे NSDates तुलना कर सकते हैं <, >और ==(पहले से ही समर्थित)।


यदि मैं इसमें से एक विस्तार करने की कोशिश करता हूं, तो मुझे "ऑपरेटर केवल वैश्विक दायरे में अनुमति दी जाती है", सुझाव?
JohnVanDijk

@JohnVanDijk आप इसे एक्सटेंशन के अंदर नहीं डाल सकते। मैं इसे विस्तार के रूप में एक ही फाइल में डाल चाहते हैं, लेकिन बाहर{ ... }
एंड्रयू

13

NSDate एक तुलना समारोह है।

compare:एक NSComparisonResultमान लौटाता है जो रिसीवर और दूसरी दी गई तारीख के अस्थायी आदेश को इंगित करता है।

(NSComparisonResult)compare:(NSDate *)anotherDate

पैरामीटर : anotherDate वह तारीख जिसके साथ रिसीवर की तुलना करनी है। यह मान शून्य नहीं होना चाहिए। यदि मान शून्य है, तो व्यवहार अपरिभाषित है और मैक ओएस एक्स के भविष्य के संस्करणों में बदल सकता है।

प्रतिलाभ की मात्रा:

  • यदि रिसीवर और अन्यडेट एक दूसरे के बराबर हैं, NSOrderedSame
  • यदि रिसीवर बाद में किसी अन्य दिनांक की तुलना में, NSOrderedDescending
  • यदि रिसीवर किसी अन्य डेट से पहले के समय में है NSOrderedAscending

@ आईएनआरई दो एनएसडी वस्तुओं की तुलना करने का एक तरीका है जिसमें केवल समय घटक अलग है? किसी कारण से उपरोक्त विधि काम नहीं करती है।
The uSeFuL

12

आप NSDate तुलना का उपयोग करना चाहते हैं :, laterDate :, इससे पहले के संस्करण :, या isEqualToDate: विधियाँ। इस स्थिति में <और> ऑपरेटरों का उपयोग पॉइंटर्स की तुलना कर रहा है, तिथियों की नहीं


11
- (NSDate *)earlierDate:(NSDate *)anotherDate

यह रिसीवर और पहले के अन्य डेट को लौटाता है। यदि दोनों समान हैं, तो रिसीवर लौटा दिया जाता है।


1
ध्यान दें कि NSDates का बैकिंग ऑब्जेक्ट आपके संकलित कोड के 64-बिट संस्करणों पर अनुकूलित किया जा सकता है, जैसे कि दिनांक जो उसी समय का प्रतिनिधित्व करते हैं, उसी पते पर होगा। इस प्रकार यदि cDate = [aDate earlierDate:bDate]तब cDate == aDateऔर cDate == bDateदोनों सत्य हो सकते हैं। पाया यह iOS 8 पर कुछ तारीख काम कर रहा है
बेन फ्लिन

1
इसके विपरीत, 32 बिट प्लेटफार्मों पर, यदि तिथियां समान नहीं हैं, -earlierDate:(और -laterDate:) न तो रिसीवर और न ही तर्क वापस कर सकते हैं।
बेन फीज

7

कुछ तारीख उपयोगिताएँ, जिसमें अंग्रेजी में तुलना शामिल है, जो अच्छी है:

#import <Foundation/Foundation.h>


@interface NSDate (Util)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
- (NSDate*) dateByAddingDays:(int)days;

@end

कार्यान्वयन:

#import "NSDate+Util.h"


@implementation NSDate (Util)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedAscending);
}

-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedDescending);

}
-(BOOL) isEarlierThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedAscending);
}

- (NSDate *) dateByAddingDays:(int)days {
    NSDate *retVal;
    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setDay:days];

    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    retVal = [gregorian dateByAddingComponents:components toDate:self options:0];
    return retVal;
}

@end

1
या सिर्फ उपयोग करें: github.com/erica/NSDate-Extensions
Dan Rosenstark


6

आपको उपयोग करना चाहिए :

- (NSComparisonResult)compare:(NSDate *)anotherDate

तारीखों की तुलना करने के लिए। उद्देश्य सी में कोई ऑपरेटर ओवरलोडिंग नहीं है।


6

आप लोग इन NSDateतुलना विधियों का उपयोग क्यों नहीं करते हैं :

- (NSDate *)earlierDate:(NSDate *)anotherDate;
- (NSDate *)laterDate:(NSDate *)anotherDate;

4

मेरी लगभग समान स्थिति है, लेकिन मेरे मामले में मैं जाँच कर रहा हूं कि क्या संख्या में अंतर है

NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *compDate = [cal components:NSDayCalendarUnit fromDate:fDate toDate:tDate options:0];
int numbersOfDaysDiff = [compDate day]+1; // do what ever comparison logic with this int.

उपयोगी जब आपको NSDate की तुलना डेज / मंथली / ईयर यूनिट में करने की आवश्यकता हो


NSDayCalendarUnit को पदावनत किया जाता है, इसलिए इसके बजाय NSCalendarUnitDay का उपयोग करें
Mazen Kasser

2

आप इस विधि से भी दो तारीखों की तुलना कर सकते हैं

        switch ([currenttimestr  compare:endtimestr])
        {
            case NSOrderedAscending:

                // dateOne is earlier in time than dateTwo
                break;

            case NSOrderedSame:

                // The dates are the same
                break;
            case NSOrderedDescending:

                // dateOne is later in time than dateTwo


                break;

        }

0

मैंने यह कोशिश की है कि यह आपके लिए काम करे

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];      
int unitFlags =NSDayCalendarUnit;      
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];     
NSDate *myDate; //= [[NSDate alloc] init];     
[dateFormatter setDateFormat:@"dd-MM-yyyy"];   
myDate = [dateFormatter dateFromString:self.strPrevioisDate];     
NSDateComponents *comps = [gregorian components:unitFlags fromDate:myDate toDate:[NSDate date] options:0];   
NSInteger day=[comps day];

0

दिनांक तुलना के लिए इस सरल फ़ंक्शन का उपयोग करें

-(BOOL)dateComparision:(NSDate*)date1 andDate2:(NSDate*)date2{

BOOL isTokonValid;

if ([date1 compare:date2] == NSOrderedDescending) {
    NSLog(@"date1 is later than date2");
    isTokonValid = YES;
} else if ([date1 compare:date2] == NSOrderedAscending) {
    NSLog(@"date1 is earlier than date2");
    isTokonValid = NO;
} else {
    isTokonValid = NO;
    NSLog(@"dates are the same");
}

return isTokonValid;}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.