NSDate countdown from NOW to NSDate - objective-c

How can I show a countdown in HH:mm:ss format from NOW to a desired NSDate that will happen in the future?

Start at the documentation.
NSDate *future = // whatever
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
- (void)updateCounter:(NSTimer *)tmr
{
NSTimeInterval iv = [future timeIntervalSinceNow];
int h = iv / 3600;
int m = (iv - h * 3600) / 60;
int s = iv - h * 3600 - m * 60;
aUILabel.text = [NSString stringWithFormat:#"%02d:%02d:%02d", h, m, s];
if (h + m + s <= 0) {
[tmr invalidate];
}
}

You have to use a timer for ticking the date.
Store a future date, and keep on substracting future date - [nsdate today]...
Calculate the time in seconds and calculate it into Hours, minutes, seconds...
//Make two properties NSDate *nowDate, *futureDate
futureDate=...;
nowDate=[NSDate date];
long elapsedSeconds=[nowDate timeIntervalSinceDate:futureDate];
NSLog(#"Elaped seconds:%ld seconds",elapsedSeconds);
NSInteger seconds = elapsedSeconds % 60;
NSInteger minutes = (elapsedSeconds / 60) % 60;
NSInteger hours = elapsedSeconds / (60 * 60);
NSString *result= [NSString stringWithFormat:#"%02ld:%02ld:%02ld", hours, minutes, seconds];
This will come handy for you...kindly check the project...

Give this code a shot:
NSTimer* timer= [NSTimer scheduledTimerWithInterval: [self.futureDate timeIntervalSinceNow] target: self selector: #selector(countdown:) userInfo: nil, repeats: YES];
The countdown: method:
- (void) countdown: (NSTimer*) timer
{
if( [self.futureDate timeIntervalSinceNow] <= 0)
{
[timer invalidate];
return;
}
NSDateComponents* comp= [ [NSCalendar currentCalendar] components: NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit startingDate: [NSDate date] toDate: self.futureDate options: 0];
NSLog(#"%lu:%lu:%lu", comp.hour,comp.minute.comp.second);
}

Related

NSTimer not working accurately.

I am trying to make a countdown timer, however I am struggling with my code. I have a UIDatePicker to select the date to countdown to, but ever every time I try to do a countdown the seconds start at 54 seconds instead of adjusting to the actual time of the device. The code is very simple and straightforward, but I am struggling to figure it out.
- (IBAction)startCountdown:(id)sender {
if (ti == 0||ti <= 0) {
[self stopCountdown:self];
}
//Set up a timer that calls the updateTime method every second to update the label
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(updateTime)
userInfo:nil
repeats:YES];
}
-(void)updateTime{
//Get the time left until the specified date and convert time into seconds.
NSInteger ti = ((NSInteger)[self.datePicker.date timeIntervalSinceNow]); //this is the key part of the code.
NSInteger seconds = ti % 60;
NSInteger minutes = (ti / 60) % 60;
NSInteger hours = (ti / 3600) % 24;
//NSInteger days = (ti / 86400);
//Update the lable with the remaining time
//self.countdownLabel.text = [NSString stringWithFormat:#"%02i days %02i hrs %02i min %02i sec", days, hours, minutes, seconds];
self.countdownLabel.text = [NSString stringWithFormat:#"%02i hrs %02i min %02i sec", hours, minutes, seconds];
}
Please help me out it would be much appreciated!
Thank you in advance friends!!
There is more easy way to extract time units that can prevent errors in calculations. Take a look at [NSCalendar components:fromDate:toDate:options:]
It may become:
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit components = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *diff = [calendar components:components fromDate:self.datePicker.date toDate:now options:0];
NSInteger seconds = [diff second];
NSInteger minutes = [diff minute];
NSInteger hours = [diff hour];

Objective-c stringWithFormat Timer [duplicate]

This question already has answers here:
iOS Format String into minutes and seconds
(7 answers)
Closed 8 years ago.
I am trying to get a timer to show the counter like this "00:00:00". Here is my current code. I have been trying to get it to work using the stringWithFormat which should be easy but I guess I will have to set up the formats separately. Do you guys have any idea on how to do this?
- (void)TimerCount {
CountNumber = CountNumber + 1;
TimerDisplay.text = [NSString stringWithFormat:#"Hour: %0*i", length, hour];
}
- (void)timerCount {
{
CountNumber = CountNumber + 1;
NSInteger seconds = CountNumber % 60;
NSInteger minutes = (CountNumber / 60) % 60;
NSInteger hours = (CountNumber / 3600);
TimerDisplay.text = [NSString stringWithFormat:#"%i:%02i:%02i", hours, minutes, seconds];
}
Try the above code.
And configure this method to be fired every second.
In viewDidLoad
NSTimer *counterTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timerCount)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer: counterTimer forMode:NSRunLoopCommonModes];
And keep the counterTimer as an iVar to keep it alive until the VC is dealloced, if you are using ARC.
- (void)TimerCount
{
CountNumber++;
NSString *time = [[NSString alloc] init];
NSUInteger seconds = CountNumber;
NSUInteger minutes = 0;
NSUInteger hours = 0;
if (seconds > 59) {
seconds -= 60;
minutes++;
if (seconds < 10) {
time = [NSString stringWithFormat:#":0%i",seconds];
} else time = [NSString stringWithFormat:#":%i",seconds];
}
if (minutes > 59) {
minutes -= 60;
hours++;
if (minutes < 10) {
time = [NSString stringWithFormat:#":0%i%#",minutes,time];
} else time = [NSString stringWithFormat:#":%i%#",minutes,time];
}
if (hours < 10) {
time = [NSString stringWithFormat:#"0%i%#",hours,time];
} else time = [NSString stringWithFormat:#"%i%#",hours,time];
}
NSString *time is the time.
Also NSTimer to call this method every second:
NSTimer *counterTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timerCount)
userInfo:nil
repeats:YES];

How to update UILabel frequently?

I want to update text for label frequently but it seems not working.
for (int i = 0; i <100; i++)
{
mylabel.text =[NSString stringWithFormat:#"%d", i];
}
Does anyone suggest for me an idea ? I thought. Maybe, we should update text label in multiple threads.
Watch is best example hope it will help you....
int second,minute; //set second = 0 and minute = 0
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
- (void)updateCounter:(NSTimer *)theTimer {
second++;
if(second < 60)
{
if (second < 10)
{
timerLbl.text = [NSString stringWithFormat:#"00:0%d", second];
}
else
{
timerLbl.text = [NSString stringWithFormat:#"00:%d",second];
}
}
else
{
minute = second / 60;
int sec = second % 60;
if (minute < 10 && sec < 10)
{
timerLbl.text = [NSString stringWithFormat:#"0%d:0%d", minute, sec];
}
if(minute < 10 && sec >= 10)
{
timerLbl.text = [NSString stringWithFormat:#"0%d:%d", minute, sec];
}
if (minute >= 10 && sec < 10)
{
timerLbl.text = [NSString stringWithFormat:#"%d:0%d", minute, sec];
}
if(minute >= 10 && sec >= 10)
{
timerLbl.text = [NSString stringWithFormat:#"%d:%d", minute, sec];
}
}
}
Add below code in viewDidLoad
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5f
target:self
selector:#selector(showTime)
userInfo:NULL
repeats:YES];
- (void)showTime
{
NSDate *now=[NSDate date];
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:#"HH:mm:ss"];
timeLabel.text=[dateFormatter stringFromDate:now];
}
Hope this answer will help you....
use NSTimer for the regular interval and call the method where the lable is printed let suppose
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(targetMethod:)
userInfo:nil
repeats:Yes];
in the target method print the label on text
-(void)targetMethod:(NSTimer *)timer{
NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#" HH:MM:SS"];
NSString* str = [formatter stringFromDate:date];
label.text = str;
}
try this it will work surely

countdown timer with minutes and seconds

i create a countdown timer that go from 10 to 0. i create a uilabel that shows the counter in seconds. now i want the label to show the counter minutes and second, like that: 00:00.
how can i do that?
here is my countdowncode:
-(void)countdown
{
countdownCounter -= 1;
countdown.text = [NSString stringWithFormat:#"%i", countdownCounter];
}
-(IBAction)strat:(id)sender
{
countdownCounter = 10;
countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countdown) userInfo:nil repeats:YES];
}
}
thanks!
This can be done using one time, and one label. Try using the following code:
int seconds = [countDown.text intValue] % 60;
int minutes = ([countDown.text intValue] / 60) % 60;
countDown.text = [NSString stringWithFormat:#"%2d:%02d", minutes, seconds];
Do it exactly the same way, just add another timer.
countdownTimer2 = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:#selector(countdown2) userInfo:nil repeats:YES];
-(void)countdown2
{
countdownCounterMinutes -= 1;
}
and change countdown to
-(void)countdown
{
countdownCounter -= 1;
countdown.text = [NSString stringWithFormat:#"%i%i", countdownCounterMinutes, countdownCounter];
}
for anyone who what the answer in the end i do it this way:
-(IBAction)start
{
timer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(updateTimer:) userInfo:nil repeats:YES];
}
-(void)updateTimer:(NSTimer *)timer {
currentTime -= 10 ;
[self populateLabelwithTime:currentTime];
if(currentTime <=0)
[timer invalidate];
}
- (void)populateLabelwithTime:(int)milliseconds {
seconds = milliseconds/1000;
minutes = seconds / 60;
hours = minutes / 60;
seconds -= minutes * 60;
minutes -= hours * 60;
NSString * result1 = [NSString stringWithFormat:#"%#%02d:%02d:%02d:%02d", (milliseconds<0?#"-":#""), hours, minutes, seconds,milliseconds%1000];
result.text = result1;
}
in viewDidLoad i set currentTime for the countdown time in milliseconds.
hope you understand...
I formatted the numbers (from float)with mins and seconds
it this way, thanks your answers helped. (hope this helps another)
- (void)ticTimer
{
self.current -= self.updateSpeed;
CGFloat progress = self.current / self.max;
[self populateLabelwithTimeFormatted:self.current];
/// TimeLabelNode.text = [NSString stringWithFormat:#"%f", progress];
// * Time is over
if (self.current <= self.min) {
[self stop];
_TimeLabelNode.text= #"time up!";
}
}
- (void)populateLabelwithTimeFormatted:(float)time {
//convert float into mins and seconds format
int mytime = (int) _current;
int seconds = mytime%60;
int minutes = mytime / 60 % 60;
NSString * result1 = [NSString stringWithFormat:#"%2d:%02d", minutes, seconds];
_TimeLabelNode.text = result1;
}

How do I pause a stopwatch, then have it pick back up from where it started?

I am designing a timer that I want to be able to pause and continue from the same place. I tried doing it but the code wouldn't work for me. Here is my code:
.m file:
-(IBAction)buttonPause:(id)sender {
NSString *dateString = timer.text;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SS"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
dateFromString = startDate;
}
- (IBAction)buttonStart:(id)sender {
startDate = [NSDate date];
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/100.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
- (void)updateTimer{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
timer.text = timeString;
}
My problem appears to lie in the buttonPause method. What am I doing wrong or am not doing? Thank you in advanced.
You can use NSTimeInterval instead of timer. I have a functional code to pause and stop the timer.
#interface PerformBenchmarksViewController () {
int currMinute;
int currSecond;
int currHour;
int mins;
NSDate *startDate;
NSTimeInterval secondsAlreadyRun;
}
#end
- (void)viewDidLoad
{
[super viewDidLoad];
running = false;
}
- (IBAction)StartTimer:(id)sender {
if(running == false) {
//start timer
running = true;
startDate = [[NSDate alloc] init];
startTime = [NSDate timeIntervalSinceReferenceDate];
[sender setTitle:#"Pause" forState:UIControlStateNormal];
[self updateTime];
}
else {
//pause timer
secondsAlreadyRun += [[NSDate date] timeIntervalSinceDate:startDate];
startDate = [[NSDate alloc] init];
[sender setTitle:#"Start" forState:UIControlStateNormal];
running = false;
}
}
- (void)updateTime {
if(running == false) return;
//calculate elapsed time
NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval elapsed = secondsAlreadyRun + currentTime - startTime;
// extract out the minutes, seconds, and hours of seconds from elapsed time:
int hours = (int)(mins / 60.0);
elapsed -= hours * 60;
mins = (int)(elapsed / 60.0);
elapsed -= mins * 60;
int secs = (int) (elapsed);
//update our lable using the format of 00:00:00
timerLabel.text = [NSString stringWithFormat:#"%02u:%02u:%02u", hours, mins, secs];
//call uptadeTime again after 1 second
[self performSelector:#selector(updateTime) withObject:self afterDelay:1];
}
Hope this will help. Thanks