2011-03-25 106 views
1

我需要創建一個計時器,從我從服務器獲得的字符串倒計時。字符串輸出總剩餘秒數。時間計算給出越來越錯誤的結果

我正在使用此代碼 - 它計算的初始數字時間正確,它倒計時但分鐘是問題。

編輯 - 每分鐘計算每增加一分鐘。但我不明白爲什麼它這樣做。

- (空)showTimmer:(ID)發送{

//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; 
int minute = (seconds/60); 
seconds -= minute * 60; 
int second = seconds; 

//set the labels 

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

回答

1

您目前使用的鉗子螺絲釘,一個NSDateComponentsseconds方法給你,你會看到在一個時鐘,如果你看例如,在我輸入的時候,是UTC 2011年3月26日星期六02:52:04如果我得到了[NSDate date],把它變成了NSDateComponents並要求它的seconds ,我會得到「4」,如果我一秒鐘再做一次,我會得到「5」,當分鐘點擊時,我會得到「59」,然後是「0」

你可以自己驗證一下;把這個在您的計時器方法:

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

所以每次的實際時鐘的分鐘刻度隨着時間的推移,你的剩餘時間計算:

NSInteger seconds = time1 - [dateComponents second]; 

time1減去0,給你回time1。這就是你遇到問題的原因。

修復它的方法是轉儲日曆內容並使用CFAbsoluteTimeGetCurrent()。首先,把開始時間在你的計時器的用戶信息(或伊娃如果您喜歡):

[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()] 
       ...]; 

然後改變你的剩餘時間計算(你叫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; 
... 

*:那麼,一個的方式,但我認爲可能是最好的。

+0

另一個選擇是將開始時間保存爲一個'NSDate',然後你可以這樣做'NSInteger elapsedTime =(NSInteger)[startDate timeIntervalSinceNow];' – 2011-03-26 03:27:59

+0

這個工作完美謝謝你,一旦知道它簡單得多。 – jaggi 2011-03-27 17:51:50

+0

是的,我認爲這是一個舍入錯誤,直到我意識到'NSDateComponents'在做什麼。那個階級及其同伴的文件絕對是簡潔的一面。 (我個人最喜歡的是['NSCalendar -firstWeekday'](http://developer.apple。com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCalendar_Class/Reference/NSCalendar.html#// apple_ref/occ/instm/NSCalendar/firstWeekday。)順便說一下,你可以嘗試使用double,這就是'CF-'和'NS-''TimeInterval'都是。然後根據需要使用'fmod','ceil'和'floor'。無論如何,很高興我能幫上忙! – 2011-03-27 20:40:22

3

您需要去下一行減去秒的總金額計算的小時(不知道爲什麼你使用模)。像這樣的東西(注

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

希望能解決它。

+0

不,但我沒有注意到,問題是,當分鐘在iPhone SIM上升mintue上漲一個!有任何想法嗎? – jaggi 2011-03-26 00:10:31

+0

做模數是一種非常有效的時間解析方法;您可能需要保持總計數器值。 – 2011-03-26 03:31:08