Issue in count down days hours minutes from NSDate - iphone

I am struggling with updating UILabel for count down for that I use following code
- (void)updateLabel {
// convert date string to date then set to a label
NSDateFormatter *dateStringParser = [[NSDateFormatter alloc] init];
[dateStringParser setDateFormat:#"MM/dd/yyyy"];
NSLog(#"date from update label %#", _selectedBirthdate);
//OUTPUT date from update label 07/23/2013
NSDate *date = [dateStringParser dateFromString:_selectedBirthdate];
NSLog(#"date from update label %#", date);
NSTimeInterval timeInterval = [date timeIntervalSinceNow]; ///< Assuming this is in the future for now.
NSString *stringVariable = [self stringFromTimeInterval:timeInterval];
self.dayLable.text = [NSString stringWithFormat:#"%#", stringVariable];
self.hourLable.text = [NSString stringWithFormat:#"%#", stringVariable];
self.minutesLable.text = [NSString stringWithFormat:#"%#", stringVariable];
// i want to update this day hour minutes lable like this much of days hour and minutes remaining
NSLog(#"%#",stringVariable);
}
I use following method for counting days hours and minutes but I dont know whats the logic mind is not working here how to find days hours and minutes from interval
- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {
NSInteger ti = (NSInteger)interval;
NSLog(#"%d",ti);
// NSInteger seconds = ti % 60;
NSInteger days = (ti * 60);
NSInteger minutes = (ti / 60) % 60;
NSLog(#"%d",minutes);
NSInteger hours = (ti / 3600);
NSLog(#"%d",hours);
return [NSString stringWithFormat:#"%02i hours : %02i min", hours, minutes];
}

To count no. of days, months and years, apply below code.
double differenceSeconds;
double datediff;
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"YYYY-MM-dd HH:mm:ss ZZZ"];
[df setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *todayDate = [NSDate date];
long long tdate =[todayDate timeIntervalSince1970];
datediff = tdate - yourdate;
int days=(int)((double)datediff/(3600.0*24.00));
int diffDay=datediff-(days*3600*24);
int diffhours=(int)((double)diffDay/3600.00);
int diffMin=diffDay-(diffhours*3600);
int diffminutes=(int)(diffMin/60.0);

Related

How to Convert NSString into NSTimeInterval

I have NSString that has value "22/04/2013 05:56", as per the requirement I just want to calculate this time and date and show some condition based messages.
First condition:
If (String date = current date and stringtime = current time)||(string date = current date and string time < 1 minute from current time)
Second condition: If (String date = current date and stringtime > current time by how many minutes or hour)
Third Condition: To know is string date is yesterday.
Fourth Condition: To Know is string date is day before yesterday.
I am receiving this string from server. How can I achieve above things with this "22/04/2013 05:56" string.
You need to take 2 step:
convert string to NSDate
convert date to timeStamp
like below:
- (void) dateConverter{
NSString *string = #"22/04/2013 05:56";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// this is imporant - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter setDateFormat:#"dd/MM/yyyy hh:mm"];
NSDate *date = [[NSDate alloc] init];
// voila!
date = [dateFormatter dateFromString:string];
NSLog(#"dateFromString = %#", date);
//date to timestamp
NSTimeInterval timeInterval = [date timeIntervalSince1970];
}
Then to achieve something like time ago following method will help, although it's not totally for you bu i believe you can modify it to help you!
- (NSString *) timeAgoFor : (NSDate *) date {
double ti = [date timeIntervalSinceDate:[NSDate date]];
ti = ti * -1;
if (ti < 86400) {//86400 = seconds in one day
return[NSString stringWithFormat:#"Today"];
} else if (ti < 86400 * 2) {
return[NSString stringWithFormat:#"Yesterday"];
}else if (ti < 86400 * 7) {
int diff = round(ti / 60 / 60 / 24);
return[NSString stringWithFormat:#"%d days ago", diff];
}else {
int diff = round(ti / (86400 * 7));
return[NSString stringWithFormat:#"%d wks ago", diff];
}
}
From string using dateformatter convert it to date.Then you have to compare the dates and get the value
NSString *str=#"22/04/2013 05:56";
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"dd/MM/YYYY hh:mm"];
NSDate *dateObj= [dateFormatter dateFromString:str];
NSLog(#"%#",dateObj);

How i can take the differece between two timings in iphone?

I have an application in which i need to show a label in the tableview as Xseconds ago and xminutes&yseconds ago,X hrs ago like that.i am doing like this `
NSString *todaysdateString=[dict objectForKey:#"sendingtime"];
NSString *time = todaysdateString;
NSString*todaysdateString1=[NSString stringWithString: #" "];
NSDate *date1;
NSDate *date2;
//{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"HH:mm:ss"];
date1 = [formatter dateFromString:time];
date2 = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]];
[formatter release];
//}
NSTimeInterval interval = [date1 timeIntervalSinceDate: date2];
float seconds = interval;
float hour = interval / 3600;
float minute =(interval - hour*3600) / 60;
NSLog(#"%02.0f,%02.0f,%02.0f",hour, minute, seconds);
`But this wont giving me the desired answers,I am getting like -0,00,-297 that is utterly wrong.Can anybody point me in where i am going wrong..
Use a NSCalendar to do this, maybe this code helps you
NSCalendar *c = [NSCalendar currentCalendar];
NSDateComponents *components = [c components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit
fromDate:initialDate
toDate:endDate
options:0];
and in the components variables you will have the differences, get it back using: components.day, components.minute and components.second
As your seconds is in negative, you should swap your date here
NSTimeInterval interval = [date1 timeIntervalSinceDate: date2];
to :
NSTimeInterval interval = [date2 timeIntervalSinceDate: date1];
And can do as :
NSInteger intervalInt=interval;
NSInteger seconds = intervalInt % 60;
NSInteger minutes = (intervalInt / 60) % 60;
NSInteger hours = intervalInt / (60 * 60);
NSString *result = [NSString stringWithFormat:#"%02ld:%02ld:%02ld", hours, minutes, seconds];

NSDate countdown with NSInterval

Here's my code:
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSString *currentTime = [dateFormatter stringFromDate:currDate];
NSDate *now = [NSDate date];
int interval = 1*60; // one minute (minutes*60)
long int nowSeconds = (long int) [now timeIntervalSince1970];
int secondsLeft = interval - (nowSeconds % interval);
NSDate *nextIntervalDate = [NSDate dateWithTimeIntervalSince1970:nowSeconds+secondsLeft];
NSString *nextTrigger = [dateFormatter stringFromDate:nextIntervalDate];
timeRemaining.text = [NSString stringWithFormat:#"%02d:%02d", secondsLeft/60, secondsLeft%60];
NSLog([NSString stringWithFormat:#"%#:%#", currentTime, nextTrigger]);
if ([currentTime isEqualToString:nextTrigger]) {
}
Problem is, 'if ([currentTime isEqualToString:nextTrigger])' is never equal. Because nextTrigger changes to the next time segment before they're equal. Here is the NSLog:
2013-01-17 15:54:59.987 app[35987:c07] 15:54:59:15:55:00
2013-01-17 15:54:59.997 app[35987:c07] 15:54:59:15:55:00
2013-01-17 15:55:00.007 app[35987:c07] 15:55:00:15:56:00 <----RIGHT HERE
2013-01-17 15:55:00.016 app[35987:c07] 15:55:00:15:56:00
My code's nextTrigger is basically a round up of the current time by the nearest minute. ALSO, this whole code segment is in a repeating NSTimer every .1 seconds.
How can I fix this?
If you have code that you'd like triggered when the next whole minute passes, it's inefficient to repeatedly check to see if said time has passed. Put that code in its own method, and create a single NSTimer to trigger it at the appropriate time.
NSDate* date = [NSDate date] ;
NSCalendar* calendar = [NSCalendar currentCalendar] ;
NSDateComponents* secondsComponents = [calendar components:NSSecondCalendarUnit fromDate:date] ;
NSTimeInterval secondsUntilNextWholeMinute = 60 - secondsComponents.second ;
[NSTimer scheduledTimerWithTimeInterval:secondsUntilNextWholeMinute target:self selector:#selector(yourMethod) userInfo:nil repeats:NO ] ;
I had a somewhat similar problem. What I did was make a copy and check it by that.(one thing is to have both oldTrigger and newTrigger declared already)Check this code
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSString *currentTime = [dateFormatter stringFromDate:currDate];
NSDate *now = [NSDate date];
int interval = 1*60; // one minute (minutes*60)
long int nowSeconds = (long int) [now timeIntervalSince1970];
int secondsLeft = interval - (nowSeconds % interval);
NSDate *nextIntervalDate = [NSDate dateWithTimeIntervalSince1970:nowSeconds+secondsLeft];
oldTrigger = nextTrigger;
nextTrigger = [dateFormatter stringFromDate:nextIntervalDate];
timeRemaining.text = [NSString stringWithFormat:#"%02d:%02d", secondsLeft/60, secondsLeft%60];
NSLog([NSString stringWithFormat:#"%#:%#", currentTime, nextTrigger]);
if ([currentTime isEqualToString:oldTrigger]) {
}

get time between two times of the day

I've already tried with NSDate but with no luck.
I want the difference between for example 14:10 and 18:30.
Hours and minutes.
I Hope you can help me shouldn't be that complicated :)
There's no need to calculate this by hand, take a look at NSCalendar. If you want to get the hours and minutes between two dates, use something like this:
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit;
NSDateComponents *components = [gregorianCalendar components:unitFlags
fromDate:firstDate
toDate:otherDate
options:0];
[gregorianCalendar release];
You now have the hours and minutes as NSDateComponents and can access them as NSIntegers like [components hour] and [components minute]. This will also work for hours between days, leap years and other fun stuff.
Here's my quick solution:
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
[df setDateFormat:#"HH:mm"];
NSDate *date1 = [df dateFromString:#"14:10"];
NSDate *date2 = [df dateFromString:#"18:09"];
NSTimeInterval interval = [date2 timeIntervalSinceDate:date1];
int hours = (int)interval / 3600; // integer division to get the hours part
int minutes = (interval - (hours*3600)) / 60; // interval minus hours part (in seconds) divided by 60 yields minutes
NSString *timeDiff = [NSString stringWithFormat:#"%d:%02d", hours, minutes];
The NSDate class has a method timeIntervalSinceDate that does the trick.
NSTimeInterval secondsBetween = [firstDate timeIntervalSinceDate:secondDate];
NSTimeInterval is a double that represents the seconds between the two times.
NSString *duration = [self calculateDuration:oldTime secondDate:currentTime];
- (NSString *)calculateDuration:(NSDate *)oldTime secondDate:(NSDate *)currentTime
{
NSDate *date1 = oldTime;
NSDate *date2 = currentTime;
NSTimeInterval secondsBetween = [date2 timeIntervalSinceDate:date1];
int hh = secondsBetween / (60*60);
double rem = fmod(secondsBetween, (60*60));
int mm = rem / 60;
rem = fmod(rem, 60);
int ss = rem;
NSString *str = [NSString stringWithFormat:#"%02d:%02d:%02d",hh,mm,ss];
return str;
}

How do I break down an NSTimeInterval into year, months, days, hours, minutes and seconds on iPhone?

I have a time interval that spans years and I want all the time components from year down to seconds.
My first thought is to integer divide the time interval by seconds in a year, subtract that from a running total of seconds, divide that by seconds in a month, subtract that from the running total and so on.
That just seems convoluted and I've read that whenever you are doing something that looks convoluted, there is probably a built-in method.
Is there?
I integrated Alex's 2nd method into my code.
It's in a method called by a UIDatePicker in my interface.
NSDate *now = [NSDate date];
NSDate *then = self.datePicker.date;
NSTimeInterval howLong = [now timeIntervalSinceDate:then];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:howLong];
NSString *dateStr = [date description];
const char *dateStrPtr = [dateStr UTF8String];
int year, month, day, hour, minute, sec;
sscanf(dateStrPtr, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &sec);
year -= 1970;
NSLog(#"%d years\n%d months\n%d days\n%d hours\n%d minutes\n%d seconds", year, month, day, hour, minute, sec);
When I set the date picker to a date 1 year and 1 day in the past, I get:
1 years 1 months 1 days 16 hours 0
minutes 20 seconds
which is 1 month and 16 hours off. If I set the date picker to 1 day in the past, I am off by the same amount.
Update: I have an app that calculates your age in years, given your birthday (set from a UIDatePicker), yet it was often off. This proves there was an inaccuracy, but I can't figure out where it comes from, can you?
Brief Description
Just another approach to complete the answer of JBRWilkinson but adding some code. It can also offers a solution to Alex Reynolds's comment.
Use NSCalendar method:
(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts
"Returns, as an NSDateComponents object using specified components, the difference between two supplied dates". (From the API documentation).
Create 2 NSDate whose difference is the NSTimeInterval you want to break down. (If your NSTimeInterval comes from comparing 2 NSDate you don't need to do this step, and you don't even need the NSTimeInterval, just apply the dates to the NSCalendar method).
Get your quotes from NSDateComponents
Sample Code
// The time interval
NSTimeInterval theTimeInterval = ...;
// Get the system calendar
NSCalendar *sysCalendar = [NSCalendar currentCalendar];
// Create the NSDates
NSDate *date1 = [[NSDate alloc] init];
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:theTimeInterval sinceDate:date1];
// Get conversion to months, days, hours, minutes
NSCalendarUnit unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit;
NSDateComponents *breakdownInfo = [sysCalendar components:unitFlags fromDate:date1 toDate:date2 options:0];
NSLog(#"Break down: %i min : %i hours : %i days : %i months", [breakdownInfo minute], [breakdownInfo hour], [breakdownInfo day], [breakdownInfo month]);
This code is aware of day light saving times and other possible nasty things.
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components: (NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit )
fromDate:startDate
toDate:[NSDate date]
options:0];
NSLog(#"%ld", [components year]);
NSLog(#"%ld", [components month]);
NSLog(#"%ld", [components day]);
NSLog(#"%ld", [components hour]);
NSLog(#"%ld", [components minute]);
NSLog(#"%ld", [components second]);
From iOS8 and above you can use NSDateComponentsFormatter
It has methods to convert time difference in user friendly formatted string.
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
NSLog(#"%#", [formatter stringFromTimeInterval:1623452]);
This gives the output - 2 weeks, 4 days, 18 hours, 57 minutes, 32 seconds
Convert your interval into an NSDate using +dateWithIntervalSince1970, get the date components out of that using NSCalendar's -componentsFromDate method.
SDK Reference
This works for me:
float *lenghInSeconds = 2345.234513;
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:lenghInSeconds];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
[formatter setDateFormat:#"HH:mm:ss"];
NSLog(#"%#", [formatter stringFromDate:date]);
[formatter release];
The main difference here is that you need to adjust for the timezone.
Or there is my class method. It doesn't handle years, but that could easily be addedn though it's better for small timelaps like days, hours and minutes. It take plurals into account and only shows what's needed:
+(NSString *)TimeRemainingUntilDate:(NSDate *)date {
NSTimeInterval interval = [date timeIntervalSinceNow];
NSString * timeRemaining = nil;
if (interval > 0) {
div_t d = div(interval, 86400);
int day = d.quot;
div_t h = div(d.rem, 3600);
int hour = h.quot;
div_t m = div(h.rem, 60);
int min = m.quot;
NSString * nbday = nil;
if(day > 1)
nbday = #"days";
else if(day == 1)
nbday = #"day";
else
nbday = #"";
NSString * nbhour = nil;
if(hour > 1)
nbhour = #"hours";
else if (hour == 1)
nbhour = #"hour";
else
nbhour = #"";
NSString * nbmin = nil;
if(min > 1)
nbmin = #"mins";
else
nbmin = #"min";
timeRemaining = [NSString stringWithFormat:#"%#%# %#%# %#%#",day ? [NSNumber numberWithInt:day] : #"",nbday,hour ? [NSNumber numberWithInt:hour] : #"",nbhour,min ? [NSNumber numberWithInt:min] : #"00",nbmin];
}
else
timeRemaining = #"Over";
return timeRemaining;
}
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
// format: YYYY-MM-DD HH:MM:SS ±HHMM
NSString *dateStr = [date description];
NSRange range;
// year
range.location = 0;
range.length = 4;
NSString *yearStr = [dateStr substringWithRange:range];
int year = [yearStr intValue] - 1970;
// month
range.location = 5;
range.length = 2;
NSString *monthStr = [dateStr substringWithRange:range];
int month = [monthStr intValue];
// day, etc.
...
- (NSString *)convertTimeFromSeconds:(NSString *)seconds {
// Return variable.
NSString *result = #"";
// Int variables for calculation.
int secs = [seconds intValue];
int tempHour = 0;
int tempMinute = 0;
int tempSecond = 0;
NSString *hour = #"";
NSString *minute = #"";
NSString *second = #"";
// Convert the seconds to hours, minutes and seconds.
tempHour = secs / 3600;
tempMinute = secs / 60 - tempHour * 60;
tempSecond = secs - (tempHour * 3600 + tempMinute * 60);
hour = [[NSNumber numberWithInt:tempHour] stringValue];
minute = [[NSNumber numberWithInt:tempMinute] stringValue];
second = [[NSNumber numberWithInt:tempSecond] stringValue];
// Make time look like 00:00:00 and not 0:0:0
if (tempHour < 10) {
hour = [#"0" stringByAppendingString:hour];
}
if (tempMinute < 10) {
minute = [#"0" stringByAppendingString:minute];
}
if (tempSecond < 10) {
second = [#"0" stringByAppendingString:second];
}
if (tempHour == 0) {
NSLog(#"Result of Time Conversion: %#:%#", minute, second);
result = [NSString stringWithFormat:#"%#:%#", minute, second];
} else {
NSLog(#"Result of Time Conversion: %#:%#:%#", hour, minute, second);
result = [NSString stringWithFormat:#"%#:%#:%#",hour, minute, second];
}
return result;
}
Here's another possibility, somewhat cleaner:
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSString *dateStr = [date description];
const char *dateStrPtr = [dateStr UTF8String];
// format: YYYY-MM-DD HH:MM:SS ±HHMM
int year, month, day, hour, minutes, seconds;
sscanf(dateStrPtr, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minutes, &seconds);
year -= 1970;