Skip to content

Commit

Permalink
make DateRange into an Interable
Browse files Browse the repository at this point in the history
  • Loading branch information
eEQK committed Feb 10, 2024
1 parent 595a7b4 commit e321787
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 42 deletions.
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ Package to work with **date** & **time** in separation and with its ranges.

## Features

* Only Date comparison
* Only Time comparison
* Overflowed Time with keeping days
* Find crossing of dates
* Find crossing of times in the day
- Only Date comparison
- Only Time comparison
- Overflowed Time with keeping days
- Find crossing of dates
- Find crossing of times in the day

## Getting started

1. Add dependency

```yml
dependencies:
date_time_iso: <newest>
date_time_iso: <newest>
```
2. Import the dependency
Expand Down Expand Up @@ -70,12 +70,10 @@ print(date.copyWith(year: 2022)); // prints 07/03/2022
```dart
final range = DateRange(
const Date(year: 2021, month: 1, day: 1),
const Date(year: 2021, month: 12, day: 31),
const Date(year: 2021, month: 1, day: 3),
);
test('should be valid', () {
range.isValid.should.beTrue();
});
inspect(range.toList()) // [2021-01-01, 2021-01-02, 2021-01-03]
```

### Time
Expand Down Expand Up @@ -125,8 +123,8 @@ withClock(
Clock(() => DateTime.now().subtract(Duration(days: 10, minutes: 214))),
() {
print(clock.now()); // 2022-06-21 16:28:46.366887
print(DateTime.now()); // 2022-07-01 20:02:46.367579
print('${Date.now()} ${Time.now()}'); // 6/21/2022 16:28:46
print(DateTime.now()); // 2022-07-01 20:02:46.367579
print('${Date.now()} ${Time.now()}'); // 6/21/2022 16:28:46
},
);
```
Expand All @@ -144,18 +142,20 @@ If you fixed a bug or implemented a new feature, please send a [pull request](ht

We accept the following contributions:

* New features
* Improving documentation
* Fixing bugs
- New features
- Improving documentation
- Fixing bugs

## Maintainers

### This fork:
* [XperiTech](mailto:[email protected]?subject=[GitHub]%20Source%20Dart%20date_time_iso)

- [XperiTech](mailto:[email protected]?subject=[GitHub]%20Source%20Dart%20date_time_iso)

[xperitech.com](https://www.xperitech.com)

### Base repo:
* [Andrew Piterov](mailto:[email protected]?subject=[GitHub]%20Source%20Dart%20date_time)

- [Andrew Piterov](mailto:[email protected]?subject=[GitHub]%20Source%20Dart%20date_time)

<a href="https://www.buymeacoffee.com/devcraft.ninja" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Support me" height="41" width="174"></a>
50 changes: 44 additions & 6 deletions lib/src/date_range.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,60 @@
import 'package:date_time_iso/src/date.dart';

///
class DateRange {
/// Initialize `DateRange`
const DateRange(this.start, this.end);
class DateRange with Iterable<Date> implements Iterator<Date> {
/// Creates a date range based on dates from [start] to [end] (inclusive).
DateRange(
this.start,
this.end, {
this.step = const Duration(days: 1),
}) : assert(step.inDays > 0, 'Step must be at least a day');

final Date start;

/// End of the range, inclusive
final Date end;

/// Since the smallest step possible for a date is a day,
/// the [step] parameter is required to be at least a day.
final Duration step;

Date? _current;
var _exhausted = false;

@override
Date get current => _current!;

@override
bool moveNext() {
if (_exhausted) {
return false;
}

if (_current == null) {
_current = start;
} else {
_current = _current!.add(step);
}

_exhausted = _current!.isAfter(end);
return !_exhausted;
}

@override
Iterator<Date> get iterator => DateRange(start, end, step: step);

/// Returns whether or not [start] is before [end].
bool get isValid => start <= end;

/// Difference between [start] and [end]
Duration get duration => end.asDateTime.difference(start.asDateTime);

/// Returns whether or not [date] is contained in this range.
bool contains(Date date) =>
start.isSameOrBefore(date) && date.isSameOrBefore(end);
/// Returns whether or not [object] is contained in this range.
@override
bool contains(Object? object) =>
object is Date &&
start.isSameOrBefore(object) &&
object.isSameOrBefore(end);

@override
bool operator ==(Object other) =>
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: date_time_iso
description: Package to work with ISO date & time in separation and with its ranges.
version: 1.0.4
version: 1.0.5
homepage: https://github.com/XperiTech
repository: https://github.com/XperiTech/date_time_iso

Expand Down
80 changes: 62 additions & 18 deletions test/date_range_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,49 @@ import 'package:test/scaffolding.dart';

void main() {
test('is a valid date range when end is after start', () {
const range = DateRange(
Date(year: 2021, month: 3, day: 3),
Date(year: 2021, month: 5, day: 7),
final range = DateRange(
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 5, day: 7),
);

expect(range.isValid, isTrue);
});

test('is not a valid date range when start is after end', () {
const range = DateRange(
Date(year: 2021, month: 5, day: 7),
Date(year: 2021, month: 3, day: 3),
final range = DateRange(
const Date(year: 2021, month: 5, day: 7),
const Date(year: 2021, month: 3, day: 3),
);

expect(range.isValid, isFalse);
});

test('treats two date ranges with equal start and end dates as equal', () {
const dateRange1 = DateRange(
Date(year: 2021, month: 3, day: 3),
Date(year: 2021, month: 5, day: 7),
final dateRange1 = DateRange(
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 5, day: 7),
);
const dateRange2 = DateRange(
Date(year: 2021, month: 3, day: 3),
Date(year: 2021, month: 5, day: 7),
final dateRange2 = DateRange(
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 5, day: 7),
);

dateRange2.should.be(dateRange1);
});

test('computes difference between start and end', () {
const range = DateRange(
Date(year: 2021, month: 3, day: 3),
Date(year: 2021, month: 3, day: 7),
final range = DateRange(
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 3, day: 7),
);

expect(range.duration.inDays, equals(4));
});

test('calculates if date is within a range', () {
const range = DateRange(
Date(year: 2021, month: 3, day: 3),
Date(year: 2021, month: 3, day: 7),
final range = DateRange(
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 3, day: 7),
);

expect(range.contains(const Date(year: 2021, month: 3, day: 4)), true);
Expand All @@ -58,4 +58,48 @@ void main() {
expect(range.contains(const Date(year: 2021, month: 2, day: 4)), false);
expect(range.contains(const Date(year: 2021, month: 4, day: 4)), false);
});

test('calculates elements for a range', () {
final range = DateRange(
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 3, day: 7),
);

expect(
range.toList(),
equals([
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 3, day: 4),
const Date(year: 2021, month: 3, day: 5),
const Date(year: 2021, month: 3, day: 6),
const Date(year: 2021, month: 3, day: 7),
]),
);
});

test('calculates elements for a range when start=end', () {
final range = DateRange(
const Date(year: 2021, month: 3, day: 3),
const Date(year: 2021, month: 3, day: 3),
);

expect(
range.toList(),
equals([
const Date(year: 2021, month: 3, day: 3),
]),
);
});

test('returns no elements for a range when start is after end', () {
final range = DateRange(
const Date(year: 2021, month: 3, day: 5),
const Date(year: 2021, month: 3, day: 3),
);

expect(
range.toList(),
equals([]),
);
});
}

0 comments on commit e321787

Please sign in to comment.