Cómo calcular el tiempo en horas entre dos fechas en iOS

103

¿Cómo puedo calcular el tiempo transcurrido en horas entre dos momentos (posiblemente ocurriendo en días diferentes) en iOS?

iosrookie
fuente
1
Otra opción es utilizar NSCalendarel -components:fromDate:toDate:options:método de.
Thomas Müller
No creo que esto le dé un número absoluto de horas. Solo le dará un valor de 0-24, donde debe confiar en los componentes Día, Mes y Año para obtener el intervalo de tiempo completo.
codeperson
Probé esto y funciona bien. Con fromDate 1 / Jan / 2012 y toDate 4 / Jan / 2012, esto devolvió 96 horas.
Thomas Müller
publica tu código Thomas? No funciona para algunos.
John Riselvato

Respuestas:

171

El NSDate función timeIntervalSinceDate: le dará la diferencia de dos fechas en cuestión de segundos.

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

Consulte la biblioteca de referencia de Apple http://developer.apple.com/library/mac/navigation/ o si está usando Xcode, simplemente seleccione ayuda / documentación en el menú.

Ver: cómo-convertir-un-n-tiempo-intervalo-segundos-en-minutos

--editar: Vea la respuesta de ÐąrέÐέvil a continuación para manejar correctamente el horario de verano / segundos bisiestos

Akusete
fuente
2
¿Y qué sucede si las fechas / horas cruzan la transición del horario de verano?
Abizern
2
@Abizern: Gracias, no estaba considerando esos casos cuando respondí la pregunta. Me he vinculado a la respuesta de ÐąrέÐέvil
Akusete
tengo un intervalo de tiempo como 4:50:30, h: m: si tengo que restar este tiempo de 12:30:20 cómo haré esto
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

Cambie los componentes necesarios por día, hora o minuto, la diferencia que desee. Si NSDayCalendarUnitse selecciona, devolverá el número de días entre dos fechas de manera similar para NSHourCalendarUnityNSMinuteCalendarUnit

Versión 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
fuente
¿Qué valor acepta dateWithTimeIntervalSince1970? Creo que ha convertido la fecha 2012-06-22 a 1340323201. Por favor corríjame.
Jeet
No funciona para mi. El valor de la diferencia es 9223372036854775807. ¿Está en milisegundos?
Kirti Nikam
Rápido 4.2. En lugar de [.hora] puede utilizar Establecer <Calendar.Component> ([. Hora])
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
fuente
9
No, no hagas esto. No todas las horas tienen 3600 segundos. No todos los días tienen 24 horas.
rmaddy
5
Esto está totalmente mal. No tiene en cuenta los segundos intercalares ni el horario de verano. No reinvente la rueda, solo use las API proporcionadas con iOS como NSDateComponents.
Juan Catalán
5

Pago: Se encarga del horario de verano, año bisiesto, ya que usó el calendario de iOS para calcular. Puede cambiar la cadena y las condiciones para incluir minutos con horas y días.

+(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 @"";
}
Ankish Jain
fuente
no muestra más de 12 horas de diferencia. Si quiero verificar algunas condiciones a las 23 horas, ¿cómo obtener 23 horas de diferencia entre horas?
Moxarth
Da un intervalo de tiempo incorrecto, no funciona para mí.
Arvind Patel
3

Para aquellos que usan swift 3 y 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
fuente