2012-06-30 174 views
9

我想在我的应用程序中使用NSDateFormatter,该应用程序需要一个日期字符串并将其格式化为一个NSDate,以便我可以进行日期比较,但是我在查找时使用dateFromString并将其格式化为日期失去一天。NSDateFormatter dateFromString返回不正确的日期

NSString *dateString = @"02-06-2012"; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateFormat:@"dd-MM-yyyy"]; 
NSDate *dateFromString = [[NSDate alloc] init]; 
dateFromString = [dateFormatter dateFromString:dateString]; 
NSLog(@"My Date = %@", dateFromString); 
[dateFormatter release]; 

它输出到控制台:

我的日期= 2012-06-01 23:00:00 +0000

回答

19

我不要相信德鲁夫的答案是正确的。事实上,目前尚不清楚有什么问题。你似乎对所发生的事情和/或对发生的事情的解释有不正确的期望。

NSDate代表某个时刻。这一刻没有一个独特的名字。它会在不同的地方和不同的命名系统(时区,日历)中以不同的名称出现。 NSDate不处理任何本,只是一瘸一拐在其-description方法,它具有产生那一刻的字符串表示。

其次,像一个字符串“2012年2月6日”不及时指定一个精确的时刻。首先,这只是一个没有时间信息的日期,因此NSDateFormatter只是默认为该日期的第一时刻。其次,它没有指定时区。日历日的第一时刻是每个时区的不同时刻。除非你指定一个时区与-setTimeZone:或字符串本身带有时区信息,NSDateFormatter假定你问它来解析任何日期字符串在当前时区。

所以,你dateFromString对象表示在指定的日期,2012年2月6日的第一刻起,在您的时区。我希望这是你想要的。然而,当你记录日志时,你会被NSDate描述的方式困惑。正如我所说的,NSDate有挑选一些“名”(字符串表示)为它所代表的时刻,其命名为挑选是非常随意的。这几天它正在选择UTC时刻已知的名称。我从您的问题中显示的日志输出中收集您位于UTC + 0100的信息。所以,日期可能看起来早一天,但它确实与您指定的时间相同。换句话说,“2012-06-01 23:00:00 +0000”和“2012-06-02 00:00:00 +0100”是完全相同时刻的两个等同名称。你不习惯看到第一张,并误解了它。

经验教训是,你必须停止依靠NSDate的自我描述,以在任何特定的时区。真的,你不得不依赖任何关于它的东西,因为它没有记录。实际上,-[NSDate description]的文档声明:“该表示不保证在操作系统的不同版本中保持不变。”

Dhruv直升机的解决方案似乎帮助仅仅是因为它会导致NSDateFormatter-[NSDate description]对时区一致。但那是不可靠的。例如,它不适用于Snow Leopard,因为-[NSDate description]在该版本的框架中使用本地时区而不是UTC。

更重要的是,它改变了从NSDateFormatter对日期字符串的解释中获得的NSDate对象表示的实际时刻。我怀疑你真的希望这具有特定的含义 - 你希望字符串被解释为在当地时区 - 他的解决方案会阻碍你的意图。博士:你一直得到你想要的日期;不要依赖-[NSDate description];不要使用Dhruv的解决方案

+0

嗨,肯,谢谢你的详细回复,你会推荐我做什么或使用?在我的应用程序中,我需要检查是否等于或大于需要放入我的应用程序的特定硬编码日期。谢谢 – MonkeyBlue

+1

你必须决定你真正意义的时刻。硬编码日期是否意味着被解释为处于某个特定的固定时区(如贵公司的总部)?或者它应该被解释为在用户的时区?如果是前者,则应在日期格式化程序上设置固定时区。如果是后者,则可以将其保留为默认值,或者可以将其明确设置为'[NSTimeZone defaultTimeZone]'(或'+ systemTimeZone')。 –

+0

谢谢肯我会给出一个去 - 固定时间基本上是一个特定的日期,所以如果你打开应用程序和你的基地在世界任何地方它应该使用具体的日期,看看今天是否更大或相等,我们这样做因为我们必须在某个日期显示我们的应用中的不同信息。你的解释也更有意义,所以我会标记你的答案。谢谢 – MonkeyBlue

49

尝试添加该行代码,

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT+0:00"]]; 

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]]; 

SWIFT更新:

从quetion代码,

let dateString = "02-06-2012" 
var dateFormatter = NSDateFormatter() 
dateFormatter.dateFormat = "dd-MM-yyyy" 
var dateFromString : NSDate = dateFormatter.dateFromString(dateString)! 
println("My Date \(dateFromString)") 

和解决方案,

dateFormatter.timeZone = NSTimeZone(name: "GMT") 

OR

dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00") 
+0

谢谢你的完美。 – MonkeyBlue

+0

这不是一个非通用的解决方案吗?如果设备不在格林威治时间,该怎么办? – Stavash

+4

@stavash就是这一点,GMT与UTC或世界时间相同。这是每个人都可以使用的一个标准化时区,并且它永远不会改变(由于夏令时等)。这是iOS如何存储日期/时间.... – lnafziger

相关问题