Add TimeOfDay comparison methods (#151233)

Implement Comparable for the TimeOfDay class as discussed in #139098. 

Also implements utility methods as `isBefore`, `isAfter` and `isAtSameTimeAs` for convenience and parity with `DateTime` from the dart sdk.
This commit is contained in:
derdilla 2024-07-12 01:51:35 +09:00 committed by GitHub
parent ee0260b41a
commit defdb958ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 1 deletions

View File

@ -45,7 +45,7 @@ enum DayPeriod {
/// * [DateTime], which represents date and time, and is subject to eras and
/// time zones.
@immutable
class TimeOfDay {
class TimeOfDay implements Comparable<TimeOfDay> {
/// Creates a time of day.
///
/// The [hour] argument must be between 0 and 23, inclusive. The [minute]
@ -112,6 +112,39 @@ class TimeOfDay {
);
}
/// Whether this [TimeOfDay] occurs earlier than [other].
///
/// Does not account for day or sub-minute differences. This means
/// that "00:00" of the next day is still before "23:00" of this day.
bool isBefore(TimeOfDay other) => compareTo(other) < 0;
/// Whether this [TimeOfDay] occurs later than [other].
///
/// Does not account for day or sub-minute differences. This means
/// that "00:00" of the next day is still before "23:00" of this day.
bool isAfter(TimeOfDay other) => compareTo(other) > 0;
/// Whether this [TimeOfDay] occurs at the same time as [other].
///
/// Does not account for day or sub-minute differences. This means
/// that "00:00" of the next day is still before "23:00" of this day.
bool isAtSameTimeAs(TimeOfDay other) => compareTo(other) == 0;
/// Compares this [TimeOfDay] object to [other] independent of date.
///
/// Does not account for day or sub-minute differences. This means
/// that "00:00" of the next day is still before "23:00" of this day.
///
/// A [compareTo] function returns:
/// * a negative value if this TimeOfDay [isBefore] [other].
/// * `0` if this DateTime [isAtSameTimeAs] [other], and
/// * a positive value otherwise (when this TimeOfDay [isAfter] [other]).
@override
int compareTo(TimeOfDay other) {
final int hourComparison = hour.compareTo(other.hour);
return hourComparison == 0 ? minute.compareTo(other.minute) : hourComparison;
}
@override
bool operator ==(Object other) {
return other is TimeOfDay

View File

@ -167,6 +167,36 @@ void main() {
expect(notifyLog, isEmpty);
});
});
testWidgets('correctly compares to other TimeOfDays', (WidgetTester tester) async {
expect(const TimeOfDay(hour: 0, minute: 0).compareTo(const TimeOfDay(hour: 1, minute: 0)), lessThan(0));
expect(const TimeOfDay(hour: 20, minute: 0).compareTo(const TimeOfDay(hour: 20, minute: 1)), lessThan(0));
expect(const TimeOfDay(hour: 0, minute: 0).compareTo(const TimeOfDay(hour: 0, minute: 0)), 0);
expect(const TimeOfDay(hour: 1, minute: 0).compareTo(const TimeOfDay(hour: 0, minute: 0)), greaterThan(0));
expect(const TimeOfDay(hour: 20, minute: 1).compareTo(const TimeOfDay(hour: 20, minute: 0)), greaterThan(0));
expect(const TimeOfDay(hour: 0, minute: 0).isBefore(const TimeOfDay(hour: 1, minute: 0)), isTrue);
expect(const TimeOfDay(hour: 0, minute: 0).isBefore(const TimeOfDay(hour: 23, minute: 0)), isTrue);
expect(const TimeOfDay(hour: 0, minute: 0).isBefore(const TimeOfDay(hour: 0, minute: 10)), isTrue);
expect(const TimeOfDay(hour: 0, minute: 0).isBefore(const TimeOfDay(hour: 0, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 1, minute: 0).isBefore(const TimeOfDay(hour: 0, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 23, minute: 0).isBefore(const TimeOfDay(hour: 0, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 10).isBefore(const TimeOfDay(hour: 0, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 0).isAfter(const TimeOfDay(hour: 1, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 0).isAfter(const TimeOfDay(hour: 23, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 0).isAfter(const TimeOfDay(hour: 0, minute: 10)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 0).isAfter(const TimeOfDay(hour: 0, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 1, minute: 0).isAfter(const TimeOfDay(hour: 0, minute: 0)), isTrue);
expect(const TimeOfDay(hour: 23, minute: 0).isAfter(const TimeOfDay(hour: 0, minute: 0)), isTrue);
expect(const TimeOfDay(hour: 0, minute: 10).isAfter(const TimeOfDay(hour: 0, minute: 0)), isTrue);
expect(const TimeOfDay(hour: 0, minute: 0).isAtSameTimeAs(const TimeOfDay(hour: 1, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 0).isAtSameTimeAs(const TimeOfDay(hour: 0, minute: 10)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 0).isAtSameTimeAs(const TimeOfDay(hour: 0, minute: 0)), isTrue);
expect(const TimeOfDay(hour: 1, minute: 0).isAtSameTimeAs(const TimeOfDay(hour: 0, minute: 0)), isFalse);
expect(const TimeOfDay(hour: 0, minute: 10).isAtSameTimeAs(const TimeOfDay(hour: 0, minute: 0)), isFalse);
});
}
class _RestorableWidget extends StatefulWidget {