iPhone4 iOS5 [[NSTimeZone localTimeZone] daylightSavingTimeOffset] wrong for daylight savings time? - ios5

I live in the US eastern time zone (EST), and a couple weeks ago the daylight savings began. I was testing some of my earlier code, which was working(supposedly) fine and noticed that the day second calculations are running 1 hour earlier.
here's the code that I use for testing:
int gmtOffset = [[NSTimeZone localTimeZone] secondsFromGMT];
int daylightOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffset];
int daySeconds = ((int)([date timeIntervalSinceReferenceDate]+gmtOffset+daylightOffset))%(86400+1);
NSLog(#"Day seconds: %i", daySeconds);
The result is 3600 seconds less than the expected value. The daylightOffset is 0. How can I correctly get the daylight offset for the timezone that the user is in? the NSDateFormatter parses the date correctly, so it must know something that NSTimeZone is not telling me.
Thank you!

The [localTime secondsFromGMT] return the true GMT including the daylight saving time, you can get the offset itself by [localTime daylightSavingTimeOffset]

This seems to be a recurring problem for many (me included) and after having pulled my hair way too long I have finally solved the issue.
The assumptions this code relies on is that:
you are interested in dates, not in time
you want your date calculations to be oblivious to any Daylight Saving Time
you want an easy enough string representation of the date such that you can persist it.
In order to achive 1. I use unique NSCalendar instance that is initialized to Gregorian, GMT
This also serves 2.
For 3. the NSDateFormatter is initialized with both the unique calendar and its time zone.
Setting the timezone of the formatter to that of the calendar otherwise used for calculation was the key to all the issues I had!
This should always be true (assume the code below is part of a DateModel class):
NSDate * today = [DateModel normalize: [NSDate date]] ;
NSString*todayS= [DateModel dateToString: today] ;
BOOL alwaysTrue=[[DateModel normalize: [NSDate date]] isEqual: [DateModel stringToDate: todayS]] ;
Here's the code:
+ (NSDate *) normalize: (NSDate *) date {
NSDateComponents * comps = [[DateModel calendar] components:NSYearCalendarUnit
| NSMonthCalendarUnit
| NSDayCalendarUnit
| NSHourCalendarUnit
| NSMinuteCalendarUnit
| NSSecondCalendarUnit
fromDate:date] ;
[comps setHour:0] ;
[comps setMinute:0] ;
[comps setSecond:0] ;
NSDate * dateOnly = [[DateModel calendar] dateFromComponents:comps] ;
return dateOnly ;
}
+ (NSCalendar *) calendar {
static NSCalendar * calendar = nil ;
if (calendar == nil) {
calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] ;
calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation: #"GMT"] ;
}
return calendar ;
}
+ (NSDateFormatter *) dateFormatter {
static NSDateFormatter * formatter = nil ;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc] init] ;
[formatter setCalendar:[self calendar]] ; // <- This is
[formatter setTimeZone:[self calendar].timeZone] ; // <- critical
[formatter setDateFormat:#"yyyyMMdd"] ;
}
return formatter ;
}
+ (NSDate *) dateFromString: (NSString *) stringDate {
return [DateModel normalize: [[DateModel dateFormatter] dateFromString:stringDate]] ;
}
+ (NSString *) stringFromDate: (NSDate *) date {
return [[DateModel dateFormatter] stringFromDate:[DateModel normalize: date]] ;
}
Hope this helps someone!

