NSDateFormatter dateFromString返回不正确的date

我想在我的应用程序中使用NSDateFormatter ,它需要一个datestring,并将其格式化为一个NSDate以便我可以做date比较,但是我发现当我使用dateFromString和格式化date失去一天。

 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]; 

这输出到控制台:

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

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

NSDate代表了一个时刻。 这一刻没有一个唯一的名字。 在不同的地方和不同的命名系统(时区,日历)中将以不同的名字来表示。 NSDate不处理任何这种情况,除了在其描述方法中-description地方,它必须产生那个时刻的string表示。

其次,像“02-06-2012”这样的string没有指定一个精确的时刻。 首先,这只是一个没有时间信息的date,所以NSDateFormatter只是默认为该date的第一时刻。 其次,它没有指定时区。 日历日的第一时刻是每个时区的不同时刻。 除非您使用-setTimeZone:指定时区,否则该string本身带有时区信息, NSDateFormatter假定您要求它parsing的任何datestring都在当前时区中。

因此,您的dateFromString对象表示指定date(2012年2月6日)在您的时区中的第一个时刻。 我希望这是你想要的。 然而,你被NSDatelogging时描述自己的方式弄糊涂了。 正如我所说, NSDate必须select一个“名称”(string表示)的时刻,它select的名称是相当随意的。 这几天它正在selectUTC时刻已知的名称。 我从你的问题中显示的日志输出中收集你在UTC + 0100。 所以,date看起来可能早一天,但确实是你指定的那一刻。 换句话说,“2012-06-01 23:00:00 +0000”和“2012-06-02 00:00:00 +0100”是完全相同的两个等同名称。 你只是不习惯看到第一个,误解了它。

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

Dhruv的解决scheme似乎只是因为它会导致NSDateFormatter-[NSDate description]在时区上达成一致。 但那是不可靠的。 例如,它不适用于Snow Leopard,因为-[NSDate description]在该版本的框架中使用本地时区而不是UTC。

更重要的是,它改变了从NSDateFormatter对datestring的解释中获得的NSDate对象表示的实际时刻。 我怀疑你真的希望有一个特定的含义 – 你希望string被解释为在当地时区 – 他的解决scheme阻碍了你的意图。

博士:你一直得到你想要的date; 不要依赖-[NSDate description] ; 不要使用Dhruv的解决scheme

尝试将这些行添加到您的代码中,

 [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)") 

和解决scheme,

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

要么

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