Как рассчитать время в часах между двумя датами в iOS

103

Как я могу рассчитать время, прошедшее в часах между двумя моментами (возможно, в разные дни) в iOS?

iosrookie
источник
1
Другой вариант заключается в использовании NSCalendar«s -components:fromDate:toDate:options:метода.
Томас Мюллер
Я не верю, что это даст вам абсолютное количество часов. Это даст вам только значение от 0 до 24, где вы должны полагаться на компоненты День, Месяц и Год, чтобы получить полный интервал времени.
codeperson
Я тестировал это, и он отлично работает. С fromDate 1 / Jan / 2012 и toDate 4 / Jan / 2012 это вернуло 96 часов.
Thomas Müller
разместить свой код Томас? У некоторых это не работает.
Джон Риселвато

Ответы:

171

NSDate функция timeIntervalSinceDate: даст вам разницу двух дат в секундах.

 NSDate* date1 = someDate;
 NSDate* date2 = someOtherDate;
 NSTimeInterval distanceBetweenDates = [date1 timeIntervalSinceDate:date2];
 double secondsInAnHour = 3600;
 NSInteger hoursBetweenDates = distanceBetweenDates / secondsInAnHour;

См. Справочную библиотеку Apple http://developer.apple.com/library/mac/navigation/, или, если вы используете Xcode, просто выберите справку / документацию в меню.

Смотрите: как-преобразовать-время-интервал-секунды в минуты

--редактировать: см. . ответ ÐąrέÐέvil ниже для правильной обработки летнего времени / дополнительных секунд

Акусете
источник
2
А что произойдет, если даты и время пересекают переход на летнее время?
Abizern
2
@Abizern: Спасибо, я не рассматривал те случаи, когда отвечал на вопрос. Я связался с ответом ÐąrέÐέvil
Akusete
У меня есть временной интервал вроде 4:50:30, ч: мин: си, мне нужно вычесть это время из 12:30:20, как я это сделаю
AyAz
90
NSCalendar *c = [NSCalendar currentCalendar];
NSDate *d1 = [NSDate date];
NSDate *d2 = [NSDate dateWithTimeIntervalSince1970:1340323201];//2012-06-22
NSDateComponents *components = [c components:NSHourCalendarUnit fromDate:d2 toDate:d1 options:0];
NSInteger diff = components.minute;

NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit

Измените необходимые компоненты на день, час или минуту, какая разница вам нужна. Если NSDayCalendarUnitвыбран этот параметр, он будет возвращать количество дней между двумя датами аналогично для NSHourCalendarUnitиNSMinuteCalendarUnit

Версия Swift 4

let cal = Calendar.current
let d1 = Date()
let d2 = Date.init(timeIntervalSince1970: 1524787200) // April 27, 2018 12:00:00 AM
let components = cal.dateComponents([.hour], from: d2, to: d1)
let diff = components.hour!
аахсанали
источник
Какую дату валютирования с TimeIntervalSince1970 принять? Я считаю, что вы преобразовали дату 2012-06-22 в 1340323201. Пожалуйста, поправьте меня.
Jeet
У меня не работает. Получено значение разности 9223372036854775807. Оно выражено в миллисекундах?
Кирти Никам 02
Swift 4.2. Вместо [.hour] можно использовать Set <Calendar.Component> ([. Hour])
Иван Павлюк
19
-(NSMutableString*) timeLeftSinceDate: (NSDate *) dateT {

    NSMutableString *timeLeft = [[NSMutableString alloc]init];

    NSDate *today10am =[NSDate date];

    NSInteger seconds = [today10am timeIntervalSinceDate:dateT];

    NSInteger days = (int) (floor(seconds / (3600 * 24)));
    if(days) seconds -= days * 3600 * 24;

    NSInteger hours = (int) (floor(seconds / 3600));
    if(hours) seconds -= hours * 3600;

    NSInteger minutes = (int) (floor(seconds / 60));
    if(minutes) seconds -= minutes * 60;

    if(days) {
        [timeLeft appendString:[NSString stringWithFormat:@"%ld Days", (long)days*-1]];
    }

    if(hours) {
        [timeLeft appendString:[NSString stringWithFormat: @"%ld H", (long)hours*-1]];
    }

    if(minutes) {
        [timeLeft appendString: [NSString stringWithFormat: @"%ld M",(long)minutes*-1]];
    }

    if(seconds) {
        [timeLeft appendString:[NSString stringWithFormat: @"%lds", (long)seconds*-1]];
    }

    return timeLeft;
}
Ашиш Патель
источник
9
Нет, не делай этого. Не все часы имеют 3600 секунд. Не во всех днях есть 24 часа.
rmaddy
5
Это совершенно неверно. Без учета дополнительных секунд и перехода на летнее время. Пожалуйста, не изобретайте велосипед, просто используйте API, предоставляемые с iOS, такие как NSDateComponents.
Хуан Каталон,
5

Оформление заказа: учитывает переход на летнее время и високосный год, поскольку для расчета используется календарь iOS. Вы можете изменить строку и условия, включив минуты с часами и днями.

+(NSString*)remaningTime:(NSDate*)startDate endDate:(NSDate*)endDate {

    NSDateComponents *components;
    NSInteger days;
    NSInteger hour;
    NSInteger minutes;
    NSString *durationString;

    components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute
                                                 fromDate: startDate toDate: endDate options: 0];
    days = [components day];
    hour = [components hour];
    minutes = [components minute];

    if (days > 0) {

        if (days > 1) {
            durationString = [NSString stringWithFormat:@"%d days", days];
        }
        else {
            durationString = [NSString stringWithFormat:@"%d day", days];
        }
        return durationString;
    }

    if (hour > 0) {

        if (hour > 1) {
            durationString = [NSString stringWithFormat:@"%d hours", hour];
        }
        else {
            durationString = [NSString stringWithFormat:@"%d hour", hour];
        }
        return durationString;
    }

    if (minutes > 0) {

        if (minutes > 1) {
            durationString = [NSString stringWithFormat:@"%d minutes", minutes];
        }
        else {
            durationString = [NSString stringWithFormat:@"%d minute", minutes];
        }
        return durationString;
    }

    return @"";
}
Анкиш Джайн
источник
разница не превышает 12 часов. Если я хочу проверить некоторые условия в 23 часа, то как получить разницу в 23 часа?
Moxarth
Это дает неправильный временной интервал, у меня не работает.
Арвинд Патель,
3

Для тех, кто использует swift 3 и выше,

    let dateString1 = "2018-03-15T14:20:00.000Z"
    let dateString2 = "2018-03-20T14:20:00.000Z"

    let Dateformatter = DateFormatter()
    Dateformatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

    let date1 = Dateformatter.date(from: dateString1)
    let date2 = Dateformatter.date(from: dateString2)

    let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
    let secondsInAnHour: Double = 3600
    let secondsInDays: Double = 86400
    let secondsInWeek: Double = 604800

    let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
    let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
    let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))

    print(weekBetweenDates,"weeks")//0 weeks
    print(daysBetweenDates,"days")//5 days
    print(hoursBetweenDates,"hours")//120 hours
Джон Раджа
источник