Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 352 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to determine if an NSDate is today?

#1
How to check if an `NSDate` belongs to today?

I used to check it using first 10 characters from `[aDate description]`. `[[aDate description] substringToIndex:10]` returns string like `"YYYY-MM-DD"` so I compared the string with the string returned by `[[[NSDate date] description] substringToIndex:10]`.

Is there more fast and/or neat way to check?

Thanks.
Reply

#2
This could probably be reworked as an NSDate category, but i used:

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

(However, comparing the two date strings as in the original question almost feels 'cleaner'..)
Reply

#3
This is an offshoot to your question, but if you want to print an NSDate with "Today" or "Yesterday", use the function


- (void)setDoesRelativeDateFormatting:(BOOL)b

for NSDateFormatter
Reply

#4
I would try to get today's date normalized to midnight and the second date, normalize to midnight then compare if it is the same NSDate.

From [an Apple example][1] here's how you normalize to midnight today's date, do the same for the second date and compare:

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


[1]:

[To see links please register here]

Reply

#5
If you have a lot of these date comparisons, then the calls to `calendar:components:fromDate` start to take up a lot of time. According to some profiling I have done, they seem to be quite expensive.

Say you are trying to determine which from some array of dates, say `NSArray *datesToCompare`, are the same day as some given day, say `NSDate *baseDate`, then you can use something like the following (partly adapted from an answer above):

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


Output:

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
Reply

#6
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;
}
Reply

#7
My solution is calculate how much days passed since 1970 by division and compare the integer part

#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);
}
Reply

#8
Refer to Apple's documentation entry entitled "Performing Calendar Calculations" [[link]](

[To see links please register here]

).

Listing 13 on that page suggests that to determine the number of midnights between days, you use:

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

You may then determine if two days are the same by using that method and seeing if it returns 0 or not.
Reply

#9
You could also check the time interval between the date you have, and the current date:

[myDate timeIntervalSinceNow]

This will give you the time interval, in seconds, between myDate and the current date/time.

[Link][1].


[1]:

[To see links please register here]


Edit: Note to everyone: I'm well aware that [myDate timeIntervalSinceNow] does not unambiguously determine whether myDate is today.

I am leaving this answer as is so that if someone is looking for something similar and [myDate timeIntervalSinceNow] is useful, they may find it here.
Reply

#10
for iOS7 and earlier:


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



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through