iOS: Bandingkan dua tanggal

96

Saya memiliki NSDateyang harus saya bandingkan dengan dua tanggal lainnya NSDatedan saya coba dengan NSOrderAscendingdan NSOrderDescendingtetapi jika tanggal saya sama pada dua tanggal lainnya?

Contoh: jika saya memiliki a myDate = 24/05/2011 dan dua lainnya yaitu satu = 24/05/2011dan dua 24/05/2011apa yang dapat saya gunakan?

bersepedaIsBetter
sumber
1
Saya tidak sepenuhnya memahami pertanyaan Anda, apa yang ingin Anda capai?
arclight
tanggal satu dan tanggal dua bisa menjadi satu = 15/05/2011 dan dua = 31/05/2011 tetapi mereka juga harus pada hari yang sama satu = 24/05/2011 dan dua = 24/05/2011 maka saya harus memeriksa apakah myData adalah antara tanggal satu dan tanggal dua
cyclingIsBetter
Ekstrak saja tahun, bulan, dan tanggal, lalu bandingkan dalam urutan itu. Jika ada seri maka bandingkan bidang berikutnya.
Himadri Choudhury

Jawaban:

210

Menurut dokumentasi AppleNSDate compare:

Mengembalikan nilai NSComparisonResult yang menunjukkan urutan sementara penerima dan tanggal tertentu lainnya.

- (NSComparisonResult)compare:(NSDate *)anotherDate

Parameter anotherDate

Tanggal untuk membandingkan penerima. Nilai ini tidak boleh nol. Jika nilainya nihil, perilaku tidak ditentukan dan dapat berubah di versi mendatang dari Mac OS X.

Nilai Kembali

Jika:

Receiver dan anotherDate sama persis satu sama lain, NSOrderedSame

Penerima lebih lambat dari tanggal lain, NSOrderedDescending

Penerima lebih awal dari pada tanggal lain, NSOrderedAscending

Dengan kata lain:

if ([date1 compare:date2] == NSOrderedSame) ...

Perhatikan bahwa mungkin lebih mudah dalam kasus khusus Anda untuk membaca dan menulis ini:

if ([date2 isEqualToDate:date2]) ...

Lihat Dokumentasi Apple tentang yang satu ini .

Vincent Guerci
sumber
tetapi f ([date1 bandingkan: date2] == NSOrderedSame) periksa juga jam menit dan detik dan saya tidak menginginkannya
cyclingIsBetter
1
pertanyaan Anda agak tidak jelas maaf, lihat stackoverflow.com/questions/1889164/3092009#3092009 , Anda akan menemukan jawabannya.
Vincent Guerci
Jawaban ini benar dalam dua hal. Untuk mengontrol komponen tanggal yang Anda bandingkan gunakanNSDateComponents
Nazir
32

Setelah banyak mencari stackoverflow dan web, saya harus menyimpulkan bahwa cara terbaik untuk melakukannya adalah seperti ini:

- (BOOL)isEndDateIsSmallerThanCurrent:(NSDate *)checkEndDate
{
    NSDate* enddate = checkEndDate;
    NSDate* currentdate = [NSDate date];
    NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
    double secondsInMinute = 60;
    NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;

    if (secondsBetweenDates == 0)
        return YES;
    else if (secondsBetweenDates < 0)
        return YES;
    else
        return NO;
}

Anda juga dapat mengubahnya menjadi perbedaan antar jam.

Nikmati!


Edit 1

Jika Anda ingin membandingkan tanggal dengan format hh / MM / tttt saja, Anda perlu menambahkan baris di bawah ini antara NSDate* currentdate = [NSDate date];&&NSTimeInterval distance

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd/MM/yyyy"];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]
                          autorelease]];

NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];

currentdate = [dateFormatter dateFromString:stringDate];
Yossi Tsafar
sumber
1
Terima kasih ini bekerja lebih baik daripada membandingkan atau isEqualToDate
ArdenDev
Sepakat. Saya menemukan masalah dalam menggunakan bandingkan & isEqualToDate. Tentu, ini mungkin tambahan 2 baris kode, tetapi lebih dapat diandalkan.
Pelatih Roebuck
23

