【问题标题】:Calculating the number of days between two dates in Objective-C在 Objective-C 中计算两个日期之间的天数
【发布时间】:2011-06-02 07:40:22
【问题描述】:

可能重复:
How can I compare two dates, return a number of days

我有两个日期(作为“yyyy-mm-dd”形式的 NSString),例如:

NSString *start = "2010-11-01";
NSString *end = "2010-12-01";

我想实现:

- (int)numberOfDaysBetween:(NSString *)startDate and:(NSString *)endDate {

}

【问题讨论】:

标签: objective-c ios nsstring nsdate


【解决方案1】:

有一个完整的日期和时间编程指南。这是relevant section,它会提示您该做什么。

这是另一个问题中示例代码的来源。

尝试在此基础上写一些东西,然后如果您有具体问题再回来。

编辑

好的。以下是我将如何以最基本的形式编写代码。

首先,我会扩展 NSDate。

头文件:

//  NSDate+ADNExtensions.h

#import <Cocoa/Cocoa.h>


@interface NSDate (ADNExtensions)

- (NSInteger)numberOfDaysUntil:(NSDate *)aDate;

@end

实现文件:

//  NSDate+ADNExtensions.m

#import "NSDate+ADNExtensions.h"


@implementation NSDate (ADNExtensions)


- (NSInteger)numberOfDaysUntil:(NSDate *)aDate {
    NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

    NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit fromDate:self toDate:aDate options:0];

    return [components day];
}


@end

这是非常粗略的代码。没有错误检查或验证第二个日期晚于第一个日期。

然后我会像这样使用它(在 64 位垃圾收集环境中运行):

NSDate *startDate = [NSDate dateWithString:@"2010-11-01 00:00:00 +0000"];
NSDate *endDate = [NSDate dateWithString:@"2010-11-02 00:00:00 +0000"];

NSInteger difference = [startDate numberOfDaysUntil:endDate];

NSLog(@"Diff = %ld", difference);

这太可惜了,因为通过发布代码和不正确的输出并获得更具体的帮助,您会学到很多东西。但是如果你只是想成为一个剪切粘贴程序员;拿着这个代码,祝你好运。

【讨论】:

  • 你能不能只提供代码?老实说,我尝试了很多东西。我尝试过使用 Gregarian,也尝试过获取 NSTimeInterval。请只执行该方法?
  • 罗伯特,这不是一个“给我代码”的网站。就您遇到的问题提出问题,您将收到帮助来解决该问题。人们不仅会为你解决问题。您越早了解这一点,您就能越早从 Stack Overflow 上的人们那里得到更好的答案。我认为 Abizer 在给你代码方面有点了。 ;)
  • 顺便说一句,我不确定NSDate 方法dateWithString 是否存在,但至少它很久以前就被弃用了,所以第二个答案更相关,你必须使用@987654327 @现在
  • 呵呵,我是来找这样的sn-p代码的,现在我的罪孽深重,哈哈!
  • 你不需要扩展类,只是为了写一个简单的辅助方法。
【解决方案2】:
NSString *start = @"2010-09-01";
NSString *end = @"2010-12-01";

NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:@"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];

NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay
                                                    fromDate:startDate
                                                      toDate:endDate
                                                     options:0];

components 现在拥有不同之处。

NSLog(@"%ld", [components day]);

【讨论】:

  • 我们究竟如何从组件中访问它?
  • @RamyAlZuhouri,你为什么需要 f 是静态的?
  • @SpacePyro:算了,这是我在别处说过的双关语。
  • @RamyAlZuhouri 哈哈,明白了。我在那里担心了一秒钟。 ;)
  • 我实际上认为这不能正常工作。尝试使用真正的NSDate 组件,看看结果是 1 天,因为有些没有 > 24 小时的差异
【解决方案3】:

这段代码似乎在 Swift 2 中运行良好:

func daysBetweenDate(startDate: NSDate, endDate: NSDate) -> Int
{
    let calendar = NSCalendar.currentCalendar()

    let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])

    return components.day
}