If you want to determine the number of seconds since midnight, you can use date components. This code adjusts appropriately for daylight savings.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *comps = [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit| NSSecondCalendarUnit
fromDate:[NSDate date]];
NSInteger time = [comps hour] * 3600 + [comps minute] * 60 + [comps second];
NSLog(#"Day seconds: %i", time);

Related

Comparing NSDate + Period

I have start date and a duration (period). For example startDate = '2014-02-12' period = 2. I desired dates 2014-02-12, 2014-02-14, 2014-02-16, .... I need to determine the current date is flagged during.
To check if the difference between the start date and the current date is an even
number of days, use NSDateComponents:
NSDate *startDate = ...;
NSDate *currentDate = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *diff = [cal components:NSDayCalendarUnit fromDate:startDate
toDate:currentDate options:0];
NSInteger days = diff.day;
if (days % 2 == 0) {
// even number of days between start date and current date
}
You can get the desired dates using
- (id)dateByAddingTimeInterval:(NSTimeInterval)seconds
with seconds = period*3600*24
Calc the days from startDate to givenData, check the result whether it can be divisible by the period.
+ (NSInteger)daysWithinEraFromDate:(NSDate *)startDate toDate:(NSDate *)endDate {
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone localTimeZone]];
// for timezone issue
NSDate *newDate1 = [startDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]];
NSDate *newDate2 = [endDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]];
NSInteger startDay = [gregorian ordinalityOfUnit:NSDayCalendarUnit
inUnit: NSEraCalendarUnit forDate:newDate1];
NSInteger endDay = [gregorian ordinalityOfUnit:NSDayCalendarUnit
inUnit: NSEraCalendarUnit forDate:newDate2];
return endDay - startDay;
}

Replacement of date object with “today” and “yesterday” strings in iphone

