NSDateFormatter dateFromString返回错误的日期 [英] NSDateFormatter dateFromString returns incorrect date

查看:106
本文介绍了NSDateFormatter dateFromString返回错误的日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的应用中使用 NSDateFormatter ,它接受日期字符串并将其格式化为 NSDate 所以我可以做Date Comparisons,但是我发现当我使用dateFromString并将其格式化时,日期会丢失一天。

I am trying to use NSDateFormatter in my app which takes a date string and formats it to an NSDate so that I can do Date Comparisons, however I am finding when I use dateFromString and format it the date is losing one day.

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

My Date = 2012-06-01 23:00:00 +0000


推荐答案

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

I don't believe that Dhruv's answer is correct. In fact, it's not clear there's any problem at all. You just seem to have an incorrect expectation of what should happen and/or interpretation of what's happening.

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

NSDate represents a moment in time. This moment does not have one unique name. It will be known by different names in different places and under different naming systems (time zones, calendars). NSDate doesn't deal with any of this, except lamely in its -description method, where it has to produce a string representation of that moment.

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

Second, a string like "02-06-2012" doesn't specify a precise moment in time. First of all, it's just a date with no time information, so NSDateFormatter just defaults to the first moment for that date. Second, it doesn't specify the time zone. The first moment of the calendar day is a different moment in each time zone. Unless you specify a time zone with -setTimeZone: or the string itself carries time zone information, NSDateFormatter assumes that any date strings you ask it to parse are in the current time zone.

所以,你的 dateFromString 对象代表了第一时刻您所在时区的指定日期02-06-2012。我希望这是你想要的。但是,您对记录时 NSDate 描述自身的方式感到困惑。正如我所说, NSDate 必须在它代表的时刻选择一些名称(字符串表示),它选择的名称是相当随意的。这些天它正在选择以UTC表示时刻的名称。我从你问题中显示的日志输出中收集到你所在的UTC + 0100。因此,日期可能看起来像是前一天,但它确实与您指定的时刻相同。换句话说,2012-06-01 23:00:00 +0000和2012-06-02 00:00:00 +0100是完全相同的时刻的两个等效名称。你只是不习惯看到第一个并误解了它。

So, your dateFromString object represents the first moment of the specified date, 02-06-2012, in your time zone. I expect this is what you wanted. However, you then got confused by the way that NSDate describes itself when logged. As I said, NSDate has to pick some "name" (string representation) for the moment it represents and which name it picks is fairly arbitrary. These days it is picking the name that the moment is known by in UTC. I gather from the log output shown in your question that you are located at UTC+0100. So, the date may look like it's one day earlier but it really is the same moment you specified. In other words, "2012-06-01 23:00:00 +0000" and "2012-06-02 00:00:00 +0100" are two equivalent names for exactly the same moment in time. You just aren't used to seeing the first one and misinterpreted it.

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

The lesson is that you have to stop relying on NSDate's self-description to be in any particular time zone. Really, you have to not rely on anything about it, since it's not documented. In fact, the docs for -[NSDate description] state, "The representation is not guaranteed to remain constant across different releases of the operating system."

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

Dhruv's solution seems to help merely because it causes NSDateFormatter and -[NSDate description] to agree on the time zone. But that's unreliable. It wouldn't work on Snow Leopard, for example, because -[NSDate description] used the local time zone instead of UTC in that version of the frameworks.

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

More importantly, though, it alters the actual moment represented by the NSDate object you get from NSDateFormatter's interpretation of your date string. I suspect you really want that to have a specific meaning – you want the string to be interpreted as being in the local time zone – and his solution thwarts your intent.

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

tl;dr: you were getting the date you wanted all along; don't rely on -[NSDate description]; don't use Dhruv's solution

这篇关于NSDateFormatter dateFromString返回错误的日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