0

我有一个根据用户位置生成当前日期的函数。即使在英国的夏令时更改之后,这也能提供正确的日期和时间。

但是,当我尝试创建一个带有日期的字符串时,它似乎为我增加了一个额外的小时......

例如,存储在 Coredata 中的日期是 2013 年 1 月 3 日 12:00,但是当转换为字符串时,它显示为 2013 年 1 月 3 日 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];
4

4 回答 4

3

请注意,在控制台中打印 NSDate 将始终以 UTC 格式打印日期。

只需将其存储[NSDate date]在您的数据库中。当用户从未更改其时区时,从数据库中读取日期并对其进行格式化将返回正确的结果。

Core Data 中的 NSDate 对象存储为带有 UTC 时区的 UNIX 时间戳。读取和格式化日期对象时,应用用户的当前时区。

当使用 Core Data 存储日期并且依赖于不同的时区时,正确格式化日期的唯一方法是存储适当的时区(时区名称为字符串)。读取和格式化日期对象时,您必须将存储的时区应用于dateFormatter. 然后你会得到正确的结果。

于 2013-04-08T16:36:44.027 回答
2

NSDate 不知道时区,只有在转换时区才算数,因此您的 localDate 方法可能会以您不希望的方式捏造事情。您可能需要做的是将格式化程序或日历的时区设置为本地区域,因此:

[formatter setTimeZone:localTimeZone];

或者

[gregorian setTimeZone:localTimeZone];

并将返回的值[NSDate date]单独保留。

于 2013-04-01T11:29:01.307 回答
0

设置 dateformatter 的语言环境;

NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
于 2013-04-01T12:49:53.407 回答
0

根据您在设置初始日期/时间后的需要,您可能希望在时区(包括 DST)已更改时收到通知。如果是这样,applicationSignificantTimeChange:将是您的朋友。

于 2013-04-01T12:51:00.157 回答