iPhone4 iOS5[[NSTimeZone localTimeZone]daylightSavingTimeOffset]夏令时错误?

iPhone4 iOS5[[NSTimeZone localTimeZone]daylightSavingTimeOffset]夏令时错误?,ios5,nsdate,dst,iphone-4,nstimezone,Ios5,Nsdate,Dst,Iphone 4,Nstimezone,我住在美国东部时区(EST),几周前夏令时开始了。我正在测试我以前的一些代码,这些代码(据推测)运行得很好,并注意到第二天的计算提前了1小时运行 以下是我用于测试的代码: int gmtOffset = [[NSTimeZone localTimeZone] secondsFromGMT]; int daylightOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffset]; int daySeconds = (

我住在美国东部时区(EST),几周前夏令时开始了。我正在测试我以前的一些代码,这些代码(据推测)运行得很好,并注意到第二天的计算提前了1小时运行

以下是我用于测试的代码:

 int  gmtOffset =  [[NSTimeZone localTimeZone] secondsFromGMT];
 int daylightOffset =  [[NSTimeZone localTimeZone] daylightSavingTimeOffset];

  int daySeconds =  ((int)([date timeIntervalSinceReferenceDate]+gmtOffset+daylightOffset))%(86400+1);

 NSLog(@"Day seconds: %i", daySeconds);
结果比预期值少3600秒。日光偏移量为0。如何正确获取用户所在时区的日光偏移?NSDateFormatter正确解析日期,因此它必须知道NSTimeZone没有告诉我的某些信息


谢谢大家!

如果要确定午夜后的秒数,可以使用日期组件。此代码针对夏令时进行适当调整

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone localTimeZone]];

NSDateComponents *comps = [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit| NSSecondCalendarUnit
                                      fromDate:[NSDate date]];
NSInteger time = [comps hour] * 3600 + [comps minute] * 60 + [comps second];

NSLog(@"Day seconds: %i", time);

如果要确定午夜后的秒数,可以使用日期组件。此代码针对夏令时进行适当调整

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone localTimeZone]];

NSDateComponents *comps = [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit| NSSecondCalendarUnit
                                      fromDate:[NSDate date]];
NSInteger time = [comps hour] * 3600 + [comps minute] * 60 + [comps second];

NSLog(@"Day seconds: %i", time);

[localTime secondsFromGMT]
返回包括夏令时在内的真实GMT,您可以通过
[localTime daylightSavingTimeOffset]
获取偏移量。
[localTime secondsFromGMT]
返回包括夏令时在内的真实GMT,您可以通过
[localTime daylightSavingTimeOffset]

这似乎是一个()问题,在把头发拉长太久之后,我终于解决了这个问题

本准则所依据的假设是:

  • 你对日期感兴趣,而不是时间
  • 您希望您的日期计算不受任何夏令时的影响
  • 您需要一个足够简单的日期字符串表示形式,以便可以持久化它
  • 为了实现1,我使用了唯一的NSCalendar实例,该实例被初始化为Gregorian,GMT 这也服务于2

    对于3,NSDateFormatter使用唯一日历及其时区进行初始化。 将格式化程序的时区设置为用于计算的日历的时区是我遇到的所有问题的关键

    这应该总是正确的(假设下面的代码是
    DateModel
    类的一部分):

    代码如下:

    + (NSDate *) normalize: (NSDate *) date {
        NSDateComponents * comps = [[DateModel calendar] components:NSYearCalendarUnit
                                                                |   NSMonthCalendarUnit
                                                                |   NSDayCalendarUnit
                                                                |   NSHourCalendarUnit
                                                                |   NSMinuteCalendarUnit
                                                                |   NSSecondCalendarUnit
                                                           fromDate:date] ;
    
        [comps setHour:0] ;
        [comps setMinute:0] ;
        [comps setSecond:0] ;
    
        NSDate * dateOnly = [[DateModel calendar] dateFromComponents:comps] ;
    
        return dateOnly ;
    }
    
    + (NSCalendar *) calendar {
        static NSCalendar * calendar = nil ;
        if (calendar == nil) {
            calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] ;
            calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"GMT"] ;
        }
        return calendar ;
    }
    
    + (NSDateFormatter *) dateFormatter {
        static NSDateFormatter * formatter = nil ;
        if (formatter == nil) {
            formatter = [[NSDateFormatter alloc] init] ;
            [formatter setCalendar:[self calendar]] ;          // <- This is
            [formatter setTimeZone:[self calendar].timeZone] ; // <- critical
            [formatter setDateFormat:@"yyyyMMdd"] ;
        }
        return formatter ;
    }
    
    + (NSDate *) dateFromString: (NSString *) stringDate {
        return [DateModel normalize: [[DateModel dateFormatter] dateFromString:stringDate]] ;
    }
    
    + (NSString *) stringFromDate: (NSDate *) date {
        return [[DateModel dateFormatter] stringFromDate:[DateModel normalize: date]] ;
    }
    
    +(NSDate*)规范化:(NSDate*)日期{
    NSDateComponents*comps=[[DateModel calendar]组件:NSYearCalendarUnit
    |NSMonthCalendarUnit
    |国家统计局日历单位
    |安舒尔日历单位
    |NSMinuteCalendar单位
    |第二日历单元
    fromDate:日期];
    [comps设置小时:0];
    [comps setMinute:0];
    [补偿设置秒:0];
    NSDate*dateOnly=[[DateModel calendar]dateFromComponents:comps];
    仅限返回日期;
    }
    +(NSCalendar*)日历{
    静态NSCalendar*日历=nil;
    如果(日历==nil){
    日历=[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
    calendar.timeZone=[NSTimeZone timezoneWithabRevision:@“GMT”];
    }
    返回日历;
    }
    +(NSDateFormatter*)日期格式化程序{
    静态NSDateFormatter*格式化程序=nil;
    if(格式化程序==nil){
    格式化程序=[[NSDateFormatter alloc]init];
    [formatter setCalendar:[self calendar]];//这似乎是一个()问题,在我把头发拉长太久之后,我终于解决了这个问题

    本准则所依据的假设是:

  • 你对日期感兴趣,而不是时间
  • 您希望您的日期计算不受任何夏令时的影响
  • 您需要一个足够简单的日期字符串表示形式,以便可以持久化它
  • 为了实现1,我使用了唯一的NSCalendar实例,该实例被初始化为Gregorian,GMT 这也服务于2

    对于3,NSDateFormatter使用唯一日历及其时区进行初始化。 将格式化程序的时区设置为用于计算的日历的时区是我遇到的所有问题的关键

    这应该总是正确的(假设下面的代码是
    DateModel
    类的一部分):

    代码如下:

    + (NSDate *) normalize: (NSDate *) date {
        NSDateComponents * comps = [[DateModel calendar] components:NSYearCalendarUnit
                                                                |   NSMonthCalendarUnit
                                                                |   NSDayCalendarUnit
                                                                |   NSHourCalendarUnit
                                                                |   NSMinuteCalendarUnit
                                                                |   NSSecondCalendarUnit
                                                           fromDate:date] ;
    
        [comps setHour:0] ;
        [comps setMinute:0] ;
        [comps setSecond:0] ;
    
        NSDate * dateOnly = [[DateModel calendar] dateFromComponents:comps] ;
    
        return dateOnly ;
    }
    
    + (NSCalendar *) calendar {
        static NSCalendar * calendar = nil ;
        if (calendar == nil) {
            calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] ;
            calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"GMT"] ;
        }
        return calendar ;
    }
    
    + (NSDateFormatter *) dateFormatter {
        static NSDateFormatter * formatter = nil ;
        if (formatter == nil) {
            formatter = [[NSDateFormatter alloc] init] ;
            [formatter setCalendar:[self calendar]] ;          // <- This is
            [formatter setTimeZone:[self calendar].timeZone] ; // <- critical
            [formatter setDateFormat:@"yyyyMMdd"] ;
        }
        return formatter ;
    }
    
    + (NSDate *) dateFromString: (NSString *) stringDate {
        return [DateModel normalize: [[DateModel dateFormatter] dateFromString:stringDate]] ;
    }
    
    + (NSString *) stringFromDate: (NSDate *) date {
        return [[DateModel dateFormatter] stringFromDate:[DateModel normalize: date]] ;
    }
    
    +(NSDate*)规范化:(NSDate*)日期{
    NSDateComponents*comps=[[DateModel calendar]组件:NSYearCalendarUnit
    |NSMonthCalendarUnit
    |国家统计局日历单位
    |安舒尔日历单位
    |NSMinuteCalendar单位
    |第二日历单元
    fromDate:日期];
    [comps设置小时:0];
    [comps setMinute:0];
    [补偿设置秒:0];
    NSDate*dateOnly=[[DateModel calendar]dateFromComponents:comps];
    仅限返回日期;
    }
    +(NSCalendar*)日历{
    静态NSCalendar*日历=nil;
    如果(日历==nil){
    日历=[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
    calendar.timeZone=[NSTimeZone timezoneWithabRevision:@“GMT”];
    }
    返回日历;
    }
    +(NSDateFormatter*)日期格式化程序{
    静态NSDateFormatter*格式化程序=nil;
    if(格式化程序==nil){
    格式化程序=[[NSDateFormatter alloc]init];
    [格式化程序设置日历:[自日历]]//