Ios NSDateFormatter意外调整时间时出现问题
在Objective-C中工作时,我有一种方法可以正确格式化从数据库中获取的日期。 数据库返回一个没有时区信息的日期和时间。例如“2016-06-07T09:29:50.253” 问题是,它正确地获取了日期,然后将日期往回转了一个小时。对于我09:29的时间,我会以08:29结束 我现在在英国夏令时工作 我有以下代码:Ios NSDateFormatter意外调整时间时出现问题,ios,objective-c,nsdateformatter,Ios,Objective C,Nsdateformatter,在Objective-C中工作时,我有一种方法可以正确格式化从数据库中获取的日期。 数据库返回一个没有时区信息的日期和时间。例如“2016-06-07T09:29:50.253” 问题是,它正确地获取了日期,然后将日期往回转了一个小时。对于我09:29的时间,我会以08:29结束 我现在在英国夏令时工作 我有以下代码: +(NSDate *)getDate:(NSString *)date { //Gets the date date = [date stringByR
+(NSDate *)getDate:(NSString *)date {
//Gets the date
date = [date stringByReplacingOccurrencesOfString:@"T" withString:@" "];
date = [date componentsSeparatedByString: @"."][0];
//Formats the date
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//This line is the one that fixes it.
[formatter setTimeZone: [NSTimeZone timeZoneWithName:@"UTC"]];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *returnDate = [formatter dateFromString:date];
return returnDate;
}
我在谷歌上搜索了几次,发现添加了下面这行代码就解决了这个问题
[formatter setTimeZone: [NSTimeZone timeZoneWithName:@"UTC"]];
这暂时还可以,但我担心它会在夏令时再次中断,我也不完全确定为什么会修复它。我还希望我能让它适应不同的时区,但到目前为止还没有运气
进一步资料:
-日期来自sql server中的getDate()调用。我对这一点的理解是,它以日期为准,不了解时区。如果我进行选择呼叫,我会得到结果:“2016-06-07T09:29:50.253”
使问题正式化:
为什么上面的代码会对returnDate进行调整?在
NSDate
对象和它使用格式化程序的表示之间有一个重要的区别:
NSDate
对象将始终相对于世界时标准(UTC)。它不受夏令时和时区的影响,这是您希望它存储在数据库中的方式(作为UTC时间戳)
使用格式化程序时,它通常用于向用户显示日期。因此,格式化程序将默认使用当前设备的区域设置表示日期,因此,如果您的日期是11:00,并且您所在的时区为+4且没有夏令时,则您将获得的日期将是15:00。如果有夏令时,时间会略有变化。您需要这种行为,因为这将意味着无论您在世界上的何处,用户都将始终获得他们正在查看的日期的正确相对时间
除非您已经默认格式化程序使用“UTC”区域设置,否则不应将其与“+0”时区混淆。这就是为什么你会有不同的约会 尝试使用此格式化程序(而不是删除T和。):
UTC是一种标准,而不是时区。为此,请使用GMT。更多信息-请在08:29添加“结束”的方式。你怎么看这个日期?以及日期如何存储在数据库中-在某个时间点,时区将被声明或已达成一致。为什么要删除
T
以及
之后的内容。将它们添加到日期格式中。顺便说一句,在这样的数据库中存储日期时,无论用户的本地化设置如何,最好将locale
设置为en_US_POSIX
,以确保格式一致。请参阅。您应该从格式化程序中删除Z
,因为日期字符串中没有Z
。另外,仅供参考,”
仅在T
附近需要。谢谢@Rob的评论。
let dateLiteral = "2016-06-07T09:29:50.253"
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"
formatter.dateFromString(dateLiteral) // Jun 7, 2016, 9:29 AM