首页 文章

NSDate月加法和减法

提问于
浏览
2

我有一个 class ,其中包含开始日期和结束日期,通常初始化为该月的最后一个月和最后一个月 .

以下功能可以正常工作,从2010年11月开始到12月再返回,但是从11月开始倒退,最后将startDate设置为

2010-09-30 23:00:00 GMT

IE浏览器 . 一个月一小时前 .

奇怪的是,endDate仍然正确设置为

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

解决方案:正确回答指出这是DST问题

如果您想要处理绝对时间和日期,那么使用以下内容可以避免涉及任何DST .

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

3 回答

  • 1

    这可能不是一个错误,而是与10月至11月期间DST变化有关的事情 .

  • 0

    只需 grab 当前日期的月份和年份,添加/减去月份差异,然后从这些新值生成日期就更容易了 . 无需担心夏令时变化,闰年等 . 这样的事情应该有效:

    -(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
    }
    
  • 5

    这是一种正确的方法 . 在添加/减去月份“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;
    }
    

相关问题