سؤال

لدي كمية من seconds التي مرت من حدث معين. انها مخزنة في NSTimeInterval نوع البيانات.

أريد تحويلها إلى minutes و seconds.

على سبيل المثال، لدي: "326.4" ثوان وأريد تحويله إلى السلسلة التالية: "5:26".

ما هي أفضل طريقة لتحقيق هذا الهدف؟

شكرا.

هل كانت مفيدة؟

المحلول

كود مزيف:

minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)

نصائح أخرى

وصف مختصر

  1. الجواب من Brian Ramsay هو أكثر ملاءمة إذا كنت ترغب فقط في تحويل إلى دقائق.
  2. إذا كنت تريد Cocoa API القيام بذلك من أجلك وتحويل NstimeInterval الخاص بك ليس فقط دقائق ولكن أيضا إلى أيام وأشهر وأسبوع، وما إلى ذلك ... أعتقد أن هذا نهج أكثر عمومية
  3. استخدام طريقة Nscalendar:

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

    • "إرجاع، ككائن NSDateComponents باستخدام مكونات محددة، الفرق بين التواريخ المرفقة". من وثائق API.

  4. قم بإنشاء 2 NSDate اختلافه هو NstimeInterval الذي تريد تحويله. (إذا كان NstimeInterval يأتي من مقارنة 2 NSdate، فلا تحتاج إلى القيام بهذه الخطوة، ولا تحتاج حتى nstimeInterval).

  5. احصل على علامات الاقتباس الخاصة بك من NSDateComponents

عينة من الرموز

// The time interval 
NSTimeInterval theTimeInterval = 326.4;

// 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
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit;

NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:date1  toDate:date2  options:0];

NSLog(@"Conversion: %dmin %dhours %ddays %dmoths",[conversionInfo minute], [conversionInfo hour], [conversionInfo day], [conversionInfo month]);

[date1 release];
[date2 release];

مشاكل معروفة

  • الكثير عن مجرد تحويل، فأنت على حق، ولكن هذه هي الطريقة التي يعمل بها واجهة برمجة التطبيقات.
  • اقتراحي: إذا اعتدت على إدارة بيانات وقتك باستخدام NSDate و NSCALENDAR، فسيقوم API بعمل العمل الشاق لك.

كل هذه تبدو أكثر تعقيدا مما يجب أن تكون! فيما يلي طريقة قصيرة وحلوة لتحويل الفاصل الزمني إلى ساعات، دقائق والثواني:

NSTimeInterval timeInterval = 326.4;
long seconds = lroundf(timeInterval); // Since modulo operator (%) below needs int or long

int hour = seconds / 3600;
int mins = (seconds % 3600) / 60;
int secs = seconds % 60;

ملاحظة عند وضع تعويم في Int، يمكنك الحصول على الكلمة () تلقائيا، ولكن يمكنك إضافتها إلى الأولين إذا كنت تشعر بأنك أفضل :-)

سامحني أن أكون عذراء مكدس ... لست متأكدا من كيفية الرد على إجابة براين رامساي ...

لن يعمل استخدام الجولة في القيم الثانية بين 59.5 و 59.99999. ستكون القيمة الثانية 60 خلال هذه الفترة. استخدام Trunc بدلا من ذلك ...

 double progress;

 int minutes = floor(progress/60);
 int seconds = trunc(progress - minutes * 60);

إذا كنت تستهدف أو أعلى من نظام التشغيل iOS 8 أو OS X 10.10، فهذا أصبح أسهل كثيرا. الجديد NSDateComponentsFormatter الطبقة تسمح لك بتحويل معين NSTimeInterval من قيمتها في ثوان إلى سلسلة مترجمة لإظهار المستخدم. علي سبيل المثال:

ج موضوعية

NSTimeInterval interval = 326.4;

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

componentFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
componentFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropAll;

NSString *formattedString = [componentFormatter stringFromTimeInterval:interval];
NSLog(@"%@",formattedString); // 5:26

سويفت

let interval = 326.4

let componentFormatter = NSDateComponentsFormatter()

componentFormatter.unitsStyle = .Positional
componentFormatter.zeroFormattingBehavior = .DropAll

if let formattedString = componentFormatter.stringFromTimeInterval(interval) {
    print(formattedString) // 5:26
}

NSDateCompnentsFormatter كما يسمح لهذا الإخراج بأشكال أطول. يمكن العثور على مزيد من المعلومات في Nshipster NSFormatter المادة. وبعد واعتمادا على الطبقات التي تعمل بالفعل مع (إن لم يكن) NSTimeInterval)، قد يكون الأمر أكثر ملاءمة لتمرير تكثيف مثيل NSDateComponents, ، او اثنين NSDate الكائنات، والتي يمكن القيام به وكذلك عن طريق الطرق التالية.

