Objective-C 计算两个日期之间的天数

发布于 2024-10-10 03:10:41 字数 449 浏览 5 评论 0 原文

可能的重复:
如何比较两个日期并返回一个数字天数

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

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

我想实现:

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

}

Possible Duplicate:
How can I compare two dates, return a number of days

I have two dates (as NSString in the form "yyyy-mm-dd"), for example:

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

I'd like to implement:

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

趴在窗边数星星i 2024-10-17 03:10:41
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]);
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 now holds the difference.

NSLog(@"%ld", [components day]);
春夜浅 2024-10-17 03:10:41

有完整的日期和时间编程指南。这是相关部分 为您提供有关操作的提示。

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

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

编辑

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

首先,我会扩展 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);

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

There is a whole guide to Date and Time Programming. Here is a relevant section which gives you a hint about what to do.

It's where the example code comes from in the other question.

Try and write something based on that and then come back if you have specific questions.

Edit

Okay. Here is how I would write the code in it's most basic form.

First, I would extend NSDate.

The header file:

//  NSDate+ADNExtensions.h

#import <Cocoa/Cocoa.h>


@interface NSDate (ADNExtensions)

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

@end

The implementation file:

//  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

This is very rough code. There is no error checking or validating that the second date is later than the first.

And then I would use it like this (running on a 64-bit, Garbage Collected environment):

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

This is such a shame, because you would have learned a lot more by posting your code and the incorrect outputs and getting more specific help. But if you just want to be a cut-and-paste programmer; take this code and good luck to you.

扛起拖把扫天下 2024-10-17 03:10:41

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

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

}

Swift 4 implementation

Method call :

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

Method Implementation:

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

Objective C implementation:

Method Call:

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

Method Implementation:

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

}
倒带 2024-10-17 03:10:41

这段代码似乎在 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
}

This code seems to work nicely in 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
}
满身野味 2024-10-17 03:10:41

ObjC 代码:

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

结果:

int totalDays = (int)dateComponent.day;

ObjC Code:

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

Result:

int totalDays = (int)dateComponent.day;
北风几吹夏 2024-10-17 03:10:41

斯威夫特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!

Swift 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!
顾挽 2024-10-17 03:10:41

上面提到的例子只代表了解决方案的一半,因为大多数解决方案在计算差异时只考虑日期值(例如: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 小时。

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

  • 所需的结果基于时差。

或者

  • 时间没有定义差异。

但是,如果您想根据日历日期更改计算天数差异,那么就会出现问题,因为在上面的示例中,即使日历日期更改,但结果将是 天数 = 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 

更多详细信息请参阅 这里

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

The examples mentioned above represent only half picture of the solution because most of the solution only take date value (e.g: 2010-11-01) into account when calculating the difference however in-real world scenario NSDate instance always come together with time and impact the difference on the result as well.

Now, let's talk about the accepted solution where user defined the two dates but not time for them.

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

Here the time for both dates would be same because no time has been provided for them which means it doesn't impact on the difference calculation.

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

And the result would be days = 1

Now let's add a specific time for both dates:

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

After adding a specific time the result would change. Now days = 0 even though day defined in the dates are different. It's because the time difference between the two dates is less than 24 hours.

This calculation method is gonna work fine as long as:

  • Desired result is based on time difference.

Or

  • Time is not defined for difference.

However, if you wanna calculate the days difference based on calendar date change then there would a problem because in the above example even though calendar date changed but the result would be days = 0. It's because of the time difference is less than 24 hours.

So, how we can calculate the days difference based on calendar date change. Here is the Apple suggested way of doing it:

@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 

More details are available here

My two cent on the topic to represent the remaining half of the picture.

画离情绘悲伤 2024-10-17 03:10:41

输入图片此处描述

 let date1Start = Calendar.current.startOfDay(for: date1)
    let date2Start = Calendar.current.startOfDay(for: date2)
    let dayDiff2 = Calendar.current.dateComponents([.day], from: date1Start, to: date2Start).day

enter image description here

 let date1Start = Calendar.current.startOfDay(for: date1)
    let date2Start = Calendar.current.startOfDay(for: date2)
    let dayDiff2 = Calendar.current.dateComponents([.day], from: date1Start, to: date2Start).day
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文