简体   繁体   English

iOS NSDateFormatter dateFromString仅在一个实例中返回nil

[英]iOS NSDateFormatter dateFromString returns nil only in one instance

Does NSDateFormatter have a propensity for unexpectedly returning nil? NSDateFormatter是否有意外返回nil的倾向? I wouldn't think it did. 我认为不会。 I am hoping that I have overlooked some miniscule detail which for whatever reason I cannot see. 我希望我忽略了一些微小的细节,无论出于何种原因,我都看不到这些细节。

I have some data describing the sun and moon. 我有一些描述太阳和月亮的数据。 It's listed below. 在下面列出。 I also have a loop which iterates over this data once it is loaded from its plist into a dictionary. 我也有一个循环,一旦将其数据从其plist加载到字典中,就会循环访问该数据。 Finally I have a class which processes dates for me using NSDateFormatter as a singleton. 最后,我有一类使用NSDateFormatter作为单例为我处理日期的类。 This process has worked pretty well and these methods have been interacting and producing correct dates for a month or two, but today it crashed. 这个过程运行良好,这些方法已经交互并产生了一个或两个月的正确日期,但是今天它崩溃了。 All of the strings being created and passed through this simple process are correctly converted into dates except the last one which is nil. 所有创建并通过此简单过程传递的字符串都将正确转换为日期,最后一个除外,即nil。 Here's what happened: 这是发生了什么:

This is the data in the property list. 这是属性列表中的数据。

<key>2014-3-7</key>
<dict>
    <key>moonrise</key>
    <string>10:51 am</string>
    <key>moonset</key>
    <string>0:03 am</string>
    <key>phase</key>
    <string>Waxing Crescent</string>
    <key>sunrise</key>
    <string>6:39 am</string>
    <key>sunset</key>
    <string>6:21 pm</string>
</dict>

<key>2014-3-8</key>
<dict>
    <key>moonrise</key>
    <string>11:39 am</string>
    <key>moonset</key>
    <string>0:56 am</string>
    <key>phase</key>
    <string>First Quarter</string>
    <key>sunrise</key>
    <string>6:38 am</string>
    <key>sunset</key>
    <string>6:21 pm</string>
</dict>

<key>2014-3-9</key>
<dict>
    <key>moonrise</key>
    <string>1:28 pm</string>
    <key>moonset</key>
    <string>2:45 am</string>
    <key>phase</key>
    <string></string>
    <key>sunrise</key>
    <string>7:37 am</string>
    <key>sunset</key>
    <string>7:22 pm</string>
</dict>

This data is processed through a loop creating dates from date strings starting with yesterday and ending tomorrow, so in this case it starts on the 7th or march and ends on the 9th and we are working with the values in each plist item for the given date as a dictionary called iDay. 此数据通过循环处理,该循环从日期字符串开始创建日期,该日期字符串从昨天开始,到明天结束,因此在这种情况下,它从7月开始或3月开始,到9月结束,我们正在处理给定日期的每个plist项中的值作为名为iDay的字典。

NSString *eventString;
NSDate *moonrise;
NSDate *moonset;
NSString *dateFormatString = @"yyyy-MM-dd h:mm a";

if ([iDay objectForKey:@"moonrise"] != nil) {
    eventString = [NSString stringWithFormat:@"%@ %@", dateString, [iDay objectForKey:@"moonrise"]];
    moonrise = [self.dateTime makeDateFromString:eventString
                                          format:dateFormatString];
}

if ([iDay objectForKey:@"moonset"] != nil) {
    eventString = [NSString stringWithFormat:@"%@ %@",dateString, [iDay objectForKey:@"moonset"]];
    moonset = [self.dateTime makeDateFromString:eventString
                                         format:dateFormatString];
}

The strings being passed to [self.dateTime makeDateFromString] by these statements look like this: 这些语句传递给[self.dateTime makeDateFromString]的字符串如下所示:

2014-3-7 10:51 am 2014-3-7 10:51上午

2014-3-7 0:03 am 2014-3-7 0:03上午

2014-3-8 11:39 am 2014-3-8 11:39上午

2014-3-8 0:56 am 2014-3-8 0:56上午

2014-3-9 1:28 pm 2014-3-9 1:28下午

2014-3-9 2:45 am 2014-3-9 2:45上午

Okay, good. 好的。 Now the dateTime singleton: 现在dateTime单例:

+(ADateTimeClass *) sharedDateTime {
    @synchronized(self)
    {
        if (sharedInstance == NULL)
            sharedInstance = [[self alloc] init];
    }
    return sharedInstance;
}

-(id) init{
    self = [super init];
    if(self){
        self.dateFormat = [NSDateFormatter new];
        self.dateFormat.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    }
    return self;
}

... and the method where it all goes horribly wrong. ...以及所有方法都出了错的方法。 All of the strings passed to this method get returned correctly as dates except the last one, and I've checked, the nil is coming from "[dateFormat dateFromString:dateString]" right here where dateString is one of the six I listed above. 传递给此方法的所有字符串都将作为最后一个除外的日期正确返回,并且我检查过,零值来自“ [dateFormat dateFromString:dateString]”,这里的dateString是我上面列出的六个字符串之一。

-(NSDate*) makeDateFromString:(NSString *)dateString format:(NSString *)format{
    [dateFormat setDateFormat:format];
    NSDate* aDate = [dateFormat dateFromString:dateString];
    return aDate;
}

And the results: 结果:

Printing description of moonrise: 2014-03-07 14:51:00 +0000 月出的印刷说明:2014-03-07 14:51:00 +0000

Printing description of moonset: 2014-03-07 04:03:00 +0000 月球的印刷说明:2014-03-07 04:03:00 +0000

Printing description of moonrise: 2014-03-08 15:39:00 +0000 月出的印刷说明:2014-03-08 15:39:00 +0000

Printing description of moonset: 2014-03-08 04:56:00 +0000 月球的印刷说明:2014-03-08 04:56:00 +0000

Printing description of moonrise: 2014-03-09 16:28:00 +0000 月出的印刷说明:2014-03-09 16:28:00 +0000

Printing description of moonset: <nil> <------------ !!!!!! 月亮的印刷说明:<nil> <------------ !!!!!! Huh??? 嗯?

It's a simple problem actually depending on where you live. 实际上这是一个简单的问题,具体取决于您的住所。 At least in the USA, any time from March 9 2014 between 2am and 2:59am won't exist due to daylight saving time change. 至少在美国,由于夏令时更改,2014年3月9日凌晨2点至凌晨2:59之间的任何时间都不存在。 Therefore any such date is invalid. 因此,任何此类日期均无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM