NSDate日期方法返回错误的结果

我知道有很多这类问题,但我找不到解决方案; 我需要获取当前和正确的NSDate对象,而不是NSString ! 这段代码返回错误的时间(+3小时),因为我来自乌克兰。

 NSDate *currentDate = [NSDate date]; 

如何从NSDateFormatter获取当前的NSDate对象? 我只知道如何获得NSString ,但我不需要它。

编辑:我正在使用此代码比较使用NSCalendar对象的2个NSDates ,这里是代码:

 NSCalendar *calendar = [NSCalendar currentCalendar]; NSUInteger unitFlags = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit; NSDateComponents *components = [calendar components:unitFlags fromDate:nowDate toDate:endDate options:0]; 

components.hour显示我+3小时的差异

NSDates总是以UTC格式存储,实际上日期本身对时区或周,月,年不了解。 他们只是一个时间点。

要查看您在地球表面上的位置的正确时间,您需要使用代表您的时间模型的NSCalendar。 您可以直接使用它并弄乱您的日期,或创建一个NSDateFormatter,它将保持日期不变,但调整它们的外观以满足您的需求。

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateStyle:NSDateFormatterFullStyle]; [formatter setTimeStyle:NSDateFormatterFullStyle]; NSLog(@"%@", [formatter stringFromDate: date1]); 

结果是

 Thursday, July 12, 2012, 4:36:07 PM Central European Summer Time 

回应评论:

尝试此代码作为测试

 NSDate *now = [NSDate date]; NSDate *startOfToday = nil; NSDate *startOfThisWeek = nil; NSDate *startOfThisMonth = nil; NSDate *startOfThisYear = nil; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startOfToday interval:NULL forDate:now]; [[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startOfThisWeek interval:NULL forDate:now]; [[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startOfThisMonth interval:NULL forDate:now]; [[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startOfThisYear interval:NULL forDate:now]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateStyle:NSDateFormatterFullStyle]; [formatter setTimeStyle:NSDateFormatterFullStyle]; NSLog(@"%@", now); NSLog(@"%@", [formatter stringFromDate:now]); NSLog(@"%@", startOfToday); NSLog(@"%@", [formatter stringFromDate:startOfToday]); NSLog(@"%@", startOfThisWeek); NSLog(@"%@", [formatter stringFromDate:startOfThisWeek]); NSLog(@"%@", startOfThisMonth); NSLog(@"%@", [formatter stringFromDate:startOfThisMonth]); NSLog(@"%@", startOfThisYear); NSLog(@"%@", [formatter stringFromDate:startOfThisYear]); 

你会发现,每天,每周,每月和每年的开始时间将调整到你当地的时间,因为每个NSLog对中的第一个将给你UTC的日期和你当地时区的第二个日期。


在聊天中你发布了这段代码

 NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm"]; [dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; NSDate *date = [dateFormat dateFromString:dateString]; [dateFormat release]; 

所以问题是,日期字符串实际上不是来自GMT,而是EET(东欧时间)

尝试

 [dateFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"EET"]]; 

但到目前为止最优雅的解决方案是获取与UTC的偏移量的2012-07-12 12:23:00 +0300 ,类似于2012-07-12 12:23:00 +0300如果有可能的话。
在这种情况下,你可以解析它
[dateFormat setDateFormat:@"yyyy-mm-dd HH:mm:ss Z"]; 并且不需要进一步的时区处理,因为格式化程序通过Z -specifier知道偏移量。
另请注意,如果您未设置任何时区,则应使用设备的电流。 如果用户始终与日期字符串中的时间位于同一时区,则此操作也可以。 但是,如果用户离开该区域,或者您想让它在全球范围内工作,您应该使用我给您的解决方案之一。 使用第二个(在datetring中指定带有-的时区)作为首选。

日期可能具有正确的值; 也许您认为这是不正确的,因为它在您登录时看起来不对? 这是因为当您记录它时,它会以UTC显示日期。 您可以使用NSDateFormatter在本地时区获取字符串。

如果第二个日期是UTC,答案是正确的。 乌克兰目前比UTC晚3个小时,因此UTC的午夜时间是21:00。 21:00至18:00是3小时。 所以检查你是如何获得第二个约会的。 可能正在为它指定错误的时区。

如果第一次约会确实是在乌克兰时间18:00创建的

 nowDate = [NSDate date]; 

然后第二个日期真的是21:00乌克兰时间,相当于午夜UTC。 由于您声称它是午夜,因此您必须使用UTC从字符串创建它 – 隐式或显式。 告诉我们你是如何创造它的。

**编辑**

你在聊天时给我的代码是这样的:

 NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm"]; [dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; NSDate *date = [dateFormat dateFromString:dateString]; [dateFormat release]; 

第三行将时区设置为GMT,与所有意图和目的的UTC相同。 您的日期格式化程序可能已初始化为设备的正确语言环境,因此您可能只需将该行保留。