Get number of days between two NSDate dates in a particular timezone

喜你入骨 提交于 2019-12-09 11:37:30

问题


I found the codes to calculate days difference between two dates here.
I write a method :

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

This method has a problem: it can't consider the timezone thing. Even I add a line like this:

[gregorian setTimeZone:[NSTimeZone localTimeZone]];

My test code is like this:

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

The result is:

Days difference between 2012-09-03 23:00:00 and 2012-09-04 01:00:00 is: 0 days

I want to get 1 day as result by the number of midnights between the two dates. My timezone is GMT +8. But this calculation is based on GMT, so I get the wrong days number. Is there anyway to solve this problem? Thank you.


Scott Lemmon's method can solve my problem. I rewrite my code like this:

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

回答1:


If the time zone offset isn't working, how about just add or subtract it manually instead?

In your case NSDate *newDate = [oldDate dateByAddingTimeInterval:(-8 * 60 * 60)]; to subtract off your +8 hours.

Or if you want to find the GMT offset automatically as well then it would simply be NSDate *newDate = [oldDate dateByAddingTimeInterval:(-[[NSTimeZone localTimeZone] secondsFromGMT])

Another thought: A perhaps easier solution would be to just disregard the time information altogether. Just set it to the same arbitrary number for both dates, then as long as the dates come from the same timezone you will always get the correct number of mid-nights between them, regardless of GMT offset.




回答2:


What you really want is the NSDate method timeIntervalSinceDate:, and take that result and if it's more than 0 but less than 86400 (the number of seconds in a day), that's one day. Otherwise, divide your result by 86400 and you'll get the number of days.

The way you currently have your code, there's only 2 hours between the two days and that's why you are seeing a result of 0 and not one.

Edit - and to determine if midnight has happened, let's try this function I just wrote off the top of my head:

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

which I'm basing off Dave Delong's answer to this question. No guarantees that my code will work (I didn't test it), but I think the concept is sound.



来源:https://stackoverflow.com/questions/12257937/get-number-of-days-between-two-nsdate-dates-in-a-particular-timezone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!