Como calcular o tempo em horas entre duas datas no iOS

103

Como posso calcular o tempo decorrido em horas entre duas vezes (possivelmente ocorrendo em dias diferentes) no iOS?

iosrookie
fonte
1
Outra opção é usar NSCalendaro -components:fromDate:toDate:options:método de.
Thomas Müller
Não acredito que isso lhe dará um número absoluto de horas. Ele fornecerá apenas um valor de 0 a 24, onde você terá que contar com os componentes Dia, Mês e Ano para obter o intervalo de tempo integral.
codeperson de
Eu testei isso e funcionou muito bem. Com a data de 1 / jan / 2012 e a 4 / jan / 2012 retornou 96 horas.
Thomas Müller
poste seu código Thomas? Não funciona para alguns.
John Riselvato

Respostas:

171

O NSDate função timeIntervalSinceDate: vai dar-lhe a diferença de duas datas em segundos.

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

Consulte a biblioteca de referência da apple http://developer.apple.com/library/mac/navigation/ ou se você estiver usando o Xcode, selecione ajuda / documentação no menu.

Veja: how-to-convert-an-nstimeinterval-seconds-into-minutes

--edit: Veja a resposta de ÐąrέÐέvil abaixo para lidar corretamente com o horário de verão / segundos bissextos

Akusete
fonte
2
E o que acontece se as datas / horas cruzam a transição para o horário de verão?
Abizern
2
@Abizern: Obrigado, não estava considerando esses casos quando respondi à pergunta. Liguei para a resposta de ÐąrέÐέvil
Akusete
eu tenho um intervalo de tempo como 4:50:30, h: m: si tenho que subtrair este tempo de 12:30:20 como farei isso
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

Altere os componentes necessários para dia, hora ou minuto, a diferença que você deseja. Se NSDayCalendarUnitfor selecionado, ele retornará o número de dias entre duas datas de forma semelhante para NSHourCalendarUniteNSMinuteCalendarUnit

Versão 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!
aahsanali
fonte
Qual valor dateWithTimeIntervalSince1970 aceita? Acredito que você tenha convertido a data de 22/06/2012 para 1340323201. corrija-me.
Jeet
Não está funcionando para mim. Obteve o valor de diff como 9223372036854775807. Está em milissegundos?
Kirti Nikam
Swift 4.2. Em vez de [.hour], você pode usar Set <Calendar.Component> ([. Hour])
IvanPavliuk
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;
}
Ashish Patel
fonte
9
Não, não faça isso. Nem todas as horas têm 3600 segundos. Nem todos os dias têm 24 horas.
rmaddy
5
Isso está totalmente errado. Não leva em conta segundos bissextos, horário de verão. Não reinvente a roda, apenas use as APIs fornecidas com iOS como NSDateComponents.
Juan Catalan
5

Check-out: cuida do horário de verão, ano bissexto, pois usou o calendário iOS para calcular. Você pode alterar a string e as condições para incluir minutos com horas e dias.

+(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 @"";
}
Jain Ankish
fonte
não está mostrando mais de 12 horas de diferença. se eu quiser verificar algumas condições às 23 horas, como obter 23 horas de diferença entre os horários?
Moxarth
Está dando intervalo de tempo errado, não está funcionando para mim.
Arvind Patel
3

Para aqueles que usam o Swift 3 e superior,

    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
john raja
fonte