【讨论】:

    【解决方案4】:

    ObjC 代码:

    NSDateComponents *dateComponent = [calender components:NSCalendarUnitDay fromDate:startDate toDate:endDate options:0];
    

    结果:

    int totalDays = (int)dateComponent.day;
    

    【讨论】:

      【解决方案5】:

      斯威夫特 3:

      let formatter = DateFormatter()
      formatter.dateFormat = "yyyy-MM-dd"
      let start = formatter.date(from: "2010-09-01")!
      let end = formatter.date(from: "2010-12-01")!
      let days = Calendar.current.dateComponents([.day], from: start, to: end).day!
      

      【讨论】:

        【解决方案6】:

        Swift 4 实现

        方法调用:

        let numberOfDays = daysBetweenDates(startDate: fileCreatedDate,endDate: date)
        

        方法实现:

         func daysBetweenDates(startDate: Date, endDate: Date) -> Int {
                let daysBetween = Calendar.current.dateComponents([.day], from: startDate, to: endDate)
                print(daysBetween.day!)
                return daysBetween.day!
          }
        

        目标 C 实现:

        方法调用:

        int numberOfDaysSinceFileCreation = [self daysBetweenDates: fileCreatedDate
                                                                           currentDate: today];
        

        方法实现:

        - (int) daysBetweenDates: (NSDate *)startDate currentDate: (NSDate *)endDate
        {
            NSCalendar *calendar = [NSCalendar currentCalendar];
            NSDateComponents *dateComponent = [calendar components:NSCalendarUnitDay fromDate:startDate toDate:endDate options:0];
        
            int totalDays = (int)dateComponent.day;
            return totalDays;
        
        }
        

        【讨论】:

          【解决方案7】:

          上述示例仅代表解决方案的一半,因为大多数解决方案在计算差异时仅考虑日期值(例如:2010-11-01)但是在现实世界中场景 NSDate 实例总是与时间结合在一起,也会影响结果的差异。

          现在,让我们谈谈用户定义两个日期但没有为它们定义时间的公认解决方案。

          NSString *start = @"2010-09-01";
          NSString *end = @"2010-09-02";
          
          NSDateFormatter *f = [[NSDateFormatter alloc] init];
          [f setDateFormat:@"yyyy-MM-dd"];
          NSDate *startDate = [f dateFromString:start];
          NSDate *endDate = [f dateFromString:end]; 
          

          这里两个日期的时间相同,因为没有为它们提供时间,这意味着它不会影响差异计算。

          startDate "2010-09-01 12:00 AM"
          endDate "2010-09-02 12:00 AM"
          

          结果将是 days = 1

          现在让我们为这两个日期添加一个具体时间:

          startDate "2010-09-01 02:00 PM"
          endDate "2010-09-02 02:00 AM"
          

          添加特定时间后,结果会发生变化。现在 days = 0 即使日期中定义的日期不同。 这是因为两个日期的时间差小于 24 小时。

          只要满足以下条件,这种计算方法就可以正常工作:

          • 所需结果基于时差。

          或者

          • 没有为差异定义时间。

          但是,如果您想根据日历日期更改计算天差,那么就会出现问题,因为在上面的示例中,即使日历日期更改了,但结果会是 days = 0。这是因为时差小于24小时。

          那么,我们如何根据日历日期变化计算天差。这是 Apple 建议的做法:

          @implementation NSCalendar (MySpecialCalculations)
          - (NSInteger)daysWithinEraFromDate:(NSDate *)startDate toDate:(NSDate *)endDate {
               NSInteger startDay=[self ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:startDate];
               NSInteger endDay=[self ordinalityOfUnit:NSDayCalendarUnit  inUnit: NSEraCalendarUnit forDate:endDate];
               return endDay - startDay;
          }
          @end 
          

          更多详情可here

          我在主题上的两分钱代表图片的剩余一半。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-02-26
            • 2019-09-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多