NSDate dateFromString 2 months wrong?

2019-06-07 05:57发布

问题:

I have the following code:

NSDateFormatter *dateFormater = [[NSDateFormatter alloc] init];
[dateFormater setDateFormat:@"yyyy-MM-DD HH:mm:ss"];
[dateFormater setLocale:[NSLocale currentLocale]];
[dateFormater setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *localDate = [dateFormater dateFromString:localUpdate];
NSDate *serverDate = [dateFormater dateFromString:serverUpdate];

The input strings for localUpdate and serverUpdate are:

2014-01-31 23:42:17
2014-02-01 00:09:37

When converting those from NSString to NSDate, the second one is 2 months behind?

2014-01-31 22:42:17 +0000
2013-12-31 23:09:37 +0000

Can anyone explain this?

回答1:

check this line:

[dateFormater setDateFormat:@"yyyy-MM-DD HH:mm:ss"];

the correct date format is @"yyyy-MM-dd HH:mm:ss" with "dd" not "DD"

I had the same problem once... and if the date format it's incorrect, when you use the dateFormatter, it will subtract or add one month to the date.



回答2:

Your date format string "yyyy-MM-DD HH:mm:ss" is not quite right.

You're telling NSDateFormatter to parse the 01 in your second example as the day of the year (DD) instead of the day of the month (dd), which you want instead.

yyyy-MM-DD HH:mm:ss
2014-02-01 00:09:37
        ^^~~~~~~~~~~~ these digits are being parsed as day of year rather
                      than as day of month

This is an easy mistake, and one that is confusingly hidden by your first example, in which the day of month and the day of year are the same.

See the Unicode reference for the date formats used by iOS 6 and up. (For older versions, choose the right link in Apple's documentation.)

Academic tangent: why NSDateFormatter interprets the second date as being on the last day of 2013 (rather than 1st day of 2014, as specified) is probably a bug caused by specifying a month and a day of year (which are mutually exclusive), a bug in the parser (interpreting the -01th day of the year), or a timezone or daylight savings detail (if the rules changed on midnight in the local timezone.)