Saya anggap Anda bertanya apa nilai kembaliannya dalam fungsi perbandingan.

Jika tanggalnya sama maka kembali NSOrderedSame

Jika ascending (2nd arg> 1st arg) return NSOrderedAscending

Jika descending (2nd arg <1st arg) kembali NSOrderedDescending

Himadri Choudhury
sumber
Cara yang baik untuk memikirkan naik dan turun.
David
16

Saya tidak tahu persis apakah Anda menanyakan hal ini, tetapi jika Anda hanya ingin membandingkan komponen tanggal NSDate, Anda harus menggunakan NSCalendar dan NSDateComponents untuk menghapus komponen waktu.

Sesuatu seperti ini seharusnya berfungsi sebagai kategori untuk NSDate:

- (NSComparisonResult)compareDateOnly:(NSDate *)otherDate {
    NSUInteger dateFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit;
    NSCalendar *gregorianCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    NSDateComponents *selfComponents = [gregorianCalendar components:dateFlags fromDate:self];
    NSDate *selfDateOnly = [gregorianCalendar dateFromComponents:selfComponents];

    NSDateComponents *otherCompents = [gregorianCalendar components:dateFlags fromDate:otherDate];
    NSDate *otherDateOnly = [gregorianCalendar dateFromComponents:otherCompents];
    return [selfDateOnly compare:otherDateOnly];
}
Matthias Bauch
sumber
2

NSDatesebenarnya mewakili interval waktu dalam hitungan detik sejak tanggal referensi (1 Jan 2000 UTC menurut saya). Secara internal, angka floating point presisi ganda digunakan sehingga dua tanggal arbitrer sangat tidak mungkin untuk membandingkan sama bahkan jika keduanya berada pada hari yang sama. Jika Anda ingin melihat apakah tanggal tertentu jatuh pada hari tertentu, Anda mungkin perlu menggunakan NSDateComponents. misalnya

NSDateComponents* dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2011];
[dateComponents setMonth: 5];
[dateComponents setDay: 24];
/*
 *  Construct two dates that bracket the day you are checking.  
 *  Use the user's current calendar.  I think this takes care of things like daylight saving time.
 */
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* startOfDate = [calendar dateFromComponents: dateComponents];
NSDateComponents* oneDay = [[NSDateComponents alloc] init];
[oneDay setDay: 1];
NSDate* endOfDate = [calendar dateByAddingComponents: oneDay toDate: startOfDate options: 0];
/*
 *  Compare the date with the start of the day and the end of the day.
 */
NSComparisonResult startCompare = [startOfDate compare: myDate];
NSComparisonResult endCompare = [endOfDate compare: myDate];

if (startCompare != NSOrderedDescending && endCompare == NSOrderedDescending)
{
    // we are on the right date
} 
JeremyP
sumber
2

Periksa Fungsi berikut untuk perbandingan tanggal pertama-tama buat dua objek NSDate dan teruskan ke fungsi: Tambahkan baris kode di bawah ini di viewDidload atau sesuai dengan skenario Anda.

-(void)testDateComaparFunc{

NSString *getTokon_Time1 = @"2016-05-31 03:19:05 +0000";
NSString *getTokon_Time2 = @"2016-05-31 03:18:05 +0000";
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss Z"];
NSDate *tokonExpireDate1=[dateFormatter dateFromString:getTokon_Time1];
NSDate *tokonExpireDate2=[dateFormatter dateFromString:getTokon_Time2];
BOOL isTokonValid = [self dateComparision:tokonExpireDate1 andDate2:tokonExpireDate2];}

inilah fungsinya

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

BOOL isTokonValid;

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

}

return isTokonValid;}

Cukup ubah tanggal dan uji fungsi di atas :)

Akhtar
sumber