2009-08-06 71 views
54

我有一個跨越幾年的時間間隔,我希望所有的時間從一年下降到秒。如何在iPhone上將NSTimeInterval分解爲年,月,日,小時,分鐘和秒鐘?

我的第一個想法是在一年內將整個時間間隔除以秒,從一秒鐘的總運行時間中減去該時間間隔,在一個月內將其除以秒,從運行總和中減去該時間間隔,依此類推。

這似乎令人費解,我讀過,當你做一些看起來很複雜的事時,可能有一種內置方法。

有嗎?

我將Alex的第二種方法整合到我的代碼中。

它在我的界面中由UIDatePicker調用的方法。

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); 

當我設定的日期選取器日期1年零1天過去,我得到:

1年1個月1天16小時0 分20秒

這是1個月和16個小時了。如果我過去將日期選擇器設置爲1天,那麼我的數量就會減少。

更新:我有一個應用程序,計算你的年齡,考慮到你的生日(從UIDatePicker設置),但它經常關閉。這證明存在不準確性,但我無法弄清楚它來自哪裏,對嗎?

+0

如果您設定的日期選取器一天前,你就要去以一個月爲六個小時? – 2009-08-06 19:10:04

+0

是的,一個月零十六個小時。 – willc2 2009-08-07 01:19:15

+0

如果結果持續一個月零十六個小時,無論您選擇什麼值,無論是從變量中減去該值,還是移位,或者您需要評估錯誤來自哪裏。我的猜測是,如果你總是偏離這個數值,那麼你的時間間隔就不對了。 – 2009-08-07 23:15:52

回答

99

簡要說明

  1. 只是另一種方法來完成JBRWilkinson的答案,但增加了一些代碼。它也可以爲Alex Reynolds的評論提供解決方案。

  2. 使用NSCalendar方法:

    • (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts

    • 「返回,作爲NSDateComponents使用指定的部件,兩個提供的日期之間的差值對象」。 (來自API文檔)。

  3. 創建2的NSDate要打破它的區別是NSTimeInterval。(如果您的NSTimeInterval來自於比較2 NSDate,則不需要執行此步驟,而且您甚至不需要NSTimeInterval,只需將日期應用於NSCalendar方法即可)。

  4. 獲得從NSDateComponents您的報價

示例代碼

// 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]); 
+0

讚賞實際的工作代碼,而不是文字。 – willc2 2009-09-07 06:32:47

+0

謝謝,先生。 – Martin 2010-01-28 14:19:45

+5

此方法存在夏季時間變化的問題,您將直接遇到1小時問題。 – hokkuk 2012-05-09 21:30:25

4

使用+dateWithIntervalSince1970將您的間隔轉換爲NSDate,使用NSCalendar-componentsFromDate方法獲取日期組分。

SDK Reference

+4

+1。爲了讓OP更加詳細一些,你不能精確地將時間間隔轉換成這些組件,你必須知道你從哪裏開始(因此然後是dateWithIntervalFrom1970),因爲例如如果你在二月份的話,29天是一個月第一個(當然除了在雙摺式年份),但是如果你在1月1日... – fraca7 2009-08-06 12:18:37

2
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. 
... 
0

這裏的另一種可能性,有些清潔劑:

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; 
+0

對於1秒(一秒前)的時間間隔,返回「年-1,月12,第31天,小時16,分鐘0,秒1「。 – willc2 2009-08-28 04:09:20

+0

這聽起來像一個錯誤。 – 2009-08-28 06:05:39

3

這個工作對我來說:

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]; 

這裏的主要區別是,你需要調整爲時區。

+1

+1不忘記時區 – 2011-11-10 11:28:06

+3

-1忘記24小時以後的任何事情將會失敗 – Jonny 2013-04-30 06:27:29

3

或者有我的班級方法。它不能處理多年,但可以很容易地添加,但對於像日,小時和分鐘這樣的小時間段來說更好。它以複數考慮,僅顯示所需的內容:

+(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; 
} 
0
- (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; 

} 
15

此代碼是知道的日光節約時間和其他可能討厭的東西。

​​
4

從iOS8上和上面你可以使用NSDateComponentsFormatter

它有方法,將用戶友好的格式化字符串的時間差。

NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init]; 
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull; 

NSLog(@"%@", [formatter stringFromTimeInterval:1623452]); 

這使輸出 - 2周,4天,18小時,57分鐘,32秒

相關問題