Jak podzielić NSTimeInterval na rok, miesiące, dni, godziny, minuty i sekundy na iPhonie?
Mam przedział czasu, który obejmuje lata i chcę wszystkie składniki czasu od roku do sekund.
Moja pierwsza myśl polega na całkowitym podzieleniu przedziału czasu przez sekundy w roku, odjęciu tego od sumy sekund w biegu, podzieleniu tego przez sekundy w miesiącu, odjęciu tego od sumy sekund w biegu i tak dalej.
To po prostu wydaje się zawiłe i czytałem, że kiedykolwiek robisz coś, co wygląda zawiłe, prawdopodobnie istnieje wbudowana metoda.
Jest tam?
Włączyłem drugą metodę Alexa do mojego kodu.Jest w metodzie wywoływanej przez UIDatePicker w moim interfejsie.
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);
Kiedy ustawiam date selector na date 1 rok i 1 dzień w przeszłości, otrzymuję:
Czyli 1 miesiąc i 16 godzin wolnego. Jeśli w przeszłości ustawiłem selektor daty na 1 dzień, jestem wyłączony o taką samą kwotę.1 lat 1 miesięcy 1 dni 16 godzin 0 minut 20 sekund
Update : mam aplikację, która oblicza Twoje wiek w latach, biorąc pod uwagę urodziny (zestaw z UIDatePicker), jednak często był wyłączony. To dowodzi, że była nieścisłość, ale nie wiem, skąd to się wzięło, prawda?
9 answers
Krótki Opis
Kolejne podejście do uzupełnienia odpowiedzi JBRWilkinson, ale dodanie jakiegoś kodu. Może również zaoferować rozwiązanie komentarza Alexa Reynoldsa.
-
Użyj metody NSCalendar:
(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts
"zwraca, jako obiekt NSDateComponents wykorzystujący określone komponenty, różnicę między dwiema podanymi datami". (Z dokumentacji API).
Utworzyć 2 NSDate, których różnica jest NSTimeInterval, który chcesz rozbić. (Jeśli NSTimeInterval pochodzi z porównania 2 NSDate, nie musisz robić tego kroku, a nawet nie potrzebujesz NSTimeInterval, po prostu zastosuj daty DO METODY NSCalendar).
-
Uzyskaj swoje cytaty z NSDateComponents
Przykładowy Kod
// 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]);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-16 14:49:46
Ten kod jest świadomy czasu oszczędzania światła dziennego i innych możliwych nieprzyjemnych rzeczy.
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]);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-07 09:59:50
Z iOS8 i wyżej możesz użyć NSDateComponentsFormatter
Posiada metody konwersji różnicy czasu w przyjaznym dla użytkownika sformatowanym łańcuchu.
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
NSLog(@"%@", [formatter stringFromTimeInterval:1623452]);
Daje to wynik-2 tygodni, 4 dni, 18 godzin, 57 minut, 32 sekund
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-19 12:52:37
Przelicz swój interwał na NSDate
używając +dateWithIntervalSince1970
, Uzyskaj składniki daty z tego za pomocą metody NSCalendar
S -componentsFromDate
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-18 16:11:18
To działa dla mnie:
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];
Główna różnica polega na tym, że musisz dostosować strefę czasową.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-06 02:00:40
Albo jest moja metoda klasowa. Nie obsługuje lat, ale można to łatwo dodać, chociaż lepiej jest dla małych timelaps, takich jak dni, godziny i minuty. Bierze pod uwagę liczby mnogie i pokazuje tylko to, co jest potrzebne:
+(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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-08 23:16:15
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.
...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-06 09:26:02
Jest jeszcze jedna możliwość, nieco czystsza:
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;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-06 09:38:55
- (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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-07 21:34:54