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?


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


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!

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

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 @"";
}

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.