【问题标题】:NSDateFormatter dateFromString working on iOS 10 but returning nil on iOS 11NSDateFormatter dateFromString 在 iOS 10 上工作,但在 iOS 11 上返回 nil
【发布时间】:2017-09-20 17:22:30
【问题描述】:

我在过去 2 年运行的内部应用程序有不同格式的 messages dates

1* Sep 20, 2017 at 8:09:39 PM

2* Feb 3, 2017, 5:49:42 PM

我正在像这样将这些字符串转换为日期

NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateStyle:NSDateFormatterMediumStyle];
[df setTimeStyle:NSDateFormatterMediumStyle];
[df setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
return [df dateFromString:dtStr];

对于日期 1,它在 iOS 10 和 11 上完美运行

但对于日期 2,它仅适用于 iOS 10,而不适用于 iOS 11

我该如何解决这个问题?

【问题讨论】:

  • 期望像 NSDateFormatterMediumStyle 这样的模糊格式能够像这样工作,实在是懒惰和冒险。如果您知道日期字符串的格式,为什么不使用与它匹配的特定格式的格式化程序?
  • @matt 同意,但有趣的是,该代码适用于 iOS 10 而不是 11。我想知道 Apple 是否更改了这些操作系统版本之间的默认日期或时间格式?似乎很有可能。
  • @DuncanC 也许他们有,但代码一开始就很傻;它或多或少是偶然的。
  • 问题是多个人已经在这个项目上工作过,将日期固定到一个甲酸盐现在不起作用(稍后修复),因为已经存储在数据库中的消息具有不同的日期格式...我需要修复此问题以发布热修复......
  • @S.J 你误会了。您的解决方法是将dateStyletimeStyle 的使用替换为dateFormat 的使用。您必须尝试可以发送到您的应用的每种可能格式。

标签: ios objective-c nsdate nsdateformatter


【解决方案1】:

所以看起来你更大的问题实际上是你有多种日期格式。

在此处查看此问题/答案: Converting mutliple date format into a single format in iPhone

它似乎没有那么高效......但它会为你工作。正如其他人评论的那样,它还使用特定的日期格式。

以下是针对您的问题的改编答案:

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    NSString *date1 = @"Sep 20, 2017 at 8:09:39 PM";
    NSString *date2 = @"Feb 3, 2017, 5:49:42 PM";

    NSLog(@"Date 1: %@", [self dateFromString:date1]);
    NSLog(@"Date 2: %@", [self dateFromString:date2]);
}

- (NSDate *)dateFromString:(NSString *)dateString {
    NSDate *date = nil;

    // here, insert other date formats you know might be given
    NSArray *dateFormatterList = @[
                                   @"MMM d, y, hh:mm:ss a",
                                   @"MMM d, y 'at' hh:mm:ss a"
                                   ];

    if (dateString) {
        for (NSString *dateFormatterString in dateFormatterList) {
            [self.dateFormatter setDateFormat:dateFormatterString];
            date = [self.dateFormatter dateFromString:dateString];
            if (date) break;
        }
    }

    return date;
}

- (NSDateFormatter *)dateFormatter {
    if (!_dateFormatter) {
        _dateFormatter = [[NSDateFormatter alloc] init];
    }
    return _dateFormatter;
}
@end

基本上正在发生的事情是......我们有一系列已知的日期格式。我们遍历每种格式并尝试使用该格式从日期字符串中获取 NSDate。如果我们得到一个,我们会返回那个日期。如果您有更多日期格式,只需将其插入 dateFormatterList。您会注意到我已经输入了两种日期格式:@"MMM d, y, hh:mm:ss a" 用于日期 1*,@"MMM d, y 'at' hh:mm:ss a" 用于上面的日期 2*。

我用你的两个日期对其进行了测试,它有效。 日志:

Date 1: Wed Sep 20 20:09:39 2017

Date 2: Fri Feb 3 17:49:42 2017

【讨论】:

    【解决方案2】:

    请检查:

    var dateStr = "Feb 3, 2017, 5:49:42 PM"
    
    NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeDate error:&error];
    NSArray *matches = [detector matchesInString: dateStr options:0 range:NSMakeRange(0, [dateStr length])];
    
    for (NSTextCheckingResult *match in matches) {
        if (match.resultType == NSTextCheckingTypeDate) {
            NSLog(@"%@", match.date);
        }
    }    
    

    斯威夫特 4

    var date = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)
                    .matches(in: dateStr, range: NSRange(location: 0, length: dateStr.count))
                    .flatMap{$0.date}
    print(date!) 
    

    【讨论】:

      最近更新 更多