0

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:01AM、または08:01AMに設定した場合 (すべて同じ結果) 時刻が一貫して推測されるように見えるため、これらは「正しく」見えます。


  • 元の:07:30 got_date:2016-06-18 12:30:00 +0000 Formatted_time:07:30
  • オリジナル:8:30 got_date:2016-06-18 13:30:00 +0000formatted_time:08:30
  • オリジナル:9:30 got_date:2016-06-18 14:30:00 +0000formatted_time:09:30
  • オリジナル:10:30 got_date:2016-06-18 15:30:00 +0000 Formatted_time:10:30
  • オリジナル:11:30 got_date:2016-06-18 16:30:00 +0000 Formatted_time:11:30

システム クロック時間: 09:01AM US Central 8:30 日付がシフトされます (ただし、7:30、9:30、10:30、または 11:30 ではありません)。


  • 元の:07:30 got_date:2016-06-17 12:30:00 +0000 Formatted_time:07:30
  • 元の:8:30 got_date: 2016-06-18 01:30:00 +0000 Formatted_time : 20:30
  • オリジナル:9:30 got_date:2016-06-17 14:30:00 +0000formatted_time:09:30
  • オリジナル:10:30 got_date:2016-06-17 15:30:00 +0000 Formatted_time:10:30
  • オリジナル:11:30 got_date:2016-06-17 16:30:00 +0000 Formatted_time:11:30

システム クロック時間: 10:01AM US Central (現在、8:30 と 9:30 はシフトされていますが、その他はシフトされていません)


  • 元の:07:30 got_date:2016-06-17 12:30:00 +0000 Formatted_time:07:30
  • 元の:8:30 got_date: 2016-06-18 01:30:00 +0000 Formatted_time : 20:30
  • 元の:9:30 got_date: 2016-06-18 02:30:00 +0000 Formatted_time : 21:30
  • オリジナル:10:30 got_date:2016-06-17 15:30:00 +0000 Formatted_time:10:30
  • オリジナル:11:30 got_date:2016-06-17 16:30:00 +0000 Formatted_time:11:30

システム クロック時間: 11:01AM 米国中部(など...)


  • 元の:07:30 got_date:2016-06-17 12:30:00 +0000 Formatted_time:07:30
  • 元の:8:30 got_date: 2016-06-18 01:30:00 +0000 Formatted_time : 20:30
  • 元の:9:30 got_date: 2016-06-18 02:30:00 +0000 Formatted_time : 21:30
  • 元の:10:30 got_date: 2016-06-18 03:30:00 +0000 Formatted_time : 22:30
  • オリジナル:11:30 got_date:2016-06-17 16:30:00 +0000 Formatted_time:11:30

私の仮定では、日付の処理と日付の抽出に関する基本的なことを理解していないだけですが、検出された日付のサブセットのみがシステムクロック時間に基づいてシフトするのは本当に奇妙に思えます。

なぜこれが起こっているのかについての手がかりをいただければ幸いです。

4

1 に答える 1

1

これらはヒューリスティックです... データ検出器は、最も可能性の高い日付を推測しようとします。9:01 の "8:30" をスキャンする場合、Data Detector は、それが (過去の) 8:30 AM ではなく 8:30 PM (将来) を指す方がより意味があると想定します。これが、フォーマットされた時刻が 20:30 (午後 8:30) になる理由です。

さまざまなテストを見ると、PM と見なされる日付は常に、AM として検出された場合に現在の日付よりも前の日付であることがわかります。

これが常に起こることだと思い込んではいけません。この動作はロケール固有です。

于 2016-06-20T15:06:51.380 に答える