如何在iOS中计算两个日期之间的小时数


103

如何计算iOS中两次(可能发生在不同日期)之间经过的时间(以小时为单位)?


1
另一种选择是使用NSCalendar-components:fromDate:toDate:options:方法。
ThomasMüller,2010年

我认为这不会给您绝对的时间。它只会为您提供0-24之间的值,您必须依靠组件Day,Month和Year才能获得完整的时间间隔。
编码人员2012年

我对此进行了测试,它确实可以正常工作。从fromDate 1 / Jan / 2012和toDate 4 / Jan / 2012开始返回96小时。
ThomasMüller2012年

发布您的代码Thomas?它不适用于某些人。
约翰·里塞尔瓦托

Answers:


170

NSDate的功能timeIntervalSinceDate:给你两个日期的秒差。

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

请参阅苹果参考资料库 http://developer.apple.com/library/mac/navigation/, 或者如果您使用的是Xcode,则只需从菜单中选择帮助/文档即可

请参阅:如何将ns时间间隔秒转换为分钟

--edit:有关正确处理夏时制/ le秒的信息,请参见下面的бrέÐέvil答案


2
如果日期/时间越过夏时制,会发生什么?
阿比森

2
@Abizern:谢谢,回答问题时我没有考虑那些情况。我已经链接到ÐąrέÐέvil的答案
Akusete

我有类似4:50:30的时间段,h:m:si必须从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选择,则会返回两个日期之间的天数,类似于NSHourCalendarUnitNSMinuteCalendarUnit

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!

dateWithTimeIntervalSince1970接受什么值?我相信您已经将2012-06-22日期转换为1340323201。请纠正我。
Jeet 2012年

不为我工作。diff值为9223372036854775807。以毫秒为单位吗?
Kirti Nikam '17

斯威夫特4.2。代替[.hour],可以使用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
不,不要这样做。并非所有小时都有3600秒。并非全天都有24小时。
rmaddy 2015年

5
这是完全错误的。不占leap秒,节省夏时制。请不要仅仅使用iOS随附的API(例如NSDateComponents)来重新发明轮子。
胡安·加泰罗尼亚语

5

结帐:它使用iOS日历进行计算,可以解决夏令时,leap年的问题。您可以将字符串和条件更改为包括小时和天的分钟。

+(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'7

时间间隔错误,对我不起作用。
Arvind Patel

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.