I want to return my date objects with string “today” and “yesterday” and dates in Objective C.Please all comments are welcome:
I have dates with format #"yyyy-MM-dd HH:mm:ss"] and then figures out if the date is today or yesterday and than, if it is, it returns "(Yesterday | Today | Date ) " formated string.
NSDateFormatter can do this. However this does not work with custom date formats, but in most cases when you need relative dates you are presenting them to the user and you should not use hard coded date formats in the first place.
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.timeStyle = NSDateFormatterMediumStyle;
df.dateStyle = NSDateFormatterShortStyle;
df.doesRelativeDateFormatting = YES; // this enables relative dates like yesterday, today, tomorrow...
NSLog(#"%#", [df stringFromDate:[NSDate dateWithTimeIntervalSinceNow:-48*60*60]]);
NSLog(#"%#", [df stringFromDate:[NSDate dateWithTimeIntervalSinceNow:-24*60*60]]);
NSLog(#"%#", [df stringFromDate:[NSDate date]]);
NSLog(#"%#", [df stringFromDate:[NSDate dateWithTimeIntervalSinceNow:24*60*60]]);
NSLog(#"%#", [df stringFromDate:[NSDate dateWithTimeIntervalSinceNow:48*60*60]]);
this will print:
2013-06-06 09:13:22.844 x 2[11732:c07] 6/4/13, 9:13:22 AM
2013-06-06 09:13:22.845 x 2[11732:c07] Yesterday, 9:13:22 AM
2013-06-06 09:13:22.845 x 2[11732:c07] Today, 9:13:22 AM
2013-06-06 09:13:22.846 x 2[11732:c07] Tomorrow, 9:13:22 AM
2013-06-06 09:13:22.846 x 2[11732:c07] 6/8/13, 9:13:22 AM
On a device with german locale this will print "Vorgestern" (the day before yesterday) and "Übermorgen" (the day after tomorrow) for the first and last date.
What about NSDateFormatters setDoesRelativeDateFormatting ?
Specifies whether the receiver uses phrases such as “today” and “tomorrow” for the date component.
- (void)setDoesRelativeDateFormatting:(BOOL)b
Set parameters b = YES to specify that the receiver should use relative date formatting,
otherwise NO.
Take a look: NSDateFormatter class reference
I hope this also will be usefull for you as well:
NSDate *date = somedate;
NSInteger dayDiff = (int)[date timeIntervalSinceNow] / (60*60*24);
NSDateComponents *componentsToday = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
NSDateComponents *componentsDate = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:somedate];
NSInteger day = [componentsToday day] - [componentsDate day];
if (dayDiff == 0) {
NSLog(#"Today");
} else if (dayDiff == -1) {
NSLog(#"Yesterday");
} else if(dayDiff > -7 && dayDiff < -1) {
NSLog(#"This week");
} else if(dayDiff > -14 && dayDiff <= -7) {
NSLog(#"Last week");
} else if(dayDiff >= -60 && dayDiff <= -30) {
NSLog(#"Last month");
} else {
NSLog(#"A long time ago");
}
Replacement of date object with “today” and “yesterday” strings in Swift.
If you want to display date with different formate then change the timeStyle and dateStyle as per you need.
var df = DateFormatter()
df.timeStyle = .medium
df.dateStyle = .short
df.doesRelativeDateFormatting = true
// this enables relative dates like yesterday, today, tomorrow...
print("\(df.string(from: Date(timeIntervalSinceNow: -48 * 60 * 60)))")
print("\(df.string(from: Date(timeIntervalSinceNow: -24 * 60 * 60)))")
print("\(df.string(from: Date()))")
print("\(df.string(from: Date(timeIntervalSinceNow: 24 * 60 * 60)))")
print("\(df.string(from: Date(timeIntervalSinceNow: 48 * 60 * 60)))")
Result:
6/4/13, 9:13:22 AM
Yesterday, 9:13:22 AM
Today, 9:13:22 AM
Tomorrow, 9:13:22 AM
6/8/13, 9:13:22 AM
NSDate *todayDate = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *today = [dateFormat stringFromDate:todayDate];
NSLog(#"today is %#",today);
NSDate *yesterdayDate = [todayDate dateByAddingTimeInterval: -86400.0];
NSString *yesterday = [dateFormat stringFromDate:yesterdayDate];
NSLog(#"yesterday was %#",yesterday);
NSString *yourDate = [NSString stringWithFormat:#"2013-06-08 12:33:28"];
if ([yourDate isEqualToString:yesterday]) {
NSLog(#"yesterday");
}
else if ([yourDate isEqualToString:today])
{
NSLog(#"today");
}
else
{
NSLog(#"the date is %#",yourDate);
}
1) take out today's and yesterday's date , then compare the the date you enter and print accordingly
NSTimeInterval interval = [dict[#"deviceTimeStamp"]doubleValue]; // set your intervals
NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval]; // set your past date or create it using dateWithIntervalSince1970 method
[formatter setDateFormat:#"hh:mm a"];
NSTimeZone *tz = [NSTimeZone defaultTimeZone];
NSInteger seconds = [tz secondsFromGMTForDate: date];
NSDate *dateee = [NSDate dateWithTimeInterval: seconds sinceDate: date];
NSDateComponents *components = [[NSCalendar currentCalendar] components:units fromDate:dateee toDate:[NSDate date] options:0];
if (components.day > 0)
{
if (components.day > 1){
[formatter setDateFormat:#"MMM dd"];
NSString *dateString = [formatter stringFromDate:date];
NSlog(#"%#",dateString);
}
else{
NSlog(#"Yesterday");
}
}
else{
NSlog(#"Today");
}

Convert NSString to a Time, and then calculate "Time Until"

I have been on SO for awhile now trying to get this problem solved but have not had any luck.
In a nutshell I want to take a string like this: "2011-11-21 11:20:00" and calculate the "Time Until".
In a format like "1 day 36 mins" which would be a string I could display in a label.
I cant wrap my head around this. Anyone have some sample code from doing this before? Any help would be greatly appreciated.
#Maudicus is on the right track but has some flaws in his answer.
The date format you'd need to use is #"yyyy-MM-dd HH:mm:ss"
Once you have the date, you should use -[NSCalendar components:fromDate:toDate:options:] to figure out the differences between one date and another. For example:
NSDate *date = ...; // the date converted using the date formatter
NSDate *target = [NSDate date]; // now
NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger components = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *difference = [calendar components:components fromDate:date toDate:target options:0];
NSLog(#"difference: %d days, %d hours, %d minutes, %d seconds", [difference days], [difference hours], [difference minutes], [difference seconds]);
This code should help you out.
NSDate * date;
//Assume dateString is populated and of format NSString * dateString =#"2011-11-21 11:20:00";
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
//EDITED date formatter to correct behavior
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
if (dateString != nil) {
date = [dateFormatter dateFromString:dateString];
}
[dateFormatter release];
NSTimeInterval difference = [date timeIntervalSinceDate:[NSDate date]];
int days = difference/(3600*24);
difference -= (float) (days*3600*24);
int hours = difference/(3600);
difference -= (float) (hours*3600);
int minutes = difference/(60);
NSString * timeRemaining = [NSString stringWithFormat:#"%dd %dh %dm", days, hours, minutes];
duration.text = [NSString stringWithFormat:#"%d:%02d", (int)audioPlayer.duration / 3600, (int)audioPlayer.duration % 60, nil];

how to compare time with current date and time?

In My application I have to complete a particular task in given time.So first i calculated the time complete the task in seconds and then add that time to the current that like this.
NSDate *mydate = [NSDate date];
NSTimeInterval TotalDuraionInSec = sec.cal_time * 60;
TaskCmpltTime = [mydate addTimeInterval:TotalDuraionInSec];
NSLog(#"task will be completed at%#",TaskCmpltTime);
now I compare time like this
if([CurrentTime isEqualToDate:AfterCmpltTime]){
NSLog (#"Time Finish");
}
but I want to know is Time is left or not.Is current time is less then or greater then current time how can i know this ?
timeIntervalSinceNow compares the NSDate with Now. if NSDate is after Now the return value is possitive, if the date is earlier than Now the result is negative.
double timeLeft = [TaskCompltTime timeIntervalSinceNow];
if( timeLeft > 0.0 )
// still time left
else
//time is up
I have an example where I get the time from a picker and check if its today or tomorrow. You should be able to just take the code and use it in your way...
int selectedHour = [customPickerView selectedRowInComponent:0];
int selectedMinute = [customPickerView selectedRowInComponent:1];
NSDate *today = [NSDate date];
NSDateFormatter *weekdayFormatter = [[[NSDateFormatter alloc] init]autorelease];
NSDateFormatter *hmformatter = [[[NSDateFormatter alloc] init]autorelease];
[hmformatter setDateFormat: #"hh mm"];
[weekdayFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[weekdayFormatter setDateFormat: #"EE"];
// NSString *formattedDate = [formatter stringFromDate: today];
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]autorelease];
NSDateComponents *dateComponentsToday = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit) fromDate:today];
NSInteger currentHour = [dateComponentsToday hour];
NSInteger currentMinute = [dateComponentsToday minute];
NSString *weekday;
if ((selectedHour > currentHour) | ((selectedHour == currentHour) & (selectedMinute > currentMinute))) {
//so we are still in today
weekday = [weekdayFormatter stringFromDate: today];
weekday = NSLocalizedString(#"today", #"today");
} else {
//the timer should start tomorrow
NSTimeInterval secondsPerDay = 24 * 60 * 60;
NSDate *tomorrow = [today dateByAddingTimeInterval:secondsPerDay];
weekday = [weekdayFormatter stringFromDate: tomorrow];
weekday = NSLocalizedString(#"tomorrow", #"tomorrow");
}
Yeah, for your purposes it's probably best to work in time intervals. The NSTimeInterval in Objective-C is an alias for double, and it represents a time value in seconds (and, of course, fractions, down to at least millisecond resolution).
There are several methods on NSDate for this -- +timeIntervalSinceReferenceDate, which returns the number of seconds since Jan 1, 2001, -timeIntervalSinceReferenceDate, which returns the difference in time between the supplied NSDate object and Jan 1, 2001, -timeIntervalSinceDate:, which returns the difference in seconds between the two NSDate objects, and -timeIntervalSinceNow, which returns the difference between the current time and the NSDate object.
Lots of times it's most convenient to store an NSDate value as an NSTimeInterval instead (eg, timeIntervalSinceReferenceDate). This way it doesn't have to be retained and disposed, etc.

iPhone - get number of days between two dates

I'm writing a GTD app for the iPhone. For the due tasks, I want to display something like "Due tomorrow" or "Due yesterday" or "Due July 18th". Obviously, I need to display "Tomorrow" even if the task is less than 24 hours away (e.g. the user checks at 11pm on Saturday and sees there's a task on Sunday at 8am). So, I wrote a method to get the number of days in between two dates. Here's the code...
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd-HH-mm"];
NSDate *nowDate = [dateFormatter dateFromString:#"2010-01-01-15-00"];
NSDate *dueDate = [dateFormatter dateFromString:#"2010-01-02-14-00"];
NSLog(#"NSDate *nowDate = %#", nowDate);
NSLog(#"NSDate *dueDate = %#", dueDate);
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *differenceComponents = [calendar components:(NSDayCalendarUnit)
fromDate:nowDate
toDate:dueDate
options:0];
NSLog(#"Days between dates: %d", [differenceComponents day]);
... and here's the output:
NSDate *nowDate = 2010-01-01 15:00:00 -0700
NSDate *dueDate = 2010-01-02 14:00:00 -0700
Days between dates: 0
As you can see, the method returns incorrect results. It should have returned 1 as the number of days between the two days. What am I doing wrong here?
EDIT: I wrote another method. I haven't done extensive unit tests, but so far it seems to work:
+ (NSInteger)daysFromDate:(NSDate *)fromDate inTimeZone:(NSTimeZone *)fromTimeZone untilDate:(NSDate *)toDate inTimeZone:(NSTimeZone *)toTimeZone {
NSCalendar *calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
[calendar setTimeZone:fromTimeZone];
NSDateComponents *fromDateComponents = [calendar components:unitFlags fromDate:fromDate];
[calendar setTimeZone:toTimeZone];
NSDateComponents *toDateComponents = [calendar components:unitFlags fromDate:toDate];
[calendar setTimeZone:[NSTimeZone defaultTimeZone]];
NSDate *adjustedFromDate = [calendar dateFromComponents:fromDateComponents];
NSDate *adjustedToDate = [calendar dateFromComponents:toDateComponents];
NSTimeInterval timeIntervalBetweenDates = [adjustedToDate timeIntervalSinceDate:adjustedFromDate];
NSInteger daysBetweenDates = (NSInteger)(timeIntervalBetweenDates / (60.0 * 60.0 * 24.0));
NSDateComponents *midnightBeforeFromDateComponents = [[NSDateComponents alloc] init];
[midnightBeforeFromDateComponents setYear:[fromDateComponents year]];
[midnightBeforeFromDateComponents setMonth:[fromDateComponents month]];
[midnightBeforeFromDateComponents setDay:[fromDateComponents day]];
NSDate *midnightBeforeFromDate = [calendar dateFromComponents:midnightBeforeFromDateComponents];
[midnightBeforeFromDateComponents release];
NSDate *midnightAfterFromDate = [[NSDate alloc] initWithTimeInterval:(60.0 * 60.0 * 24.0)
sinceDate:midnightBeforeFromDate];
NSTimeInterval timeIntervalBetweenToDateAndMidnightBeforeFromDate = [adjustedToDate timeIntervalSinceDate:midnightBeforeFromDate];
NSTimeInterval timeIntervalBetweenToDateAndMidnightAfterFromDate = [adjustedToDate timeIntervalSinceDate:midnightAfterFromDate];
if (timeIntervalBetweenToDateAndMidnightBeforeFromDate < 0.0) {
// toDate is before the midnight before fromDate
timeIntervalBetweenToDateAndMidnightBeforeFromDate -= daysBetweenDates * 60.0 * 60.0 * 24.0;
if (timeIntervalBetweenToDateAndMidnightBeforeFromDate < 0.0)
daysBetweenDates -= 1;
}
else if (timeIntervalBetweenToDateAndMidnightAfterFromDate >= 0.0) {
// toDate is after the midnight after fromDate
timeIntervalBetweenToDateAndMidnightAfterFromDate -= daysBetweenDates * 60.0 * 60.0 * 24.0;
if (timeIntervalBetweenToDateAndMidnightAfterFromDate >= 0.0)
daysBetweenDates += 1;
}
[midnightAfterFromDate release];
return daysBetweenDates;
}
From the docs for components:fromDate:toDate:options::
The result is lossy if there is not a small enough unit requested to hold the full precision of the difference.
Since the difference is less than a full day, it correctly returns a result of 0 days.
If all you care about is tomorrow or yesterday vs. a specific date, then you can save yourself a lot of work and just test whether the dates are only one calendar day apart.
To do that, compare the dates to find which is earlier and which is later (and if they compare equal, bail out with that result), then test whether 1 day after the earlier date produces a date with the same year, month, and day-of-month as the later date.
If you really do want to know exactly how many calendar days there are from one date to the other:
Send the calendar a components:fromDate: message to get the year, month, and day-of-the-month of the first date.
Same as #1, but for the second date.
If the two dates are in the same year and month, subtract one day-of-month from the other and pass to abs (see abs(3)) to take the absolute value.
If they are not in the same year and month, test whether they are in adjacent months (e.g., December 2010 to January 2011, or June 2010 to July 2010). If they are, add the number of days in the earlier date's month (which you can obtain by sending the calendar a rangeOfUnit:inUnit:forDate: message, passing NSDayCalendarUnit and NSMonthCalendarUnit, respectively) to the day-of-month of the later date, then compare that result to the earlier date's day-of-month.
For example, when comparing 2010-12-31 to 2011-01-01, you would first determine that these are in adjacent months, then add 31 (number of days in 2010-12) to 1 (day-of-month of 2011-01-01), then subtract 31 (day-of-month of 2010-12-31) from that sum. Since the difference is 1, the earlier date is one day before the later date.
When comparing 2010-12-30 to 2011-01-02, you would determine that they are in adjacent months, then add 31 (days in 2010-12) to 2 (day-of-month of 2011-01-02), then subtract 30 (day-of-month of 2010-12-30) from that sum. 33 minus 30 is 3, so these dates are three calendar days apart.
Either way, I strongly suggest writing unit tests at least for this code. I've found that date-handling code is among the most likely to have subtle bugs that only manifest, say, twice a year.
One thing you might try is using rangeOfUnit: to zero out hours, minutes and seconds from the start and end dates.
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit range = NSDayCalendarUnit;
NSDateComponents *comps = [[NSDateComponents alloc] init];
NSDate *start = [NSDate date];
NSDate *end;
[comps setDay:1];
[calendar rangeOfUnit:range startDate:&start interval:nil forDate:start];
end = [calendar dateByAddingComponents:comps toDate:start options:0];
In this example start will be 2010-06-19 00:00:00 -0400, end will be 2010-06-20 00:00:00 -0400. I'd imagine this would work better with NSCalendar's comparison methods, although I haven't tested it myself.
I am using this piece of code, it is working very well:
- (NSInteger)daysToDate:(NSDate*)date
{
if(date == nil) {
return NSNotFound;
}
NSUInteger otherDay = [[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date];
NSUInteger currentDay = [[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:self];
return (otherDay-currentDay);
}
Here is the function I've used in the past
its defined in a category on NSDate
- (int) daysToDate:(NSDate*) endDate
{
//dates needed to be reset to represent only yyyy-mm-dd to get correct number of days between two days.
NSDateFormatter *temp = [[NSDateFormatter alloc] init];
[temp setDateFormat:#"yyyy-MM-dd"];
NSDate *stDt = [temp dateFromString:[temp stringFromDate:self]];
NSDate *endDt = [temp dateFromString:[temp stringFromDate:endDate]];
[temp release];
unsigned int unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:unitFlags fromDate:stDt toDate:endDt options:0];
int days = [comps day];
[gregorian release];
return days;
}
-(NSInteger)daysBetweenTwoDates:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime
{
NSDate *fromDate;
NSDate *toDate;
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar rangeOfUnit:NSDayCalendarUnit startDate:&fromDate
interval:NULL forDate:fromDateTime];
[calendar rangeOfUnit:NSDayCalendarUnit startDate:&toDate
interval:NULL forDate:toDateTime];
NSDateComponents *difference = [calendar components:NSDayCalendarUnit
fromDate:fromDate toDate:toDate options:0];
return [difference day];
}