From ca991ae9dddcb38d6ce5e2b17cdc41aa17006357 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Tue, 18 Jan 2022 11:36:18 +0900 Subject: [PATCH] #158 fallback for weird timestamps --- lib/model/entry.dart | 15 +------- .../metadata/metadata_fetch_service.dart | 8 ++--- lib/utils/time_utils.dart | 36 ++++++++++++------- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/lib/model/entry.dart b/lib/model/entry.dart index 0b6f72511..16f5cb237 100644 --- a/lib/model/entry.dart +++ b/lib/model/entry.dart @@ -349,20 +349,7 @@ class AvesEntry { DateTime? _bestDate; DateTime? get bestDate { - if (_bestDate == null) { - try { - if ((_catalogDateMillis ?? 0) > 0) { - _bestDate = DateTime.fromMillisecondsSinceEpoch(_catalogDateMillis!); - } else if ((sourceDateTakenMillis ?? 0) > 0) { - _bestDate = DateTime.fromMillisecondsSinceEpoch(sourceDateTakenMillis!); - } else if ((dateModifiedSecs ?? 0) > 0) { - _bestDate = DateTime.fromMillisecondsSinceEpoch(dateModifiedSecs! * 1000); - } - } catch (e, stack) { - // date millis may be out of range - reportService.recordError(e, stack); - } - } + _bestDate ??= dateTimeFromMillis(_catalogDateMillis) ?? dateTimeFromMillis(sourceDateTakenMillis) ?? dateTimeFromMillis((dateModifiedSecs ?? 0) * 1000); return _bestDate; } diff --git a/lib/services/metadata/metadata_fetch_service.dart b/lib/services/metadata/metadata_fetch_service.dart index b3e93e5fa..c483486b2 100644 --- a/lib/services/metadata/metadata_fetch_service.dart +++ b/lib/services/metadata/metadata_fetch_service.dart @@ -7,6 +7,7 @@ import 'package:aves/model/panorama.dart'; import 'package:aves/services/common/service_policy.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/services/metadata/xmp.dart'; +import 'package:aves/utils/time_utils.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -238,12 +239,7 @@ class PlatformMetadataFetchService implements MetadataFetchService { 'field': field.toExifInterfaceTag(), }); if (result is int) { - try { - return DateTime.fromMillisecondsSinceEpoch(result); - } catch (e, stack) { - // date millis may be out of range - await reportService.recordError(e, stack); - } + return dateTimeFromMillis(result, isUtc: false); } } on PlatformException catch (e, stack) { if (!entry.isMissingAtPath) { diff --git a/lib/utils/time_utils.dart b/lib/utils/time_utils.dart index c49e427b4..b3699462f 100644 --- a/lib/utils/time_utils.dart +++ b/lib/utils/time_utils.dart @@ -1,4 +1,4 @@ -import 'package:aves/services/common/services.dart'; +import 'package:flutter/foundation.dart'; extension ExtraDateTime on DateTime { bool isAtSameYearAs(DateTime? other) => year == other?.year; @@ -18,6 +18,26 @@ extension ExtraDateTime on DateTime { final epoch = DateTime.fromMillisecondsSinceEpoch(0, isUtc: true); +// Overflowing timestamps that are supposed to be in milliseconds +// will be retried after stripping extra digits. +const _millisMaxDigits = 13; // 13 digits can go up to 2286/11/20 + +DateTime? dateTimeFromMillis(int? millis, {bool isUtc = false}) { + if (millis == null || millis == 0) return null; + try { + return DateTime.fromMillisecondsSinceEpoch(millis, isUtc: isUtc); + } catch (e) { + // `DateTime`s can represent time values that are at a distance of at most 100,000,000 + // days from epoch (1970-01-01 UTC): -271821-04-20 to 275760-09-13. + debugPrint('failed to build DateTime from timestamp in millis=$millis'); + } + final digits = '$millis'.length; + if (digits > _millisMaxDigits) { + millis = int.tryParse('$millis'.substring(0, _millisMaxDigits)); + return dateTimeFromMillis(millis, isUtc: isUtc); + } +} + final _unixStampMillisPattern = RegExp(r'\d{13}'); final _unixStampSecPattern = RegExp(r'\d{10}'); final _plainPattern = RegExp(r'(\d{8})([_-\s](\d{6})([_-\s](\d{3}))?)?'); @@ -31,12 +51,7 @@ DateTime? parseUnknownDateFormat(String? s) { if (stampMillisString != null) { final stampMillis = int.tryParse(stampMillisString); if (stampMillis != null) { - try { - return DateTime.fromMillisecondsSinceEpoch(stampMillis, isUtc: false); - } catch (e, stack) { - // date millis may be out of range - reportService.recordError(e, stack); - } + return dateTimeFromMillis(stampMillis, isUtc: false); } } } @@ -47,12 +62,7 @@ DateTime? parseUnknownDateFormat(String? s) { if (stampSecString != null) { final stampSec = int.tryParse(stampSecString); if (stampSec != null) { - try { - return DateTime.fromMillisecondsSinceEpoch(stampSec * 1000, isUtc: false); - } catch (e, stack) { - // date millis may be out of range - reportService.recordError(e, stack); - } + return dateTimeFromMillis(stampSec * 1000, isUtc: false); } } }