NSTimeInterval से HH: mm: ss?


85

अगर मेरे पास एक NSTimeInterval है जो 200.0 पर सेट है, तो क्या इसे 00:03:20 में बदलने का कोई तरीका है, मैं सोच रहा था कि मैं इसके साथ एक NSDate को इनिशियलाइज़ कर सकता हूं और फिर HH: mm: ss का उपयोग करके NSDateFormatter का उपयोग कर सकता हूं। मेरा प्रश्न यह है कि क्या ऐसा करने का कोई त्वरित तरीका है या क्या मुझे स्वयं संख्या को तोड़ना होगा और उपयोग करना होगा [NSString stringWithFormat: %02d:%02d:%02d, myHour, myMin, mySec]?

जवाबों:


198

NSDateFormatterविभाजन और मोडुलो के अलावा किसी और चीज का उपयोग करने की आवश्यकता नहीं है । NSTimeIntervalबस एक डबल युक्त सेकंड है।

तीव्र

func stringFromTimeInterval(interval: NSTimeInterval) -> String {
    let interval = Int(interval)
    let seconds = interval % 60
    let minutes = (interval / 60) % 60
    let hours = (interval / 3600)
    return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}

उद्देश्य सी

- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {
    NSInteger ti = (NSInteger)interval;
    NSInteger seconds = ti % 60;
    NSInteger minutes = (ti / 60) % 60;
    NSInteger hours = (ti / 3600);
    return [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes, (long)seconds];
}

बहुत सराहना की, मैं क्या सोच रहा था, लेकिन मैं सिर्फ यह देखना चाहता था कि मैं पहले से ही कुछ गायब नहीं था आईओएस एसडीके के हिस्से के रूप में शामिल है।
फज्योर्गट

1
मैं यह बताना चाहता हूं कि ":" केवल अंग्रेजी और कुछ अन्य भाषाओं में परिसीमन का काम करता है। फिनिश, उदाहरण के लिए, "का उपयोग करता है।" - इस तरह "15.02.59"
sgosha

@sgosha, वास्तव में, आम तौर पर Apple इन के लिए स्वरूप प्रदान करने के लिए जाता है। क्या मुझे इसके बजाय स्वरूपण के लिए स्थानीयकृत स्ट्रिंग का उपयोग करना चाहिए?
गेरी शॉ

20
यह गलत उत्तर है क्योंकि यह परिसीमन को स्थानीय नहीं करता (जैसा कि अन्य टिप्पणियों में उल्लेख किया गया है)। NSDateCompomentsFormatter का उपयोग करके आप अपने समय अंतराल को एक पंक्ति में सही ढंग से प्रारूपित कर सकते हैं, जैसे NSDateComponentsFormatter().stringFromTimeInterval(NSTimeInterval(duration))कि स्विफ्ट में
इलियास करीम

4
स्थानीयकरण और भविष्य के प्रमाण के लिए, सही समाधान NSDateCompordsFormatter का उपयोग करना है जैसा कि @jrc द्वारा वर्णित है
voidref

102

IOS 8 पर, उपयोग करें NSDateComponentsFormatter

NSDateComponentsFormatter *dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init];
NSLog(@"%@", [dateComponentsFormatter stringFromTimeInterval:200.0]);

आउटपुट "3:20"।

NSDateComponentsFormatter *dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init];
dateComponentsFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
dateComponentsFormatter.allowedUnits = (NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond);
NSLog(@"%@", [dateComponentsFormatter stringFromTimeInterval:200.0]);

आउटपुट "0:03:20"।


2
अच्छा अद्यतन। लेकिन अगर यह वास्तव में सिर्फ इतनी सरल गणना है, तो इन ऑब्जेक्ट का उपयोग एक विशाल ओवरहेड (जब तक कि कोई गतिशील प्रारूप शामिल नहीं है) का उपयोग नहीं किया जाएगा?
जूलियन एफ। वेनर्ट

2
आपको यह सुनिश्चित करने के लिए प्रारूपण की आवश्यकता है कि स्ट्रिंग विभिन्न स्थानों आदि के लिए सही ढंग से दिखाई देती है
अधिकतम मैकलेओड

