【问题标题】:NSDataDetector - shifting timezone when parsing only time (no mm/dd/yyyy)NSDataDetector - 仅解析时间时移动时区(无 mm/dd/yyyy)
【发布时间】:2016-06-20 23:06:51
【问题描述】:

我在使用 NSDataDetector 从文本中提取时间时注意到了一些事情,但我不确定我是否理解发生了什么。在我的情况下,我拥有的唯一信息是时间 - 没有额外的日/月/年日期信息。只是日期的时间部分 - 例如可能嵌入在文本字符串中的“11:30”。

从字符串中提取日期信息的示例函数:

-(NSString*)extractTime:(NSString*)value {

  NSError *error = NULL;
  NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:(NSTextCheckingTypes)NSTextCheckingTypeDate error:&error];

  NSArray *matches = [detector matchesInString:value options:0 range:NSMakeRange(0, [value length])];
  NSDate *dateValue;

  for (NSTextCheckingResult *match in matches) {
    if ([match resultType] == NSTextCheckingTypeDate) {
      dateValue = [match date];
    }
  }

  NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  [formatter setDateFormat:@"HH:mm"];
  NSString *time = [formatter stringFromDate:dateValue];

  NSLog(@"original:%@ got_date:%@ formatted_time:%@", value, dateValue, time);

  return time;

}

然后我有一个简单的测试函数来向检测器抛出一些时间字符串。

-(void)testTimeExtraction {

  NSArray<NSString*>* times = @[@"07:30", @"8:30", @"9:30", @"10:30", @"11:30"];

  for(NSString *time in times) {
    NSLog(@"%@", [self extractTime:time]);
  }

}

我期望的是 7:30、8:30、9:30 等的时间信息。或者,如果失败了,至少在某种程度上是一致的时间(在同一时区)。

但是 - 我得到的结果因我的系统时钟而异。而且我不明白为什么或该怎么做。我的猜测是,在没有检测到日期的日期部分的情况下,日期被设置为当前的 UTC 日期,但我不明白为什么日期/时间会改变结果。日期似乎是根据系统时钟时间而变化的,但不是全部。

如果我将系统时钟时间设置为:06:01AM07:01AM08:01AM(所有相同的结果) 这些看起来“正确”,因为时间似乎是一致地推断出来的。


  • original:07:30 got_date:2016-06-18 12:30:00 +0000 formatted_time:07:30
  • original:8:30 got_date:2016-06-18 13:30:00 +0000 formatted_time:08:30
  • original:9:30 got_date:2016-06-18 14:30:00 +0000 formatted_time:09:30
  • original:10:30 got_date:2016-06-18 15:30:00 +0000 formatted_time:10:30
  • original:11:30 got_date:2016-06-18 16:30:00 +0000 formatted_time:11:30

系统时钟时间:美国中部时间上午 09:01 8:30 的日期被改变(但不是 7:30、9:30、10:30 或 11:30)


  • original:07:30 got_date:2016-06-17 12:30:00 +0000 formatted_time:07:30
  • original:8:30 got_date:2016-06-18 01:30:00 +0000 formatted_time:20:30
  • original:9:30 got_date:2016-06-17 14:30:00 +0000 formatted_time:09:30
  • original:10:30 got_date:2016-06-17 15:30:00 +0000 formatted_time:10:30
  • original:11:30 got_date:2016-06-17 16:30:00 +0000 formatted_time:11:30

系统时钟时间:美国中部时间上午 10:01(现在 8:30 和 9:30 已改变,但其他时间不改变)


  • original:07:30 got_date:2016-06-17 12:30:00 +0000 formatted_time:07:30
  • original:8:30 got_date:2016-06-18 01:30:00 +0000 formatted_time:20:30
  • original:9:30 got_date:2016-06-18 02:30:00 +0000 formatted_time:21:30
  • original:10:30 got_date:2016-06-17 15:30:00 +0000 formatted_time:10:30
  • original:11:30 got_date:2016-06-17 16:30:00 +0000 formatted_time:11:30

系统时钟时间:美国中部时间上午 11:01(等等...)


  • original:07:30 got_date:2016-06-17 12:30:00 +0000 formatted_time:07:30
  • original:8:30 got_date:2016-06-18 01:30:00 +0000 formatted_time:20:30
  • original:9:30 got_date:2016-06-18 02:30:00 +0000 formatted_time:21:30
  • original:10:30 got_date:2016-06-18 03:30:00 +0000 formatted_time:22:30
  • original:11:30 got_date:2016-06-17 16:30:00 +0000 formatted_time:11:30

我的假设是我只是不了解日期处理和日期提取的基本知识,但对我来说,只有一部分检测到的日期会根据系统时钟时间发生变化,这似乎真的很奇怪。

任何关于为什么会发生这种情况的线索将不胜感激。

【问题讨论】:

    标签: objective-c cocoa nsdatadetector


    【解决方案1】:

    这些是启发式方法...数据检测器试图猜测最可能的日期是什么。如果您在 9:01 扫描“8:30”,那么 Data Detectors 会假设它指的是晚上 8:30(将来)而不是上午 8:30(过去)更有意义。这就是为什么您得到的格式化时间是 20:30(晚上 8:30)。

    如果您查看各种测试,您会发现假设为 PM 的日期始终是相对于当前日期的过去日期(如果它们被检测为 AM)。

    您也不应该假设这就是总是会发生的事情。此行为是特定于语言环境的。

    【讨论】:

    • 非常非常有趣。考虑到如何应用数据检测器的上下文,这很有意义。你在那里大大拓宽了我的知识和欣赏。而且我完全了解不做假设和对语言环境敏感的问题。 (编辑是因为我愚蠢地点击了“返回”)。谢谢 - 这真的很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 2019-02-16
    • 2013-10-19
    • 1970-01-01
    相关资源
    最近更新 更多