2010-11-08 55 views
2

我有一個類,它包含開始日期和結束日期,通常初始化爲本月的最後一秒。NSDate月加法和減法

以下功能才能正常工作從2010年11月向前進入十二月,然後再返回但是從十一月倒退結束了的startDate設爲

2010-09-30 23:00:00 GMT

即,一個月和一個小時前。

奇怪的結束日期仍然正確設置爲

2010-11-01 00:00:00 GMT

,還是今後每月從這個不正確的日期也導致在正確的時間和日期。

這是一個錯誤還是我正在做一些我不該做的事情?

 
-(void) moveMonth:(NSInteger)byAmount { // Positive or negative number of months 
    NSCalendar *cal = [NSCalendar currentCalendar]; 

NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease]; 
// Update the start date 
[components setMonth:byAmount]; 
NSDate *newStartDate = [cal dateByAddingComponents:components toDate:[self startDate] options:0]; 
[self setStartDate:newStartDate]; 

// And the end date 
[components setMonth:1]; 
NSDate *newEndDate = [cal dateByAddingComponents:components toDate:[self startDate] options:0 ]; 
[self setEndDate:newEndDate]; 
} 

SOLUTION:回答正確地指出,這是一個問題,DST

如果你要處理的絕對時間和日期,然後使用以下避免捲入任何DST。

 
    NSCalendar *cal = [[NSCalendar alloc ] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 
    NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"GMT"]; 
    [cal setTimeZone:zone]; 

回答

5

這可能不是一個錯誤,而是與10月到11月期間DST變化相關的問題。

+0

就是這樣,我很遺憾忘了。 – 2010-11-08 14:50:50

1

僅抓取當前日期的月份和年份,添加/減去月份數差異,然後從這些新值中生成日期會更容易。沒有必要擔心夏令時,閏年,等等。像這樣的事情應該工作:

-(void) moveMonth:(NSInteger)byAmount { 
    NSDate *now = [NSDate date]; 
    NSCalendar *cal = [NSCalendar currentCalendar]; 

    // we're just interested in the month and year components 
    NSDateComponents *nowComps = [cal components:(NSYearCalendarUnit|NSMonthCalendarUnit) 
             fromDate:now]; 
    NSInteger month = [nowComps month]; 
    NSInteger year = [nowComps year]; 

    // now calculate the new month and year values 
    NSInteger newMonth = month + byAmount; 

    // deal with overflow/underflow 
    NSInteger newYear = year + newMonth/12; 
    newMonth = newMonth % 12; 

    // month is 1-based, so if we've ended up with the 0th month, 
    // make it the 12th month of the previous year 
    if (newMonth == 0) { 
     newMonth = 12; 
     newYear = newYear - 1; 
    } 

    NSDateComponents *newStartDateComps = [[NSDateComponents alloc] init]; 
    [newStartDateComps setYear: year]; 
    [newStartDateComps setMonth: month]; 
    [self setStartDate:[cal dateFromComponents:newDateComps]]; 
    [newDateComps release]; 

    // Calculate newEndDate in a similar fashion, calling setMinutes:59, 
    // setHour:23, setSeconds:59 on the NSDateComponents object if you 
    // want the last second of the day 
} 
0

這裏是一個方式做正確。此方法在添加/減去月份「byAmount」後返回新的NSDate。

-(NSDate*) moveMonth:(NSInteger)byAmount { 

    NSDate *now = [NSDate date]; 

    NSDateComponents *components = [[NSDateComponents alloc] init]; 
    [components setMonth:byAmount]; 

    NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:now options:0]; 

    return newDate; 
}