كيف يمكنني كسر nstimeInterval في السنة والأشهر والأيام والساعات والدقائق والثواني على iPhone؟

StackOverflow https://stackoverflow.com/questions/1237778

سؤال

لدي فاصل زمني يمتد سنوات وأريد كل مكونات الوقت من سنة إلى ثانية.

فكرتي الأولى هي أن تقسم الفاصل الزمني في غضون ثوان في السنة، مما يطرح ذلك من إجمالي ثواني تشغيل، ويقسم ذلك حسب ثوان في شهر واحد، مما يطرح ذلك من إجمالي التشغيل وما إلى ذلك.

يبدو أن هذا فقط ملتوية وأنا قرأت أنه كلما قمت بعمل شيء يبدو ملكيا، فربما تكون هناك طريقة مدمجة.

هل هناك؟

أنا دمج الأسلوب الثاني ل Alex في التعليمات البرمجية الخاصة بي.

إنه بطريقة تسمى بواسطة uidepicker في واجهتي.

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 ساعة قبالة. إذا قمت بتعيين منتقي التاريخ إلى يوم واحد في الماضي، فأنا خارج المبلغ نفسه.

تحديث: لدي تطبيق يحسب عمرك في السنوات، بالنظر إلى عيد ميلادك (تم تعيينه من UdatePicker)، ومع ذلك كان في كثير من الأحيان. هذا يثبت أن هناك عدم دقة، لكنني لا أستطيع معرفة المكان الذي يتعلق به، هل يمكنك ذلك؟

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

المحلول

وصف مختصر

  1. مجرد نهج آخر لإكمال إجابة JBrowilkinson ولكن إضافة بعض الكود. يمكن أن يقدم أيضا حلا لتعليق أليكس رينولدز.

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

نصائح أخرى

هذا الرمز يدرك مرات حفظ الضوء اليوم وغيرها من الأشياء السيئة المحتملة.

NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components: (NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit )
                                                    fromDate:startDate
                                                      toDate:[NSDate date]
                                                     options:0];


NSLog(@"%ld", [components year]);
NSLog(@"%ld", [components month]);
NSLog(@"%ld", [components day]);
NSLog(@"%ld", [components hour]);
NSLog(@"%ld", [components minute]);
NSLog(@"%ld", [components second]);

تحويل الفاصل الخاص بك إلى NSDate استخدام +dateWithIntervalSince1970, ، احصل على مكونات التاريخ من ذلك باستخدام NSCalendar-componentsFromDate طريقة.

المرجع SDK.

من iOS8 وما فوق يمكنك استخدام NSDateComponentsFormatter

لديها أساليب لتحويل اختلاف الوقت في السلسلة المنسقة سهلة الاستخدام.

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

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

هذا يعطي الناتج - أسبوعين، 4 أيام، 18 ساعة، 57 دقيقة، 32 ثانية

هذا يعمل بالنسبة لي:

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

الفرق الرئيسي هنا هو أنك تحتاج إلى ضبط للوقت الزمنية.

أو هناك طريقة الفصل الدراسي. لا يتعامل مع سنوات، ولكن يمكن إضافته بسهولة على الرغم من أنه من الأفضل بالنسبة للأشكال الصغيرة مثل الأيام والساعات والدقائق. يستغرق الأمر محليا في الاعتبار ويوضح فقط ما هو مطلوب:

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

}

إليك احتمال آخر، نظافة إلى حد ما:

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;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top