NSDateFormatter dateFromString返回错误的日期

Mon*_*lue 10 objective-c nsdate nsdateformatter ios

我试图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];
Run Code Online (Sandbox Code Playgroud)

这输出到控制台:

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

Dhr*_*ruv 49

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

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT+0:00"]];
Run Code Online (Sandbox Code Playgroud)

要么

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
Run Code Online (Sandbox Code Playgroud)

SWIFT更新:

来自排队的代码,

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

和解决方案,

dateFormatter.timeZone = NSTimeZone(name: "GMT")
Run Code Online (Sandbox Code Playgroud)

要么

dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
Run Code Online (Sandbox Code Playgroud)

  • @stavash这就是重点,GMT与UTC或Universal Time相同.这是每个人都可以使用的标准时区,它永远不会改变(由于夏令时等).这就是iOS存储日期/时间的方式.... (4认同)

Ken*_*ses 20

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

NSDate代表一个时刻.这一刻没有一个独特的名字.它将在不同的地方和不同的命名系统(时区,日历)下以不同的名称而为人所知.NSDate除了它的-description方法中的lamely之外,它不处理任何这种情况,它必须产生该时刻的字符串表示.

其次,像"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.

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

tl;博士:你一直都在想要约会; 不依赖-[NSDate description]; 不要使用Dhruv的解决方案