10

我正在尝试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

4

2 回答 2

49

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

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

或者

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

斯威夫特更新:

来自问题的代码,

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

或者

dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
于 2012-06-30T09:26:34.303 回答
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 的解决方案

于 2012-06-30T11:45:10.257 回答