سؤال

كيفية التحقق إذا كان NSDate ينتمي اليوم؟

اعتدت التحقق من ذلك باستخدام الأحرف العشرة الأولى من [aDate description]. [[aDate description] substringToIndex:10] إرجاع سلسلة مثل "YYYY-MM-DD" لذلك قارنت السلسلة مع السلسلة التي تم إرجاعها بواسطة [[[NSDate date] description] substringToIndex:10].

هل هناك طريقة سريعة و/أو أنيقة للتحقق؟

شكرًا.

هل كانت مفيدة؟

المحلول

في MacOS 10.9+ و iOS 8+ ، هناك طريقة على NSCALENDAR/CALENDAR تقوم بذلك بالضبط!

- (BOOL)isDateInToday:(NSDate *)date 

لذلك كنت ببساطة تفعل

ج موضوعية:

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

سريع 3:

let today = Calendar.current.isDateInToday(date)

نصائح أخرى

يمكنك مقارنة مكونات التاريخ:

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
}

تعديل:

أحب طريقة ستيفان أكثر ، أعتقد أنها تجعل منظفًا وأكثر فهمًا إذا كان البيان:

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. ربما يكون هذا غير ضروري بالنسبة لمعظم الناس ، لكن من السهل التحقق منه وإضافة بعض اليقين ، لذلك قمت بتضمينه. إذا كنت ستذهب للسرعة ، فربما لا تكون هذه طريقة جيدة على أي حال.


ملاحظة كما هو الحال مع العديد من الإجابات على ذلك ، بعد 7 سنوات ، هذا قديم تمامًا. في سويفت الآن فقط استخدم .isDateInToday

هذا فرع لسؤالك ، ولكن إذا كنت ترغب في طباعة nsdate مع "اليوم" أو "أمس" ، استخدم الوظيفة

- (void)setDoesRelativeDateFormatting:(BOOL)b

ل NSDateFormatter

سأحاول أن أتطبيع تاريخ اليوم حتى منتصف الليل والتاريخ الثاني ، وتطبيع حتى منتصف الليل ، ثم قارن ما إذا كان نفس NSDATE.

من عند مثال على التفاح إليك الطريقة التي تتطبيع بها حتى منتصف الليل تاريخ اليوم ، وفعل الشيء نفسه للتاريخ الثاني وقارنه:

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

عمل سويفت 3 و 4 امتداد من اقتراح Catfish_man:

extension Date {

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

}

لا حاجة إلى التوفيق مع المكونات والعصور والأشياء.

يوفر 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
}
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)
}

عملت بالنسبة لي على سويفت 2.0

نسخة سريعة من أفضل إجابة:

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
}

ارجع إلى إدخال وثائق Apple بعنوان "إجراء حسابات التقويم" حلقة الوصل.

تشير قائمة 13 في تلك الصفحة إلى تحديد عدد منتصف الليل بين الأيام ، يمكنك استخدامها:

- (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;
}

يمكنك بعد ذلك تحديد ما إذا كان يومين متماثلين باستخدام هذه الطريقة ومعرفة ما إذا كان يتم إرجاع 0 أم لا.

يمكنك أيضًا التحقق من الفاصل الزمني بين التاريخ الذي لديك ، والتاريخ الحالي:

[myDate timeIntervalSinceNow]

سيعطيك هذا الفاصل الزمني ، في ثوانٍ ، بين MyDate والتاريخ/الوقت الحالي.

وصلة.

تحرير: لاحظ للجميع: أنا أدرك جيدًا أن [MyDate TimeIntervalsincenow] لا يحدد بشكل لا لبس فيه ما إذا كان MyDate اليوم.

سأترك هذه الإجابة كما هي حتى إذا كان شخص ما يبحث عن شيء مشابه و [myDate TimeIntervalsincenow] مفيد ، فقد يجدونه هنا.

امتداد سريع استنادًا إلى أفضل الإجابات:

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

إذا كان لديك الكثير من مقارنات التاريخ هذه ، فإن المكالمات calendar:components:fromDate ابدأ في تناول الكثير من الوقت. وفقًا لبعض التنميط الذي قمت به ، يبدو أنها مكلفة للغاية.

قل أنك تحاول تحديد أي من مجموعة من التواريخ ، على سبيل المثال 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

هناك طريقة أسهل من العديد من الإجابات أعلاه!

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

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

ربما يمكن إعادة صياغة هذا كفئة 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 );
}

(ومع ذلك ، فإن مقارنة سلاسل التاريخ كما هو الحال في السؤال الأصلي تشعر "أنظف" تقريبًا ..)

لـ iOS7 وأوقد:

//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 :-)");

تحقق من إريكا سادون العظيمة NSDate extension. بسيط جدا للاستخدام. بخير هنا:

http://github.com/erica/nsdate-extensions

إنه موجود بالفعل في هذا المنشور: https://stackoverflow.com/a/4052798/362310

الحل الصحيح والآمن بدون قوة غير متوفرة ، يعمل على 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
}

إليك مبني إجابتي على الإجابة المقبولة ولكن دعم 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
}

إن حلي هو حساب مقدار الأيام التي تم تمريرها منذ عام 1970 بواسطة التقسيم ومقارنة الجزء الأيمن

#define kOneDay (60*60*24)
- (BOOL)isToday {
  NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];

  NSInteger days =[self timeIntervalSince1970] + offset;
  NSInteger currentDays = [[NSDate date] timeIntervalSince1970] + offset;
  return (days / kOneDay == currentDays / kOneDay);
}
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;  
}  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top