开发者

Time calculation giving increasingly wrong result

开发者 https://www.devze.com 2023-02-20 02:02 出处:网络
I need to create a Timer that counts down from a string I get from the server. the string outputs total seconds left.

I need to create a Timer that counts down from a string I get from the server. the string outputs total seconds left.

I am using this code - it calculates the initial number time right and it counts down but the minutes are the problem.

EDIT - Every real minute the minute calculation goes up by one. But I don't understand why it is doing this.

-(void)showTimmer:(id) sender {

//get total amount of seconds

NSString *timeRaw =  [ArrayFromServer objectAtIndex:1];
NSArray *timeArr = [timeRaw componentsSeparatedByString:@","];
timetoInt =  [timeArr objectAtIndex:0];
int time1 = [timetoInt intValue];

//set the second countdown

NSDate* now = [NSDate date];    
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *dateComponents = [gregorian components:(NSSecondCalendarUnit) fromDate:now];

NSInteger seconds = time1 - [dateComponents second];

[gregorian release];

// do the hours days maths

int hour = (seconds / 3600 );
seconds -= hour * 3600开发者_StackOverflow;
int minute = (seconds / 60 );
seconds -= minute * 60;
int second = seconds;

//set the labels

countdownLabel.text = [NSString stringWithFormat:@"%02dH %02dM %02ds", hour, minute, second];


You need to subtract the calculated hours from the total amount of seconds before going to the next line (not sure why you use modulo). Something like this (note

int hour = (seconds / 3600 );
seconds -= hour * 3600;
int minute = (seconds / 60 );
seconds -= minute * 60;
int second = seconds;

Hope that fixes it.


You're using your pliers to drive a screw. The seconds method of an NSDateComponents gives you what you would see on a clock if you looked at the second hand at the time represented by your NSDate. For example, as I type this, it's UTC Saturday March 26, 2011, 02:52:04. If I got [NSDate date], turned it into an NSDateComponents and asked that for its seconds, I'd get "4". If I did it again in a second, I'd get "5", and when the minute clicked over, I'd get "59", then "0".

You can verify this for yourself; put this in your timer method:

NSInteger dcSecond = [dateComponents second];
NSLog(@"%d", dcSecond);

So every time the minute of the actual clock ticks over, your calculation of the remaining time:

NSInteger seconds = time1 - [dateComponents second];

subtracts 0 from time1 and gives you back time1. That's why you're having the problem.

The way* to fix it is to dump the calendar stuff and use CFAbsoluteTimeGetCurrent(). First, put the start time in your timer's userInfo (or in an ivar if you prefer):

[NSTimer scheduledTimer...
        // The function returns CFAbsoluteTime, which is a
        // typedef'd double but you're already working with
        // integers, so use a cast
             userInfo:[NSNumber numberWithInteger:(NSInteger)CFAbsoluteTimeGetCurrent()]
                ...];

Then change your calculation of the remaining time (the variable you call seconds:

NSInteger startTime = [[timer userInfo] integerValue];
NSInteger currTime = (NSInteger)CFAbsoluteTimeGetCurrent();
NSInteger elapsedTime = currTime - startTime;
NSInteger duration = time1 - startTime;
//NSInteger seconds = time1 - [dateComponents second];
NSInteger remaining =  duration - elapsedTime;

int hour = remaining / 3600;
...

*: Well, one way, but I think probably the best.

0

精彩评论

暂无评论...
验证码 换一张
取 消