I need the iPhone to recognize the current time (which I can do fine with NSDate) and have it countdown to the next time interval, say every half hour on the half hour. Example: if the current time is 2:12:30 and the interval is every half hour, I want a countdown to start at 17:30 (17 min 30 seconds left) and go to 0.
Code welcome, but also general program design thoughts welcome too. Here's the code I have for starting a countdown and getting the current time:
-(void)updateCounter:(NSTimer *)theTimer {
if(secondsLeft > 0 ){
secondsLeft -- ;
minutes = (secondsLeft % 3600) / 60;
seconds = (secondsLeft % 3600) % 60;
waitingTimeLabel.text = [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
else{
secondsLeft = 10;
}
}
-(void)countdownTimer{
//secondsLeft = minutes = seconds = 0;
if([timer isValid])
{
[timer release];
}
// NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
//[pool release];
}
-(NSDate *)getCurrentTime
{
NSDate *now = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"mm:ss";
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSLog(#"The Current Time is %#",[dateFormatter stringFromDate:now]);
//[dateFormatter release];
NSString *currentTime = [NSString stringWithFormat:#"%#",[dateFormatter stringFromDate:now]];
currentTimeLabel.text = currentTime;
return now;
}
NSDate *now = [NSDate date];
int interval = 30*60; // half hour
long int nowSeconds = (long int) [now timeIntervalSince1970];
int secondsLeft = interval - (nowSeconds % interval);
NSDate *nextIntervalDate = [NSDate
dateWithTimeIntervalSince1970:nowSeconds+secondsLeft];
NSLog(#"Now is %#", now);
NSLog(#"The next interval point in time is %#", nextIntervalDate);
NSLog(#"That's another %d seconds (or %02d:%02d)",
secondsLeft, secondsLeft/60, secondsLeft%60);
Related
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);
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I want to display count down timer. I have the start date and end date. I need to display the remaining time like
days : hours : minutes : seconds
How can I do this?
you can set coundown like my below code :-
-(void) viewWillAppear:(BOOL)animated
{
timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:#selector(updateCountdown) userInfo:nil repeats: YES];
}
AND
-(void) updateCountdown
{
NSString *dateString = #"14-12-2012";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];
// voila!
dateFromString = [dateFormatter dateFromString:dateString];
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *componentsHours = [calendar components:NSHourCalendarUnit fromDate:now];
NSDateComponents *componentMint = [calendar components:NSMinuteCalendarUnit fromDate:now];
NSDateComponents *componentSec = [calendar components:NSSecondCalendarUnit fromDate:now];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componentsDaysDiff = [gregorianCalendar components:NSDayCalendarUnit
fromDate:now
toDate:dateFromString
options:0];
lblDaysSetting.text=[NSString stringWithFormat:#"%02d",componentsDaysDiff.day];
lblHouresSetting.text=[NSString stringWithFormat:#"%02d",(24-componentsHours.hour)];
lblMinitSetting.text=[NSString stringWithFormat:#"%02d",(60-componentMint.minute)];
lblSecSetting.text=[NSString stringWithFormat:#"%02d",(60-componentSec.second)];
}
now just set your logic
its code output as my project as bellow::-
this is the code for .h file:
#interface UIMyContoller : UIViewController {
NSTimer *timer;
IBOutlet UILabel *myCounterLabel;
}
#property (nonatomic, retain) UILabel *myCounterLabel;
-(void)updateCounter:(NSTimer *)theTimer;
-(void)countdownTimer;
#end
and here is the code for .m file:
#implementation UIMyController
#synthesize myCounterLabel;
int hours, minutes, seconds;
int secondsLeft;
- (void)viewDidLoad {
[super viewDidLoad];
secondsLeft = 16925;
[self countdownTimer];
}
- (void)updateCounter:(NSTimer *)theTimer {
if(secondsLeft > 0 ){
secondsLeft -- ;
hours = secondsLeft / 3600;
minutes = (secondsLeft % 3600) / 60;
seconds = (secondsLeft %3600) % 60;
myCounterLabel.text = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
}
else{
secondsLeft = 16925;
}
}
-(void)countdownTimer{
secondsLeft = hours = minutes = seconds = 0;
if([timer isValid])
{
[timer release];
}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
[pool release];
}
hope this helps. happy coding
adrian
I would recommend the below method of getting time components of From Date to To Date.
This method is more elegant than manually decrementing 3 integer variables for hour, minute and seconds because doing so would mean you have to manually check when a second hit 0, you need to manually reset the minute back to 59 and so on. I went down this route once, it wasn't very good.
Also, when you minimize your app, the count down clock will stop. If you were decrementing your count down timer manually using 3 integers (hour, minute and seconds), minimizing your app will cause the count down to screw up.
Since this method auto calculates the difference between two dates, even when the app returns from the background minimized state, it automatically recalculates the remaining time for you without any extra code.
-(void)viewDidLoad
{
// instantiate a calendar object.
gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
countDownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateClock:) userInfo:nil repeats:YES];
[countDownTimer fire];
}
-(void)updateClock:(NSTimer *)timer
{
countDownDateFormatter = [[NSDateFormatter alloc] init];
[countDownDateFormatter setDateFormat:#"hh:mm:ss"];
NSDate *now = [NSDate date];
NSDateComponents *comp = [gregorianCalendar components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit
fromDate:now
toDate:countDownEndDate
options:0];
NSString *strTimeRemaining = nil;
// if date have not expired
if([now compare:countDownEndDate] == NSOrderedAscending)
{
strTimeRemaining = [[NSString alloc] initWithFormat:#"%02d:%02d:%02d", [comp hour], [comp minute], [comp second]];
}
else
{
// time has expired, set time to 00:00 and set boolean flag to no
strTimeRemaining = [[NSString alloc] initWithString:#"00:00:00"];
[countDownTimer invalidate];
countDownTimer = nil;
}
lblCountDown.text = strTimeRemaining;
[countDownDateFormatter release];
[strTimeRemaining release];
}
i am using below code to calculate remaining time that code working good on Simulator but it gives all zero value to day hours minutes and seconds on iPad device
`NSTimeInterval remainingSec = [databaseDate timeIntervalSinceNow];
if (!timer || remainingSec <= 0) {
[timer invalidate];
timer = nil;
// getting time from database
NSLocale *indianEnglishLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_IN"];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"Asia/Kolkata"];
NSDateFormatter *dateFrmattr = [[NSDateFormatter alloc] init];
[dateFrmattr setLocale:indianEnglishLocale];
[dateFrmattr setDateFormat:#"V"];
[dateFrmattr setTimeZone:timeZone];
dateFrmattr.timeStyle = NSDateFormatterNoStyle;
dateFrmattr.dateFormat = #"MM/dd/yyyy HH:mm:ss zzz";
NSDate *finalDate = [dateFrmattr dateFromString:#"11/01/2012 10:00:00 IST"];
// NSDate *startDate = [[NSDate alloc] init];
self.databaseDate = [[NSDate alloc] init];;
remainingSec = [finalDate timeIntervalSinceDate:databaseDate];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:#selector(showClock)
userInfo:nil
repeats:YES];
}
//NSInteger remainder = ((NSInteger)remainingSec)% 3600;
NSInteger days = remainingSec/86400;
NSInteger int1 = ((NSInteger)remainingSec) % 86400;
NSInteger hours = int1/3600;
NSInteger int2 = int1 % 3600;
NSInteger minutes = int2/60;
NSInteger seconds = int2 % 60;
clockLabel.text = [NSString stringWithFormat:#" %02d : %02d : %02d : %02d ", days,hours, minutes, seconds];
value of final date is zero on device but right on simulator.
My app is universal app the time calculation working fine on iPhone Device.
Any idea or help
After removing 'zzz' from NSDateFormatter and 'IST' from date string it works on iPad.But still have a question that why the previous code works on iPhone and not in iPad? After removing time zone from NSDateFormatter and date string it works.
I've been searching internet for a few days till now. I did find some useful information but just want to make things perfect.
I'm trying to write a countdown app which only uses second, my current code is a bit too complex and maybe off the main road. Looking for someone who can straight it up.
- (void)updateTimer{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"s"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
// where the part change time string back to int
NSString *changeToInt = timeString;
int stringInt = [changeToInt integerValue];
// loop for count down numbers
if ((buttValue - stringInt) > 0) {
leftTime = buttValue - stringInt;
[self updateValue];
} else {
leftTime = 0;
[self updateValue];
}
}
2 problems with the code, 1) do I have to go through all the date formatting to get a integer? 2) in the loop I used two variables, I was hoping to take one out and use something like --
I don't understand what you need exactly, but I think that you just want to get the number of seconds from now to a known date. The timeIntervalSinceNow method will give you a NSInteger value that represent the number of seconds from the receiver date until now, which, if the receiver is earlier than now, will be a negative value (otherwise it will be positive).
So, just to be more explicit:
- (void)updateTimer
{
leftTime = MAX(0, -[startDate timeIntervalSinceNow]); //if less than 0 will be forced to 0 -> date reached
[self updateValue];
}
As I said, I'm not sure this is what you want. If it's not, I am sorry.
Good luck!
-(void)initialiseTimer
{
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timeElapsed) userInfo:nil repeats:YES];
startDate = [[NSDate date] retain];
}
-(void)timeElapsed
{
NSLog(#"Seconds elapsed since start date %d", abs([startDate timeIntervalSinceNow]));
}
you can manipulate it to make a count down style app.
Use this code !!
-(IBAction)startAndStop:(id)sender
{
startDate = [[NSDate date]retain];
if([btnStopWatch.titleLabel.text isEqualToString:#"Start"])
{
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/100.0 target:self selector:#selector(updateTimer) userInfo:nil repeats:YES];
[btnStopWatch setTitle:#"Stop" forState:UIControlStateNormal];
}
else if([btnStopWatch.titleLabel.text isEqualToString:#"Stop"])
{
[stopWatchTimer invalidate];
[btnStopWatch setTitle:#"Start" forState:UIControlStateNormal];
}
}
- (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"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLabel.text = timeString;
NSLog(#"Seconds elapsed since start date %d", abs([startDate timeIntervalSinceNow]));
}
I am new to NSTimer in iPhone. i made a stop watch. now i want to pause time in between
and also want to do resume pause. my code is given bellow.
How can I pause time?
How can i resume from where the time is stop?
Start Time:
startDate = [[NSDate date]retain];
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
Stop Time:
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[self updateTimer];
Update Time:
(void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLabel.text = timeString;
[dateFormatter release];
}
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
I created some extra variables to help keep track on the elapsed time:
BOOL watchStart;
NSTimeInterval pauseTimeInterval;
I set watchStart = NO and pauseTimeInterval = 0.0.
I used watchStart to check if its a start or pause condition (for my IBAction), and in updateTimer, I set the timeInterval to pauseTimeInterval.
The crucial part of the code is:
_startDate = [_startDate dateByAddingTimeInterval:((-1)*(_pauseTimeInterval))]
That line will add the extra timeInterval to the startDate for calculation of the time that was paused. It's kind of like "stepping back" in time to add in the interval that was previously recorded.
-(void) updateTimer {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:_startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss.S"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
_stopWatchLabel.text = timeString;
_pauseTimeInterval = timeInterval;
}
-(IBAction)btnStartPause:(id)sender {
if(_watchStart == NO) {
_watchStart = YES;
_startDate = [NSDate date];
_startDate = [_startDate dateByAddingTimeInterval:((-1)*(_pauseTimeInterval))];
_stopWatchTime = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0 target:self selector:#selector(updateTimer) userInfo:nil repeats:YES];
}
else {
_watchStart = NO;
[_stopWatchTime invalidate];
_stopWatchTime = nil;
[self updateTimer];
}
NSTimer does not have pause or resume methods. You can make 2 types of timers, one that implements only once and the second, that repeats. Example:
Creates a timer that will enter callback myMethod each second.
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(myMethod:)
userInfo:nil
repeats:YES];
You probably will choose this one for your purpose where in your class you should maintain some
BOOL pausevariable and in the callback myMethod do the following:
- (void) myMethod:(NSTimer *) aTimer
{
if (!pause) {
// do something
// update your GUI
}
}
where you update pause in your code. To stop the timer and release memory, call
[myTimer invalidate];
hope this helped.
Small correction for the above example:
_startDate = [_startDate dateByAddingTimeInterval:((-1)*(_pauseTimeInterval))];
Add retain # the end :
_startDate = [[_startDate dateByAddingTimeInterval:((-1)*(_pauseTimeInterval))]retain];
This will make things better :-)
-(void)startStopwatch
{
//initialize the timer HUD
[self setSeconds:second];
// [self.hud.stopwatch setSeconds:_secondsLeft];
//schedule a new timer
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(tick:)
userInfo:nil
repeats:YES];
}
-(void)pause{
[_timer invalidate];
}
-(void)resume {
[_timer isValid];
}
using this code we can pause and resume the timer
Friends i was successful in implementing pause and resume function to iOs timer app, the code is as follows
- (IBAction)pauseT:(id)sender {
se = sec;
mi = min;
ho = hour;
[timer invalidate];
}
- (IBAction)resumeT:(id)sender {
sec = se;
min = mi;
hour = ho;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countDown) userInfo:nil repeats:YES];
}
Hope this works for you guys..