【问题标题】:NSDate month addition and subtractionNSDate月份加减法
【发布时间】:2011-05-06 16:38:13
【问题描述】:

我有一个包含开始日期和结束日期的类,通常初始化为每月的第一秒和最后一秒。

以下函数从 2010 年 11 月向前到 12 月并再次返回正常工作,但是从 11 月向后返回最终将 startDate 设置为

格林威治标准时间 2010-09-30 23:00:00

即。一个月零一个小时前。

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

2010-11-01 00:00:00 GMT

从这个不正确的日期往前一个月也会得到正确的时间和日期。

这是一个错误还是我在做我不应该做的事情?

-(void) moveMonth:(NSInteger)byAmount { // 正数或负数月数 NSCalendar *cal = [NSCalendar currentCalendar]; NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease]; //更新开始日期 [组件 setMonth:byAmount]; NSDate *newStartDate = [cal dateByAddingComponents:components toDate:[self startDate] options:0]; [自我设置开始日期:新开始日期]; // 和结束日期 [组件集月:1]; NSDate *newEndDate = [cal dateByAddingComponents:components toDate:[self startDate] options:0 ]; [自我设置结束日期:新结束日期]; }

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

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

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

【问题讨论】:

    标签: iphone objective-c ios


    【解决方案1】:

    这可能不是错误,而是与 10 月至 11 月期间 DST 变化有关。

    【讨论】:

    • 原来是这样的,我太笨了忘记了。
    【解决方案2】:

    只获取当前日期的月份和年份,添加/减去月差数,然后从这些新值生成日期会更容易。无需担心夏令时变化、闰年等。这样的事情应该可以工作:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2011-06-04
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-01
        • 2019-07-30
        相关资源
        最近更新 更多