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

Tim*_*aev 6 objective-c nsdate nsdateformatter ios

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

NSDate *currentDate = [NSDate date];
Run Code Online (Sandbox Code Playgroud)

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

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

NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *components = [calendar components:unitFlags fromDate:nowDate toDate:endDate options:0];
Run Code Online (Sandbox Code Playgroud)

components.hour告诉我+3小时的差异

Vik*_*ica 9

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

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

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];

NSLog(@"%@", [formatter stringFromDate: date1]);
Run Code Online (Sandbox Code Playgroud)

结果是

Thursday, July 12, 2012, 4:36:07 PM Central European Summer Time 
Run Code Online (Sandbox Code Playgroud)

回应评论:

试试这段代码作为测试

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]);
Run Code Online (Sandbox Code Playgroud)

你会意识到,一天,一周,一个月和一年的开始将调整到你当地的时间,因为每个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]; 
Run Code Online (Sandbox Code Playgroud)

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

尝试

[dateFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"EET"]]; 
Run Code Online (Sandbox Code Playgroud)

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

  • 不,对不起,我得走了.请将日期创建代码添加到您的问题中,我认为它们是在不同的时区创建的. (2认同)