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

时间:2012-09-04 06:32:35

标签: objective-c datetime nstimezone

我找到了用于计算两个日期here之间天差的代码 我写了一个方法:

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

我想通过这两个日期之间的中午数量获得1天的结果。我的时区是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;
}

2 个答案:

答案 0 :(得分:5)

如果时区偏移不起作用,那么只需手动添加或减去它?

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

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

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

答案 1 :(得分:3)

你真正想要的是NSDate方法timeIntervalSinceDate:,并获取该结果,如果它超过0但小于86400(一天中的秒数),那就是一天。否则,将结果除以86400,您将获得天数。

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

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

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

我基于Dave Delong's answer to this question。不保证我的代码可以工作(我没有测试它),但我认为这个概念是合理的。