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

时间:2012-07-12 14:44:45

标签: objective-c ios nsdate nsdateformatter

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

NSDate *currentDate = [NSDate date];

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

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

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

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

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

如果第二个日期是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相同。您的日期格式化程序可能已初始化为设备的正确语言环境,因此您可能只需将该行保留。