我有一个根据用户位置生成当前日期的功能。即使在英国的夏令时发生变化之后,这也能提供正确的日期和时间。
然而,当我尝试使用日期创建一个字符串时,它似乎为我添加了额外的一小时......
E.g存储在Coredata中的日期是1/3/2013 12:00但是当转换为字符串时,它显示为1/3/2013 13:00。我用语言环境和时区改变的东西似乎没有什么区别。
我有什么想法可以解决这个问题?值得注意的是,“本地日期”功能我从未使用正确的时区创建日期时间。
代码:
+(NSDate*)localDate{
NSDate* date = [NSDate date];
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:date];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:date];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
return [NSDate dateWithTimeInterval:interval sinceDate:date];
}
格式化代码:
-(NSString*)dateWithTime{
NSDateFormatter*formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"dd"];
NSInteger day = [[formatter stringFromDate:self]integerValue];
NSInteger fullday = day;
NSString* strDay = @"";
if(day>29){
day = day - 30;
}
else if(day>19){
day = day - 20;
}
else if(day>9){
day = day - 10;
}
if(fullday ==11){
strDay = @"th";
}
else if(fullday ==12){
strDay = @"th";
}
else if(fullday ==13){
strDay = @"th";
}
else if(day == 1){
strDay = @"st";
}
else if(day ==2){
strDay = @"nd";
}
else if(day ==3){
strDay = @"rd";
}
else{
strDay = @"th";
}
[formatter setDateFormat:@"MMMM"];
NSString* month = [formatter stringFromDate:self];
[formatter setDateFormat:@"HH:mm"];
NSString* time = [formatter stringFromDate:self];
return [NSString stringWithFormat:@"%u%@ %@ %@ - %@",fullday,strDay,month,[self yearString],time];
}
编辑:即使是NSDateComponants也会返回错误的时间..
NSCalendar *gregorian = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self];
答案 0 :(得分:3)
请注意,在控制台中打印NSDate将始终以UTC格式打印日期。
只需将[NSDate date]
存储在数据库中即可。当用户从未更改过时区时,从数据库中读取日期并对其进行格式化将返回正确的结果。
核心数据中的NSDate对象存储为带有时区UTC的UNIX时间戳。在读取和格式化日期对象时,将应用用户的当前时区。
使用Core Data存储日期并且依赖于不同时区时,正确格式化日期的唯一方法是将相应的时区(时区名称作为字符串)存储起来。在阅读和格式化日期对象时,您必须将存储的时区应用于dateFormatter
。然后你会得到正确的结果。
答案 1 :(得分:2)
NSDate不知道时区,只有在转换时才计算时区,所以你的localDate方法可能会以你不想要的方式捏造东西。您可能需要做的是将格式化程序或日历的时区设置为本地区域,因此:
[formatter setTimeZone:localTimeZone];
或
[gregorian setTimeZone:localTimeZone];
并保留[NSDate date]
单独返回的值。
答案 2 :(得分:0)
设置dateformatter的区域设置;
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
答案 3 :(得分:0)
在设置初始日期/时间后,根据您的需要,您可能希望在时区(包括夏令时)发生变化时收到通知。如果是这样,applicationSignificantTimeChange:将是您的朋友。