वास्तव में छोटी टिप्पणी, लेकिन ऑब्जेक्टिव प्रश्न के लिए सी फ़ंक्शन का उदाहरण देना अजीब है। शायद यह ObjectiveC प्रारूप में बदलने के लायक है?
Rilakkuma


17

स्विफ्ट 3 संस्करण onmyway133 के उत्तर:

import Foundation

func format(_ duration: TimeInterval) -> String {
    let formatter = DateComponentsFormatter()
    formatter.zeroFormattingBehavior = .pad
    formatter.allowedUnits = [.minute, .second]

    if duration >= 3600 {
        formatter.allowedUnits.insert(.hour)
    }

    return formatter.string(from: duration)!
}


print(format(12)) // 0:12
print(format(65)) // 1:05
print(format(1750)) // 29:10
print(format(3890)) // 1:04:50
print(format(45720)) // 12:42:00

किसी DateFormatter या NumberFormatter की तरह एक DateCompldsFormatter महँगा प्रदर्शन करना है?
मोशे

1
इसके बजाय एक घंटे मूल्य हो, तो जाँच, की स्थापना की zeroFormattingBehaviorजा करने के लिए [.dropLeading, .pad]एक बेहतर (कम कोड) विकल्प हो सकता है।
मैडइन सीन

टिप्पणियां गलत प्रतीत होती हैं। इस कोड में परिणाम: 00:12, 01:05, 29:10, 01:04:50, 12:42:00
जॉर्डन एच

10

कोड की कुछ अतिरिक्त लाइनें, लेकिन मुझे लगता है कि NSDateCompords का उपयोग करना अधिक सटीक मूल्य देगा।

- (NSString *)getTimeRepresentationFromDate:(NSDate *)iDate withTimeInterval:(NSTimeInterval)iTimeInterval {
    NSString *aReturnValue = nil;
    NSDate *aNewDate = [iDate dateByAddingTimeInterval:iTimeInterval]; 

    unsigned int theUnits = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSCalendar *aCalender = [NSCalendar currentCalendar];
    NSDateComponents *aDateComponents = [aCalender components:theUnits fromDate:iDate toDate:aNewDate options:0];

    aReturnValue = [NSString stringWithFormat:@"%d:%d:%d", [aDateComponents hour], [aDateComponents minute], [aDateComponents second]];

    return aReturnValue;
}

उपरोक्त विधि 2 तिथियों का उपयोग करती है जिसके उपयोग से TimeInterval बनाया जाता है। आप डिफ़ॉल्ट मान के रूप में iDate पैरामीटर के लिए [NSDate दिनांक] भी पास कर सकते हैं।
रोशिट

2
किस तरह से @ मैथियास-बाउच द्वारा इस्तेमाल की गई विधि की तुलना में यह "अधिक सटीक" है?
jb

1
इस पद्धति के साथ u को सेकंड, घंटे, मिनट में समय अंतराल मिल जाता है अर्थात 60 के संदर्भ में जबकि @ matthias-bauch का उत्तर आपको उदाहरण के लिए दशमलव शर्तों में देता है यदि आप पर्याप्त समय की प्रतीक्षा करते हैं तो आपको 2 मिनट 19 सेकंड के बजाय 1 मिनट 79 सेकंड दिखाई देंगे
आशीष पिशेय

यह स्वीकृत समाधान की तुलना में बहुत बेहतर समाधान है। ":" का उपयोग अभी भी अंतर्राष्ट्रीयकरण के लिए एक समस्या है, लेकिन कम से कम यह लीप दिनों और दिन के उजाले की बचत सीमाओं के बीच मजबूत है।
इवानफ्लेश

@ आशीषपी मोडुलो ऑपरेटर 59 से कुछ भी बड़ा होने से रोकता है।
मथायस

8

में स्विफ्ट 2 , आईओएस 8 । यह सुनिश्चित करता है कि हम केवल आवश्यक होने पर ही घंटे दिखाते हैं

func format(duration: NSTimeInterval) -> String {
  let formatter = NSDateComponentsFormatter()
  formatter.zeroFormattingBehavior = .Pad

  if duration >= 3600 {
    formatter.allowedUnits = [.Hour, .Minute, .Second]
  } else {
    formatter.allowedUnits = [.Minute, .Second]
  }

  return formatter.stringFromTimeInterval(duration) ?? ""
}

