158

NSDateが今日に属しているかどうかを確認する方法は?

以前は の最初の 10 文字を使用してチェックしていました[aDate description][[aDate description] substringToIndex:10]のような文字列を返す"YYYY-MM-DD"ので、文字列と によって返される文字列を比較しました[[[NSDate date] description] substringToIndex:10]

より迅速かつ/またはきちんと確認する方法はありますか?

ありがとう。

4

20 に答える 20

192

日付コンポーネントを比較できます。

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
}

編集:

私はステファンの方法がもっと好きです。それはよりクリーンでわかりやすいifステートメントになると思います:

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
}

クリス、あなたの提案を取り入れました。紀元を調べなければならなかったので、知らない人のために、BC と AD を区別しています。これはおそらくほとんどの人にとって必要のないものですが、簡単に確認でき、ある程度の確実性が追加されるので、含めました。速度を重視する場合、これはおそらく良い方法ではありません。


SOに関する多くの回答と同様に、7年後、これは完全に古くなっていることに注意してください。Swiftでは今すぐ使用してください.isDateInToday

于 2010-02-25T02:23:39.120 に答える
27

これはあなたの質問から派生したものですが、「今日」または「昨日」で NSDate を出力したい場合は、関数を使用してください

- (void)setDoesRelativeDateFormatting:(BOOL)b

NSDateFormatter 用

于 2011-01-29T05:09:44.593 に答える
16

今日の日付を真夜中に正規化し、2 番目の日付を真夜中に正規化してから、同じ NSDate であるかどうかを比較します。

Apple の例から、今日の日付の午前 0 時に正規化する方法を次に示します。2 番目の日付についても同じことを行い、比較します。

NSCalendar * gregorian = [[NSCalendar alloc]
                               initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents * components =
    [gregorian components:
                 (NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit)
                 fromDate:[NSDate date]];
NSDate * today = [gregorian dateFromComponents:components];
于 2010-02-25T02:40:07.723 に答える
14

Catfish_Man による提案の作業Swift 3 & 4 拡張:

extension Date {

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

}
于 2016-09-06T11:46:26.183 に答える
12

コンポーネント、時代などをジャグリングする必要はありません。

NSCalendar は、既存の日付の特定の時間単位の開始を取得するメソッドを提供します。

このコードは、今日の開始日と別の日付を取得して比較します。と評価された場合NSOrderedSame、両方の日付が同じ日、つまり今日です。

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
}
于 2013-07-14T17:53:31.003 に答える
9
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)
}

Swift 2.0で私のために働いた

于 2015-11-03T11:50:56.670 に答える
5

現在の日付と現在の日付の間の時間間隔を確認することもできます。

[myDate timeIntervalSinceNow]

これにより、myDate と現在の日付/時刻の間の時間間隔 (秒単位) が得られます。

リンク

編集: 皆さんへの注意: [myDate timeIntervalSinceNow] が myDate が今日かどうかを明確に判断できないことは十分承知しています。

誰かが似たようなものを探していて [myDate timeIntervalSinceNow] が便利な場合は、ここで見つけることができるように、この回答をそのままにしておきます。

于 2010-02-25T02:30:43.010 に答える
4

最良の回答に基づく Swift 拡張機能:

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)
    }
}
于 2015-08-05T10:58:48.983 に答える
2

上記の多くの回答よりも簡単な方法があります。

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

if([calendar isDateInToday:date]) {
    //do stuff
}
于 2016-08-14T23:50:12.407 に答える
2

これらの日付比較が多数ある場合、calendar:components:fromDatestart の呼び出しに多くの時間がかかります。私が行ったいくつかのプロファイリングによると、それらはかなり高価なようです。

たとえばNSArray *datesToCompare、ある日付の配列からどれが特定の日と同じ日であるかを判断しようとしているとします。たとえばNSDate *baseDate、次のようなものを使用できます(上記の回答から部分的に改作されています)。

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]);
    }
}

出力:

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
于 2011-11-23T21:37:36.497 に答える
0

Swift 2.2およびiOS 8より前で動作する、強制的にアンラップしない正しい安全なソリューション:

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
}
于 2016-05-05T19:45:20.503 に答える
0

エリカ・サドゥンの素晴らしいNSDate extension. 使い方はとても簡単です。ここでうまくいきます:

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

この投稿にはすでにあります: https://stackoverflow.com/a/4052798/362310

于 2015-04-09T11:50:03.230 に答える
0

これはおそらく NSDate カテゴリとして作り直すことができますが、私は以下を使用しました:

// 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 );
}

(ただし、元の質問のように2つの日付文字列を比較すると、ほとんど「よりきれい」に感じられます..)

于 2010-02-26T15:07:47.523 に答える
-1

これは、受け入れられた回答に基づいた2セントの回答ですが、新しいAPIもサポートしています。注: ほとんどのタイム スタンプは GMT であるため、グレゴリオ暦を使用していますが、必要に応じて変更してください。

func isDateToday(date: NSDate) -> Bool {
    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    if calendar.respondsToSelector("isDateInToday:") {
        return calendar.isDateInToday(date)
    }
    let dateComponents = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay
    let today = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: NSDate()))!
    let dateToCompare = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: date))!

    return dateToCompare == today
}
于 2015-04-24T11:01:43.703 に答える
-4
NSDate *dateOne = yourDate;
NSDate *dateTwo = [NSDate date];  

switch ([dateOne compare:dateTwo])
{  
    case NSOrderedAscending:  
        NSLog(@”NSOrderedAscending”);  
        break;  

    case NSOrderedSame: 
        NSLog(@”NSOrderedSame”);  
        break;

    case NSOrderedDescending:  
        NSLog(@”NSOrderedDescending”);  
        break;  
}  
于 2010-12-07T08:03:53.877 に答える