如何计算两个日期之间的差额?


Answers:


237
NSDate *date1 = [NSDate dateWithString:@"2010-01-01 00:00:00 +0000"];
NSDate *date2 = [NSDate dateWithString:@"2010-02-03 00:00:00 +0000"];

NSTimeInterval secondsBetween = [date2 timeIntervalSinceDate:date1];

int numberOfDays = secondsBetween / 86400;

NSLog(@"There are %d days in between the two dates.", numberOfDays);

编辑:

请记住,NSDate对象代表确切的时刻,它们没有任何关联的时区信息。当您使用例如一个字符串转换为日期NSDateFormatter时,NSDateFormatter从配置的时区的时间转换。因此,两个NSDate对象之间的秒数始终是时区不可知的。

此外,本文档还指定可可的时间实现方式不包含leap秒,因此,如果您需要这种准确性,则需要滚动自己的实现方式。


5
@RalucaGurau:86400是一天中的秒数(即60秒,60分钟,24小时)。与月份无关。
dreamlax 2012年

18
并非所有的日子都有86400秒。举一个简单的例子,这很好,但是在现实世界中并不是一个好主意。DST更改,leap秒等等都可能使它混乱。NSCalendar可以告诉您一天中有几秒钟。
NeilInglis 2012年

2
@muthukumar:未在iOS上,该方法仅适用于Mac OS X的这个问题是标签cocoa,而不是cocoa-touch那么这个答案只适用于Mac OS X.
dreamlax

1
任何两个时间间隔之间的天数始终为86400。人类是否处于愚弄自己比正常情况早起一小时的阶段,对一天的长度为86400秒(忽略跳跃)的事实没有影响。秒)
dreamlax

1
只是想补充一下,如果最后没有+0000,那么无论如何,您都会在diff上获得空日期和始终为0的值。因此,请不要陷入陷阱。
Volomike

84

您可能要使用以下内容:

NSDateComponents *components;
NSInteger days;

components = [[NSCalendar currentCalendar] components: NSDayCalendarUnit 
        fromDate: startDate toDate: endDate options: 0];
days = [components day];

我相信这种方法可以解决诸如夏令时变化之类的日期。


2
是否有一种简单的方法也可以忽略给定日期的时间?
米海·蒂玛尔

可以相应地更改其他日历单位:)用于年份单位。
精通技术的人,2014年

NSDate对象已经与时区无关。当使用例如解析日期时,时区信息将被删除NSDateFormatter,以便NSDate对象表示确切的时间点。因此,如果您已有startDateendDate,则这两个对象之间的间隔为x秒。时区与它无关。
dreamlax 2014年

@Benjamin:为什么这么说?
dreamlax 2014年

dreamlax,您的答案是错误的。干净利落。计算从1月1日正午12点(标准时间)到4月1日正午12点(标准时间)之间的天数,您的公式将不起作用。这是一个懒惰的公式,开发人员应使用NSDateComponents对象进行计算。
Rickster

25
NSTimeInterval diff = [date2 timeIntervalSinceDate:date1]; // in seconds

date1date2NSDate

另外,请注意以下定义NSTimeInterval

typedef double NSTimeInterval;

请注意,NSTimeInterval实际上是一个双精度型,因此您可以像使用其他任何数字一样使用它。
Kendall Helmstetter Gelner 2010年

19

签出这个。它使用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 @""; 
}

这种方法是计算时差的理想方法。
Moxarth

只要您可以将ifif与所有if条件保持在一起。否则,您只会得到一种显示的时间格式。
Moxarth

3

使用Swift 5和iOS 12,根据您的需要,您可以使用以下两种方法之一来查找两天之间的日期差异。


#1。使用CalendardateComponents(_:from:to:)方法

import Foundation

let calendar = Calendar.current

let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!

let dateComponents = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)

print(dateComponents) // prints: day: 1621 isLeapMonth: false
print(String(describing: dateComponents.day)) // prints: Optional(1621)

#2。使用DateComponentsFormatterstring(from:to:)方法

import Foundation

let calendar = Calendar.current

let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [NSCalendar.Unit.day]

let elapsedTime = formatter.string(from: startDate, to: endDate)
print(String(describing: elapsedTime)) // prints: Optional("1,621 days")

1

Swift 4
试试看,看一下(带字符串的日期范围):

// Start & End date string
let startingAt = "01/01/2018"
let endingAt = "08/03/2018"

// Sample date formatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"

// start and end date object from string dates
var startDate = dateFormatter.date(from: startingAt) ?? Date()
let endDate = dateFormatter.date(from: endingAt) ?? Date()


// Actual operational logic
var dateRange: [String] = []
while startDate <= endDate {
    let stringDate = dateFormatter.string(from: startDate)
    startDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate) ?? Date()
    dateRange.append(stringDate)
}

print("Resulting Array - \(dateRange)")

迅捷3

var date1 = Date(string: "2010-01-01 00:00:00 +0000")
var date2 = Date(string: "2010-02-03 00:00:00 +0000")
var secondsBetween: TimeInterval = date2.timeIntervalSince(date1)
var numberOfDays: Int = secondsBetween / 86400
print(numberOfDays)

并非所有的日子都有那么多秒。
帕万

@Pavan-欢迎您通过更新此答案并将其改进来分享您的意见。
Krunal

为了使它更好,需要我重写您的整个答案,在这种情况下,也可以将其删除,因为它与上面的答案是相同的解决方案,并且不使用硬编码值:)
Pavan

0

您可以通过以秒为单位转换日期并采用自1970年以来的时间间隔来找到差异,然后可以找到两个日期之间的差异。


当两个日期可以直接相互计算时(假设相同的时域)。是否有特定的原因先计算两个1970年以来的日期,然后再求差?
Adeel

0

要发现差异,您需要获取当前日期和将来的日期。在以下情况下,我以2天作为未来日期的示例。计算方式:

2 days* 24 hours* 60 minutes* 60 seconds。我们预计2天的秒数为172,800。

// Set the current and future date
let now = Date()
let nowPlus2Days = Date(timeInterval: 2*24*60*60, since: now)

// Get the number of seconds between these two dates
let secondsInterval = DateInterval(start: now, end: nowPlus2Days).duration

print(secondsInterval) // 172800.0

1
请不要只发布代码作为答案,还请提供解释代码的作用以及如何解决问题的方法。带有解释的答案通常质量更高,并且更有可能吸引投票。
Mark Rotteveel
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.