diff --git a/firestore/lib/src/timestamp.dart b/firestore/lib/src/timestamp.dart index 555f060..43b357e 100644 --- a/firestore/lib/src/timestamp.dart +++ b/firestore/lib/src/timestamp.dart @@ -205,6 +205,9 @@ class Timestamp implements Comparable { return tryParse(any.toString()); } } + + /// The minimum representable [Timestamp] + static final zero = Timestamp(0, 0); } const _nanosPerSeconds = 1000000000; @@ -234,4 +237,22 @@ extension TekartikFirestoreTimestampExt on Timestamp { Timestamp substractDuration(Duration duration) { return _addMicroseconds(-duration.inMicroseconds); } + + /// Returns a [Duration] with the difference when subtracting [other] from + /// this [DateTime]. + /// + /// The returned [Duration] will be negative if [other] occurs after this + /// [DateTime]. + /// + /// + /// The difference is measured in seconds and fractions of seconds. + Duration difference(Timestamp other) { + var diffSeconds = seconds - other.seconds; + var diffNanos = nanoseconds - other.nanoseconds; + if (diffNanos < 0) { + diffSeconds--; + diffNanos += _nanosPerSeconds; + } + return Duration(seconds: diffSeconds, microseconds: diffNanos ~/ 1000); + } } diff --git a/firestore/test/timestamp_test.dart b/firestore/test/timestamp_test.dart index 1cb8f04..9c7d4d4 100644 --- a/firestore/test/timestamp_test.dart +++ b/firestore/test/timestamp_test.dart @@ -224,5 +224,23 @@ void main() { .substractDuration(const Duration(seconds: 2, microseconds: 400)), Timestamp(2, 999900000)); }); + test('difference', () { + expect(Timestamp(3, 1000).difference(Timestamp(3, 2000)), + const Duration(microseconds: -1)); + expect(Timestamp(3, 2000).difference(Timestamp(3, 1000)), + const Duration(microseconds: 1)); + expect(Timestamp(2, 1000).difference(Timestamp(3, 2000)), + const Duration(microseconds: -1000001)); + expect(Timestamp(3, 1000).difference(Timestamp(2, 2000)), + const Duration(microseconds: 999999)); + expect(Timestamp(62, 1000).difference(Timestamp(1, 2000)), + const Duration(minutes: 1, microseconds: 999999)); + var now = DateTime.timestamp(); + expect(Timestamp.fromDateTime(now).difference(Timestamp.zero), + now.difference(Timestamp.zero.toDateTime(isUtc: true))); + }); + test('zero', () { + expect(Timestamp.zero.toIso8601String(), '1970-01-01T00:00:00.000Z'); + }); }); }