获取特定时区中两个NSDate日期之间的天数



我在这里找到了计算两个日期之间天数差的代码
我写了一个方法:

-(NSInteger)daysWithinEraFromDate:(NSDate *) startDate toDate:(NSDate *) endDate
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSGregorianCalendar];
    NSInteger startDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                            inUnit: NSEraCalendarUnit forDate:startDate];
    NSInteger endDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                          inUnit: NSEraCalendarUnit forDate:endDate];
    return endDay-startDay;
}

这个方法有一个问题:它不能考虑时区的问题。甚至我还加了一行:

[gregorian setTimeZone:[NSTimeZone localTimeZone]];

我的测试代码是这样的:

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *strDate = @"2012-09-03 23:00:00";
    NSDate *dateStart = [dateFormat dateFromString:strDate];
    strDate = @"2012-09-04 01:00:00";
    NSDate *dateEnd = [dateFormat dateFromString:strDate];
    NSLog(@"Days difference between %@ and %@  is:  %d days",[dateFormat stringFromDate:dateStart],[dateFormat stringFromDate:dateEnd],[self daysWithinEraFromDate:dateStart toDate:dateEnd]);

结果是:

2012-09-03 23:00:00和2012-09-04 01:00:00之间的天数差为:0天

根据两次约会之间的午夜次数,我想得到一天的时间。我的时区是GMT+8。但是这个计算是基于GMT的,所以我得到了错误的天数。有办法解决这个问题吗?非常感谢。


Scott Lemmon的方法可以解决我的问题。我这样重写代码:

-(NSInteger)daysWithinEraFromDate:(NSDate *) startDate toDate:(NSDate *) endDate
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSGregorianCalendar];
    [gregorian setTimeZone:[NSTimeZone localTimeZone]];
    NSDate *newDate1 = [startDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]];
    NSDate *newDate2 = [endDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]];
    NSInteger startDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                            inUnit: NSEraCalendarUnit forDate:newDate1];
    NSInteger endDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                          inUnit: NSEraCalendarUnit forDate:newDate2];
    return endDay-startDay;
}

如果时区偏移量不起作用,不如手动加减?

在您的情况下,NSDate *newDate = [oldDate dateByAddingTimeInterval:(-8 * 60 * 60)];减去您的+8小时。

或者,如果你也想自动找到GMT偏移量,那么它只需要NSDate *newDate = [oldDate dateByAddingTimeInterval:(-[[NSTimeZone localTimeZone] secondsFromGMT])

另一个想法:一个可能更简单的解决方案是完全忽略时间信息。只需为两个日期设置相同的任意数字,那么只要日期来自同一时区,无论GMT偏移量如何,您都将始终获得它们之间的正确午夜数。

您真正想要的是NSDate方法timeIntervalSinceDate:,取该结果,如果它大于0但小于86400(一天中的秒数),则为一天。否则,把你的结果除以86400,你就会得到天数。

按照你目前的代码方式,两天之间只有2个小时,这就是为什么你看到的结果是0而不是1。

编辑-为了确定午夜是否已经发生,让我们试试我刚刚在脑海中写下的这个功能:

- (NSDate *) getMidnightDateFromDate: (NSDate *) originalDate
{
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSIntegerMax fromDate:originalDate];
    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];
    NSDate *midnight = [[NSCalendar currentCalendar] dateFromComponents:components];
    return(midnight);
}
- (BOOL) howManyDaysDifferenceBetween: startDate and: endDate
{
    NSDate * firstMidnight = [self getMidnightDateFromDate: startDate];
    NSDate * secondMidnight = [self getMidnightDateFromDate: endDate];
    NSTimeInterval timeBetween = [firstMidnight timeIntervalSinceDate: secondMidnight];
    NSInteger numberOfDays = (timeBetween / 86400);
    return(numberOfDays);
}

这是基于戴夫·德龙对这个问题的回答。不能保证我的代码会工作(我没有测试它),但我认为这个概念是合理的。

最新更新