मतलब आपके पास है

print(format(12)) // 0:12
print(format(65)) // 1:05
print(format(1750)) // 29:10
print(format(3890)) // 1:04:50
print(format(45720)) // 12:42:00


4

स्विफ्ट 4

DateComponentsFormatter().string(from: <# TimeInterval #>)

उदाहरण के लिए:

DateComponentsFormatter().string(from: 59.0)

3

स्विफ्ट में, मैं मैथियास बाउच के सुझाव का "विस्तार" करने के लिए, इसे NSTimeInterval की एक संगणित संपत्ति बनाऊंगा:

extension NSTimeInterval {
  var stringValue: String {
    let interval = Int(self)
    let seconds = interval % 60
    let minutes = (interval / 60) % 60
    let hours = (interval / 3600)
    return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
  }
}

इसका फायदा यह है कि यह NSTimeIntervalप्रकार से जुड़ा हुआ है , न कि आपके व्यू कंट्रोलर या जहां आप उस फ़ंक्शन को रखते हैं। उपयोग करने के लिए आप कुछ इस तरह से जाएंगे:

let timeInterval = NSDate().timeIntervalSinceDate(start)        
self.elapsedTimeLabel.text = timeInterval.stringValue

धन्यवाद, केनी! मेरे मामले में मुझे उनकी अलग से आवश्यकता थी, इसलिए मैंने आपके विस्तार में अतिरिक्त चर जोड़े: "var seconds: Int {let interval = (self); let seconds = interval% 60; return seconds}" इत्यादि मिनटों और घंटों के लिए। तो वह उपयोग होगा: प्रिंट ("बिताए हुए मिनट: (timeInterval.minutes)")
विटाली

3

@ Onmyway133 के उत्तर के आधार पर यहां स्विफ्ट 4 संस्करण है:

func format(duration: TimeInterval) -> String {
    let formatter = DateComponentsFormatter()
    formatter.zeroFormattingBehavior = .pad

    if duration >= 3600 {
        formatter.allowedUnits = [.hour, .minute, .second];
    } else {
        formatter.allowedUnits = [.minute, .second];
    }

    return formatter.string(from: duration) ?? "";
}

0

सीधे ऐप्पल डॉक्स से: एच फाइल में:

 @property(strong,nonatomic)NSDateComponentsFormatter *timerFormatter;

मीटर फ़ाइल में

@synthesize timerFormatter;

- (void)viewDidLoad {
[super viewDidLoad];
NSDateComponentsFormatter *timerFormatter = [[NSDateComponentsFormatter alloc] init];
timerFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional; 
//10:59 Positional THIS ONE DOES NOT SEEM TO WORK iOS<9 WHEN <1Minute JUST SHOWS 01, 10m 59s Abbreviated, 10min 59sec Short, 10minutes 59seconds Full ...
timerFormatter.allowedUnits = NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond;
}

जहाँ भी आपको अपने NSTimeInterval time को धर्मान्तरित करने की आवश्यकता है: hh: mm: ss string, यह करें:

NSString *txt=[timerFormatter stringFromTimeInterval:timeInterval];

0

मुझे लगता है, टाइमर अंश को सीमांकित किया जाना चाहिए। जैसा कि मैथियस का कोड सेकंड में उस समस्या को पैदा कर रहा था, मैं निम्नलिखित से थोड़ा संशोधित होकर मैथियस का उपयोग करता हूं

    - (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {
        int ti = (int) ceil(interval);
        int seconds = ti % 60;
        int minutes = (ti / 60) % 60;
        int hours = (ti / 3600);
        return [NSString stringWithFormat:@"%02d:%02d:%02d",hours, minutes, seconds];
    }

0

Onmyway133 के जवाब का उद्देश्य सी संस्करण

- (NSString*) formatTimeInterval:(NSTimeInterval) timeInterval {

    NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];

    formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;

    if (timeInterval > 3600) {
        formatter.allowedUnits = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    } else {
        formatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitSecond;
    }

    return [formatter stringFromTimeInterval:timeInterval];
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.