NSDateFormatter dateFromString返回错误的日期

时间:2012-06-30 09:23:14

标签: objective-c ios nsdate nsdateformatter

我正在尝试在我的应用中使用NSDateFormatter,它采用日期字符串并将其格式化为NSDate,以便我可以进行日期比较,但是我发现当我使用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

2 个答案:

答案 0 :(得分:49)

尝试将此行添加到您的代码

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

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

SWIFT更新:

来自队列的代码,

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

答案 1 :(得分:20)

我不相信Dhruv的回答是正确的。事实上,目前尚不清楚是否存在任何问题。您似乎对应该发生的事情和/或对正在发生的事情的解释有不正确的期望。

NSDate代表一个时刻。这一刻没有一个独特的名字。在不同的地方和不同的命名系统(时区,日历)下,它们将以不同的名称为人所知。 NSDate不会处理任何此类问题,除非在其-description方法中,它必须生成该时刻的字符串表示。

其次,像“02-06-2012”这样的字符串没有指定精确的时刻。首先,它只是一个没有时间信息的日期,因此NSDateFormatter只是默认为该日期的第一个时刻。其次,它没有指定时区。日历日的第一个时刻是每个时区的不同时刻。除非您指定时区为-setTimeZone:或字符串本身带有时区信息,否则NSDateFormatter会假定您要求其解析的任何日期字符串都在当前时区。

因此,您的dateFromString对象代表您所在时区中指定日期02-06-2012的第一个时刻。我希望这是你想要的。但是,您对记录时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。

更重要的是,它改变了NSDate对象所代表的实际时刻,这是NSDateFormatter对日期字符串的解释。我怀疑你真的希望它具有特定的含义 - 你希望字符串被解释为在当地时区 - 并且他的解决方案阻止了你的意图。

tl;博士:你一直都想得到你想要的日期;不要依赖-[NSDate description];不要使用Dhruv的解决方案