ج موضوعية

NSString *formattedString = [componentFormatter stringFromDate:<#(NSDate *)#> toDate:<#(NSDate *)#>];
NSString *formattedString = [componentFormatter stringFromDateComponents:<#(NSDateComponents *)#>];

سويفت

if let formattedString = componentFormatter.stringFromDate(<#T##startDate: NSDate##NSDate#>, toDate: <#T##NSDate#>) {
    // ...
}

if let formattedString = componentFormatter.stringFromDateComponents(<#T##components: NSDateComponents##NSDateComponents#>) {
    // ...
}

كود براين رامساي، De-pseudofied:

- (NSString*)formattedStringForDuration:(NSTimeInterval)duration
{
    NSInteger minutes = floor(duration/60);
    NSInteger seconds = round(duration - minutes * 60);
    return [NSString stringWithFormat:@"%d:%02d", minutes, seconds];
}

إليك نسخة سريعة:

func durationsBySecond(seconds s: Int) -> (days:Int,hours:Int,minutes:Int,seconds:Int) {
    return (s / (24 * 3600),(s % (24 * 3600)) / 3600, s % 3600 / 60, s % 60)
}

يمكن استخدامها مثل هذا:

let (d,h,m,s) = durationsBySecond(seconds: duration)
println("time left: \(d) days \(h) hours \(m) minutes \(s) seconds")
    NSDate *timeLater = [NSDate dateWithTimeIntervalSinceNow:60*90];

    NSTimeInterval duration = [timeLater  timeIntervalSinceNow];

    NSInteger hours = floor(duration/(60*60));
    NSInteger minutes = floor((duration/60) - hours * 60);
    NSInteger seconds = floor(duration - (minutes * 60) - (hours * 60 * 60));

    NSLog(@"timeLater: %@", [dateFormatter stringFromDate:timeLater]);

    NSLog(@"time left: %d hours %d minutes  %d seconds", hours,minutes,seconds);

المخرجات:

timeLater: 22:27
timeLeft: 1 hours 29 minutes  59 seconds

لأنها أساسا مزدوجة ...

قسم 60.0 واستخراج الجزء الأكاد والجزء الكسري.

سيكون الجزء الأيامي هو العدد الكامل من الدقائق.

اضرب الجزء الكسري بنسبة 60.0 مرة أخرى.

ستكون النتيجة الثواني المتبقية.

تذكر أن السؤال الأصلي يدور حول إخراج السلسلة، وليس رمز الزائفة أو مكونات السلسلة الفردية.

أريد تحويله إلى السلسلة التالية: "5:26"

يفتقد العديد من الإجابات قضايا التدويل، ومعظمها تقوم بحسابات الرياضيات باليد. جميع القرن العشرين فقط ...

لا تفعل الرياضيات بنفسك (SWIFT 4)

let timeInterval: TimeInterval = 326.4
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.unitsStyle = .positional
if let formatted = dateComponentsFormatter.string(from: timeInterval) {
    print(formatted)
}

5:26


الرافعة المالية على المكتبات

إذا كنت تريد حقا مكونات فردية، ورمز قابل للقراءة سارة، تحقق من swiftdate.:

import SwiftDate
...
if let minutes = Int(timeInterval).seconds.in(.minute) {
    print("\(minutes)")
}

5


الشكر ل mickmaccallum. و polarwar. لاستخدام كاف DateComponentsFormatter

كيف فعلت هذا في SWIFT (بما في ذلك تنسيق السلسلة لإظهاره باسم "01:23"):

let totalSeconds: Double = someTimeInterval
let minutes = Int(floor(totalSeconds / 60))
let seconds = Int(round(totalSeconds % 60))        
let timeString = String(format: "%02d:%02d", minutes, seconds)
NSLog(timeString)

SWIFT 2 الإصدار

extension NSTimeInterval {
            func toMM_SS() -> String {
                let interval = self
                let componentFormatter = NSDateComponentsFormatter()

                componentFormatter.unitsStyle = .Positional
                componentFormatter.zeroFormattingBehavior = .Pad
                componentFormatter.allowedUnits = [.Minute, .Second]
                return componentFormatter.stringFromTimeInterval(interval) ?? ""
            }
        }
    let duration = 326.4.toMM_SS()
    print(duration)    //"5:26"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top