I want some changes in the date comparison.
In my application I am comparing two dates and getting difference as number of Days, but if there is only one day difference the system shows me 0 as a difference of days.
NSDateFormatter *date_formater=[[NSDateFormatter alloc]init];
[date_formater setDateFormat:#"MMM dd,YYYY"];
NSString *now=[NSString stringWithFormat:#"%#",[date_formater stringFromDate:[NSDate date]]];
LblTodayDate.text = [NSString stringWithFormat:#"%#",[NSString stringWithFormat:#"%#",now]];
NSDate *dateofevent = [[NSUserDefaults standardUserDefaults] valueForKey:#"CeremonyDate_"];
NSDate *endDate =dateofevent;
NSDate *startDate = [NSDate date];
gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
unsigned int unitFlags = NSDayCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags fromDate:startDate toDate:endDate options:0];
int days = [components day];
I found some solutions that If we make the time as 00:00:00 for comparison then it will show me proper answer, I am right or wrong I don't know.
i think this is not correct make the time 00:00:00.
may be you get difference is less than 24 hour thats why it rounded off and you 0 day.
Alexander solution is right so use that solution like -
this works fine for me also.
NSDate *endDate=[dateFormat dateFromString:now];
NSTimeInterval interval = [CeremonyDate timeIntervalSinceDate:endDate];
int diff=interval/86400;//for converting seconds into days.
same problem of rounding a figure you get here but you can sort out that in an understable way.
I usually find out difference in seconds and calculate ceil(diffInSeconds / 86400).
Try this code for get two date and time different.
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"] autorelease]];
[dateFormatter setDateFormat:#"mm:ss"];
NSDate* firstDate = [dateFormatter dateFromString:#"04:45"];
NSDate* secondDate = [dateFormatter dateFromString:#"05:00"];
NSTimeInterval timeDifference = [secondDate timeIntervalSinceDate:firstDate];
NSLog(#"%f",timeDifference);
i hope this code usefull for you.
Here a prefect solution to find difference between two dates
- (NSString *)calculateDuration:(NSDate *)oldTime secondDate:(NSDate *)currentTime
{
NSString *timeSincePost;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:oldTime toDate:currentTime options:0];
NSInteger year = [dateComponents year];
NSInteger month = [dateComponents month];
NSInteger day = [dateComponents day];
NSInteger hour = [dateComponents hour];
NSInteger minute = [dateComponents minute];
NSInteger second = [dateComponents second];
if (year) {
timeSincePost = [NSString stringWithFormat:#"%ld%#", (long)year,[[kAppDelegate languageBundle] localizedStringForKey:#"y" value:#"" table:nil]];
}
else if (month) {
timeSincePost = [NSString stringWithFormat:#"%ld%#", (long)month,[[kAppDelegate languageBundle] localizedStringForKey:#"M" value:#"" table:nil]];
}
if(day) {
timeSincePost = [NSString stringWithFormat:#"%ld%#", (long)day,[[kAppDelegate languageBundle] localizedStringForKey:#"d" value:#"" table:nil]];
}
else if(hour) {
timeSincePost = [NSString stringWithFormat: #"%ld%#", (long)hour,[[kAppDelegate languageBundle] localizedStringForKey:#"H" value:#"" table:nil]];
}
else if(minute) {
timeSincePost = [NSString stringWithFormat: #"%ld%#", (long)minute,[[kAppDelegate languageBundle] localizedStringForKey:#"m" value:#"" table:nil]];
}
else if(second)
timeSincePost = [NSString stringWithFormat: #"%ld%#", (long)second,[[kAppDelegate languageBundle] localizedStringForKey:#"s" value:#"" table:nil]];
return timeSincePost;
}
and call above function with two parameter as NSDate
NSString *duration = [self calculateDuration:postDate secondDate:[NSDate date]];
lblPostTime.text = duration;
note:: postDate is FirstDate & second date is current date..
Related
If you want to get time left to ring the alarm. Then u can use this method and for next day you can set day =day+1; according to u. It will return u difference between current time and setted alarm time.
+(NSString*)getDifference:(NSString*)setTime
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSWeekdayCalendarUnit fromDate:[NSDate date]];
int day=[components day];
int month=[components month];
int year=[components year];
//day=day+1;
NSDateFormatter *formatter;
NSString *CurrentdateString;
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd-MM-yyyy hh:mm a"];
CurrentdateString = [formatter stringFromDate:[NSDate date]];
//settime=#"2:40 PM";
NSDate *currentDate=[formatter dateFromString:CurrentdateString];
NSDate *setDate=[formatter dateFromString:[NSString stringWithFormat:#"%i-%i-%i %#",day,month,year,setTime]];
NSLog(#"current date is %#",[formatter stringFromDate:currentDate]);
NSLog(#"setted date string is %#",[formatter stringFromDate:setDate]);
NSTimeInterval interval=[setDate timeIntervalSinceDate:currentDate];
int totalmin=(int)(interval/60);
int hour=(int)(totalmin/60);
int min=(int)fmod(totalmin,60);
[formatter release];
if (hour<0 || min<0) {
totalmin=hour*60+min;
totalmin=(24*60)+totalmin;
hour=totalmin/60;
min=fmod(totalmin, 60);
}
NSString *returnString=[[NSString alloc] init];
returnString=[NSString stringWithFormat:#"%i hr. %i min.",hour,min];
NSLog(#"date string is %i:%i",hour,min);
return returnString;
}
I would like to create an NSDate object that represents the next day that matches a NSString day.
For example. The NSString is MON or Monday I want to get the next NSDate that matches this day - it can be today aswell.
e.g.: NSString day = #"Tues";
result = 30 Aug
NSInteger desiredWeekday = 3; // Tuesday
NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSWeekdayCalendarUnit];
NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;;
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
NSInteger currentWeekday = dateComponents.weekday;
NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
daysComponents.day = differenceDays;
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
NSLog(#"newDate: %#", newDate);
2011-08-30 18:42:09.443 Test[63789:707] newDate: 2011-09-05 22:42:09 +0000
I have two time.. one fetched directly as string(#"21:00") and other is the current time. I want to display a count down timer showing how much time left from now to reach 21:00.
For eg: the label i use should display "You have 3hrs and 30 minutes left.." if the current time is 17:30.
thanks..
OK have completely revised my answer, and have created a complete solution to the problem, with fully tested sample code available on github.
Enjoy :)
Something like this should do it. This will give you the remaining time in seconds. Then you just need to to standard timer stuff as indicated in other answers.
//assumption: targetTime is after now
NSString *targetTime = #"21:00";
//split our time into components
NSArray *timeSplit = [targetTime componentsSeparatedByString:#":"];
NSUInteger hours = [[timeSplit objectAtIndex:0] intValue];
NSUInteger minutes = [[timeSplit objectAtIndex:1] intValue];
NSDate *now = [NSDate date];
//split now into year month day components
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [currentCalendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:now];
//set our time components from above
[dateComponents setHour:hours];
[dateComponents setMinute:minutes];
NSDate *targetDate = [currentCalendar dateFromComponents:dateComponents];
//ensure target is after now
if ([targetDate timeIntervalSinceDate:now] < 0)
{
NSDateComponents *day = [[NSDateComponents alloc] init];
[day setDay:1];
targetDate = [currentCalendar dateByAddingComponents:day toDate:targetDate options:0];
}
NSTimeInterval timeRemaining = [targetDate timeIntervalSinceDate:now];
You create a NSTimer that fires every second:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(tickClock) userInfo:nil repeats:YES];
When it fires, you enter a method:
- (void)tickClock;
in there, you compare the date you have against the current date [NSData currentDate];
Like
NSTimeInterval distanceBetweenDates = [currentDate timeIntervalSinceDate:yourDate];
where distanceBetweenDates is specified in seconds.
To create a date from your string create a NSDate accordingly
NSInteger year = 2011;
NSInteger month = 8;
NSInteger day = 26;
NSInteger hour = 21;
NSInteger minute = 0;
NSInteger second = 0;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:year];
[components setMonth:month];
[components setDay:day];
[components setHour:hour];
[components setMinute:minute];
[components setSecond:second];
NSDate *date = [calendar dateFromComponents:components];
[components release];
Here's a puzzler. I use the following to calculate the number of days between today's date and an upcoming birthday:
-(int) daysTillBirthday: (NSDate*)aDate {
// check to see if valid date was passed in
//NSLog(#"aDate passed in is %#",aDate);
if (aDate == nil) {
//NSLog(#"aDate is NULL");
return -1; // return a negative so won't be picked in table
}
//** HOW MANY DAYS TO BDAY
NSDate *birthDay = aDate; // [calendar dateFromComponents:myBirthDay];
//NSLog(#"birthDay: %#, today: %#",birthDay, [NSDate date]);
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *thisYearComponents = [calendar components:NSYearCalendarUnit fromDate:[NSDate date]];
NSDateComponents *birthDayComponents = [calendar components:NSMonthCalendarUnit|NSDayCalendarUnit fromDate:birthDay];
[birthDayComponents setYear:[thisYearComponents year]];
NSDate *birthDayThisYear = [calendar dateFromComponents:birthDayComponents];
//NSLog(#"birthDayThisYear: %#",birthDayThisYear);
NSDateComponents *differenceHours = [calendar components:NSHourCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
NSDateComponents *differenceDays = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
// NSLog(#"difference days: %i, hours %i",[differenceDays day],[differenceHours hour]);
//*** I added this to try and correct the "error" ***
if ([differenceDays day] == 0) { // is it today, or tomorrow?
if (([differenceHours hour] <= 0) && ([differenceHours hour] >= -24)) { // must be today
//NSLog(#"TODAY");
return (0);
[calendar release];
}else if (([differenceHours hour] >= 0) && ([differenceHours hour] <= 24)) {
//NSLog(#"TOMORROW");
return (1);
[calendar release];
}
}
if ([differenceDays day] < 0) {
// this years birthday is already over. calculate distance to next years birthday
[birthDayComponents setYear:[thisYearComponents year]+1];
birthDayThisYear = [calendar dateFromComponents:birthDayComponents];
differenceDays = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
}
return ([differenceDays day]);
[calendar release];
}
Everything works, but the results are not accurate! I often find that birthdays that are close to today, but one day apart, result in [differenceDays day] being the same! i.e. if today is 6/6/2011 and I have two birthdays, one on 6/7/2011 and another 6/8/2011, then they are both shown as 1 day away!
Anyone have any better methods for accurately calculating this, or can spot the problem?
Many thanks.
NSCalendar provides a much easier way to do this:
NSDate *birthday = ...; // the birthday
NSDate *today = [NSDate date];
NSCalendar *c = [NSCalendar currentCalendar];
NSInteger birthdayDayOfYear = [c ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:birthday];
NSInteger todayDayOfYear = [c ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:today];
NSInteger different = birthdayDayOfYear - todayDayOfYear;
Basically, we're figuring out how far into the year today and the target date are (ie, today [5 Jun] is the 156th day of the year), and then subtract them to figure out how many days are in between them.
This method, of course, relies on the assumption that the target date is in the same year as the current date. I think it'd be fairly easy to work around that, however.
Another, even easier way to do this that will account for multi-year differences is like this:
NSDateComponents *d = [[NSCalendar currentCalendar] components:NSDayCalendarUnit fromDate:today toDate:birthday options:0];
NSInteger difference = [d day];
If you need to make sure that the birthday is in the future, that's easily accomplished as well:
NSDateComponents *year = [[[NSDateComponents alloc] init] autorelease];
NSInteger yearDiff = 1;
NSDate *newBirthday = birthday;
while([newBirthday earlierDate:today] == newBirthday) {
[year setYear:yearDiff++];
newBirthday = [[NSCalendar currentCalendar] dateByAddingComponents:year toDate:birthday options:0];
}
//continue on with the 2-line calculation above, using "newBirthday" instead.
update I updated the loop above to always increment from the original date n years at a time, instead of year-by-year. If someone is born on 29 Feb, incrementing by one year would yield 1 Mar, which would be wrong once you got to a leap year again. By jumping from the original date each time, we don't have this issue.
I do the exact same thing in one of my apps. Here is how I do it:
//This is the date your going to - in your case the birthday - note the format
NSString *myDateAsAStringValue = #"20110605";
// Convert string to date object
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyyMMdd"];
NSDate *newDate = [dateFormat dateFromString:myDateAsAStringValue];
NSDateComponents *dateComp = [[NSDateComponents alloc] init];
NSCalendar *Calander = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps=[[NSDateComponents alloc] init];
unsigned int unitFlags = NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
dateComp = [Calander components:unitFlags fromDate:[NSDate date]];
[dateFormat setDateFormat:#"dd"];
[comps setDay:[[dateFormat stringFromDate:[NSDate date]] intValue]];
[dateFormat setDateFormat:#"MM"];
[comps setMonth:[[dateFormat stringFromDate:[NSDate date]] intValue]];
[dateFormat setDateFormat:#"yyyy"];
[comps setYear:[[dateFormat stringFromDate:[NSDate date]] intValue]];
[dateFormat setDateFormat:#"HH"];
[comps setHour:05];
[dateFormat setDateFormat:#"mm"];
[comps setMinute:30];
NSDate *currentDate=[Calander dateFromComponents:comps];
dateComp = [Calander components:unitFlags fromDate:newDate];
[dateFormat setDateFormat:#"dd"];
[comps setDay:[[dateFormat stringFromDate:newDate] intValue]];
[dateFormat setDateFormat:#"MM"];
[comps setMonth:[[dateFormat stringFromDate:newDate] intValue]];
[dateFormat setDateFormat:#"yyyy"];
[comps setYear:[[dateFormat stringFromDate:newDate] intValue]];
[dateFormat setDateFormat:#"HH"];
[comps setHour:05];
[dateFormat setDateFormat:#"mm"];
[comps setMinute:30];
NSDate *reminderDate=[Calander dateFromComponents:comps];
NSTimeInterval ti = [reminderDate timeIntervalSinceDate:currentDate];
int days = ti/86400;
return days;
I think I have found a solution. Checking the output carefully, it appears to all come down to the difference in HOURS. For example: comparing today with tomorrow's date might end up being, say, 18 hours away. This results in [difference day] being set at 0 i.e. it thinks tomorrow is today because it is less than 24 hours away.
You can see the fix below. I take the number of hours e.g. 18 and divide by 24 (to get the number of days). In this case 18/24 = 0.75. I then round this up i.e. to "1." So while [difference days] thinks tomorrow is today, by rounding up the hours, you know it is in fact tomorrow.
-(int) daysTillBirthday: (NSDate*)aDate {
// check to see if valid date was passed in
//NSLog(#"aDate passed in is %#",aDate);
if (aDate == nil) {
//NSLog(#"aDate is NULL");
return -1; // return a negative so won't be picked in table
}
//** HOW MANY DAYS TO BDAY
NSDate *birthDay = aDate; // [calendar dateFromComponents:myBirthDay];
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *thisYearComponents = [calendar components:NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit fromDate:[NSDate date]];
NSDateComponents *birthDayComponents = [calendar components:NSMonthCalendarUnit|NSDayCalendarUnit fromDate:birthDay];
NSInteger timeNow = [thisYearComponents hour];
[birthDayComponents setYear:[thisYearComponents year]];
[birthDayComponents setHour:timeNow];
NSDate *birthDayThisYear = [calendar dateFromComponents:birthDayComponents];
//NSLog(#"today %#, birthday %#",[NSDate date],birthDayThisYear);
NSDateComponents *difference = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
NSDateComponents *differenceHours = [calendar components:NSHourCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
double daysFromHours = ((double)[differenceHours hour])/24; // calculate number of days from hours (and round up)
int roundedDaysFromHours = ceil(daysFromHours);
NSLog(#"daysFromHours %.02f, roundedDaysFromHours %i",daysFromHours,roundedDaysFromHours);
if ([difference day] < 0) {
// this years birthday is already over. calculate distance to next years birthday
[birthDayComponents setYear:[thisYearComponents year]+1];
birthDayThisYear = [calendar dateFromComponents:birthDayComponents];
difference = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
}
//NSLog(#"%i days until birthday", [difference day]);
return (roundedDaysFromHours);
[calendar release];
}
I am sorry, as this question may have been asked before, but I could not find an answer that worked in my situation.
I am new to Objective-C, and I am not entirely knowledgable, so I apologize beforehand in the case that I seem like I am not amazing ;)
So, I have a webView, and everyday, the url changes. Ex: on April 30th the url is http://example.com/mylinkApr30
Using dates, I made a variable (sorry if my terminology is off :\ ), and the url ends in %d everything works just fine, except when it comes to month. The months are not in the typical MM form, they are in a shortened text, with the three first letters of the month name. Ex: Jan, Feb, Mar, Apr, etc.
I have the month integer working, and it writes as 1,2,3 etc.
How should I go about changing that to Jan, Feb, Mar?
Is there a different way I could go about this??
I can confirm the days are working, I have tested it with having 1 variable, and using Apr at the end of the link.
Here is my code, so it is easier for you to understand what I am asking.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"Balmoral";
NSCalendar *calendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |
NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit |
NSSecondCalendarUnit;
NSDate *date = [NSDate date];
NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:date];
//NSInteger year = [dateComponents year];
NSInteger month = [dateComponents month];
NSInteger day = [dateComponents day];
//NSInteger hour = [dateComponents hour];
//NSInteger minute = [dateComponents minute];
//NSInteger second = [dateComponents second];
NSString *baseURLStr = #"http://wwww.WebsiteHere.com/Apr";
NSURL *url = [NSURL URLWithString:[baseURLStr stringByAppendingFormat:#"%d.ashx", day]];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
[NSCalendar release];
}
Check out the NSDateFormatter class, something like:
int month = 3;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM"];
NSDate *date = [formatter dateFromString:[NSString stringWithFormat:#"%02i", month]];
[formatter setDateFormat:#"MMM"];
NSString *monthString = [formatter stringFromDate:date];
NSLog(#"MONTH STRING %#", monthString);
monthString should be "Mar"
A simple, and likely naive, approach would be to have an array with the text you want:
NSArray *months = [NSArray arrayWithObjects:#"Jan", #"Feb", nil];
This would allow you to get the string by:
NSString *monthString = [months objectAtIndex:month];
,Since you are not using the standard MM format you cannot use NSDateFormatter. You need a switch for all 12 months.
NSString * monthString = nil;
switch (month)
{
case 1:
monthString = #"Jan";
break;
case 2:
...
}
Then modify your own code:
NSString *baseURLStr = #"http://wwww.WebsiteHere.com/";
NSURL *url = [NSURL URLWithString:[baseURLStr stringByAppendingFormat:#"%#%d.ashx", monthString, day]];
EDIT:
Ryan is right. his solution is better.