added date constraints to overlay date time picker

This commit is contained in:
Brighton van den End 2022-11-18 15:57:03 +01:00
parent 3edcbe4b5a
commit 66e0090597
15 changed files with 538 additions and 118 deletions

View file

@ -11,12 +11,25 @@ and the Flutter guide for
[developing packages and plugins](https://flutter.dev/developing-packages).
-->
TODO: Put a short description of the package here that helps potential users
know whether this package might be useful for them.
# Date Time Picker
The date time picker to be able to input a date.
## Features
TODO: List what your package can do. Maybe include images, gifs, or videos.
### Drag down date time picker
A picker that is placed in the top of the screen.
You are able to select a day at this point.
When it is dragged down you are able to select a day for a given month.
### Overlay date time picker
A picker, that when opened using a button, is placed over the screen.
Then you are able to swipe through the month to select a day.
It is possible to add a constraint to de picker to limit the choice of day.
![Overlay date time picker GIF](overlay_date_time_picker.gif)
## Getting started
@ -25,15 +38,24 @@ start using the package.
## Usage
TODO: Include short and useful examples for package users. Add longer examples
to `/example` folder.
```dart
const like = 'sample';
OverlayDateTimePicker(
alignment: Alignment.bottomCenter,
child: const Text("Select Day"),
onTapDay: (date) {},
),
```
## Additional information
See the [Example Code](example/lib/main.dart) for more example's on how to use this package.
TODO: Tell users more about the package: where to find more information, how to
contribute to the package, how to file issues, what response they can expect
from the package authors, and more.
## Issues
Please file any issues, bugs or feature request as an issue on our [GitHub](https://github.com/Iconica-Development/flutter_date_time_picker/pulls) page. Commercial support is available if you need help with integration with your app or services. You can contact us at [support@iconica.nl](mailto:support@iconica.nl).
## Want to contribute
If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](../CONTRIBUTING.md) and send us your [pull request](https://github.com/Iconica-Development/flutter_date_time_picker/pulls).
## Author
This `flutter-date-time-picker` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl>

View file

@ -1,16 +1,3 @@
# example
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
The example Flutter app for the date time picker

View file

@ -80,6 +80,9 @@ class DatePickerDemo extends StatelessWidget {
onPressed: onPressed,
child: const Text("Select Day"),
),
dateTimeConstraint: DateTimeConstraint(
min: DateConstraint(date: DateTime.now()),
),
),
OverlayDateTimePicker(
theme: dateTimePickerTheme,
@ -91,6 +94,18 @@ class DatePickerDemo extends StatelessWidget {
Icons.schedule,
),
),
dateTimeConstraint: DateTimeConstraint(
min: DateConstraint(date: DateTime.now()),
max: DateConstraint(
date: DateTime(
DateTime.now().year,
DateTime.now().month + 4,
DateTime.now().day,
),
),
),
onNextPageButtonChild: const Icon(Icons.add),
onPreviousPageButtonChild: const Icon(Icons.minimize),
)
],
),

View file

@ -61,7 +61,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.0.1"
version: "2.0.0"
flutter_lints:
dependency: "direct dev"
description:

View file

@ -6,6 +6,7 @@ library flutter_date_time_picker;
export 'src/drag_down_date_time_picker.dart' show DragDownDateTimePicker;
export 'src/overlay_date_time_picker.dart' show OverlayDateTimePicker;
export 'src/models/date_constraint.dart';
export 'src/enums/date_box_shape.dart';
export 'src/models/date_box_base_theme.dart';
export 'src/models/date_box_disabled_theme.dart';

View file

@ -0,0 +1,107 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
class DateTimeConstraint {
final DateConstraint min;
final DateConstraint max;
const DateTimeConstraint({
this.min = DateConstraint.infinity,
this.max = DateConstraint.infinity,
});
bool inRange(DateTime date) {
return _checkDate(
min,
() => !date.isBefore(min.date!),
) &&
_checkDate(
max,
() => !date.isAfter(max.date!),
);
}
bool inDateRange(DateTime date) {
return _checkDate(
min,
() => !_stripToDateOnly(date).isBefore(_stripToDateOnly(min.date!)),
) &&
_checkDate(
max,
() => !_stripToDateOnly(date).isAfter(_stripToDateOnly(max.date!)),
);
}
bool inMonthRange(DateTime date) {
return _checkDate(
min,
() =>
!_stripToMonthsOnly(date).isBefore(_stripToMonthsOnly(min.date!)),
) &&
_checkDate(
max,
() =>
!_stripToMonthsOnly(date).isAfter(_stripToMonthsOnly(max.date!)),
);
}
bool inYearRange(DateTime date) {
return _checkDate(
min,
() => !_stripToYearsOnly(date).isBefore(_stripToYearsOnly(min.date!)),
) &&
_checkDate(
max,
() => !_stripToYearsOnly(date).isAfter(_stripToYearsOnly(max.date!)),
);
}
DateTime _stripToDateOnly(DateTime date) {
return DateTime(
date.year,
date.month,
date.day,
);
}
DateTime _stripToMonthsOnly(DateTime date) {
return DateTime(
date.year,
date.month,
1,
);
}
DateTime _stripToYearsOnly(DateTime date) {
return DateTime(
date.year,
1,
1,
);
}
bool _checkDate(DateConstraint constraint, bool Function() checker) {
if (!constraint.isInfinite) {
return checker();
}
return constraint.isInfinite;
}
}
class DateConstraint {
static const DateConstraint infinity =
DateConstraint(date: null, isInfinite: true);
final DateTime? date;
final bool isInfinite;
const DateConstraint({this.date, this.isInfinite = false})
: assert(
!(date != null && isInfinite),
'Can NOT have a limit set and be infinite.',
),
assert(
date != null || isInfinite,
'Must set some form of a limit.',
);
}

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:flutter/material.dart';
class DateTimePickerBarTheme {

View file

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/src/extensions/date_time.dart';
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
import 'package:flutter_date_time_picker/src/models/date_constraint.dart';
import 'package:flutter_date_time_picker/src/widgets/overlay_date_time_picker/overlay.dart';
class OverlayDateTimePicker extends StatefulWidget {
@ -14,8 +15,7 @@ class OverlayDateTimePicker extends StatefulWidget {
this.textStyle = const TextStyle(),
this.alignment = Alignment.bottomRight,
this.initialDate,
this.size = const Size(325, 350),
this.wrongTimeDialog,
this.size = const Size(325, 375),
this.onTapDay,
this.highlightToday = true,
this.alwaysUse24HourFormat = true,
@ -28,14 +28,14 @@ class OverlayDateTimePicker extends StatefulWidget {
this.buttonBuilder,
this.closeOnSelectDate = true,
this.showWeekDays = true,
this.dateTimeConstraint = const DateTimeConstraint(),
this.onNextPageButtonChild,
this.onPreviousPageButtonChild,
}) : assert(child != null || buttonBuilder != null);
/// The child contained by the DatePicker.
final Widget? child;
/// A [Widget] to display when the user picks a disabled time in the [TimePickerDialog]
final Widget? wrongTimeDialog;
/// Visual properties for the [OverlayDateTimePicker]
final DateTimePickerTheme theme;
@ -51,13 +51,13 @@ class OverlayDateTimePicker extends StatefulWidget {
/// a [bool] to set de clock on [TimePickerDialog] to a fixed 24 or 12-hour format.
final bool alwaysUse24HourFormat;
/// [pickTime] is a [bool] that determines if the user is able to pick a time after picking a date using the [TimePickerDialog].
/// is a [bool] that determines if the user is able to pick a time after picking a date using the [TimePickerDialog].
final bool pickTime;
/// indicates the starting date. Default is [DateTime.now()]
final DateTime? initialDate;
/// [markedDates] contain the dates [DateTime] that will be marked in the [OverlayDateTimePicker] by a small dot.
/// contain the dates [DateTime] that will be marked in the [OverlayDateTimePicker] by a small dot.
final List<DateTime>? markedDates;
/// a [List] of [DateTime] objects that will be disabled and cannot be interacted with whatsoever.
@ -75,12 +75,21 @@ class OverlayDateTimePicker extends StatefulWidget {
/// [buttonBuilder] is a method for building the button that can trigger the overlay to appear
final Widget Function(Key key, void Function() onPressed)? buttonBuilder;
/// [closeOnSelectDate] is a bool that indicates if the overlay should be closed if a date has been picked.
/// is a [bool] that indicates if the overlay should be closed if a date has been picked.
final bool closeOnSelectDate;
/// [showWeekDays] is a [bool] that determines if day in the week indicators should be shown
final bool showWeekDays;
/// a [DateTimeConstraint] that dictates the constraints of the dates that can be picked.
final DateTimeConstraint dateTimeConstraint;
/// a [Widget] that determents the icon of the button for going to the next page
final Widget? onNextPageButtonChild;
/// a [Widget] that determents the icon of the button for going to the previous page
final Widget? onPreviousPageButtonChild;
@override
State<OverlayDateTimePicker> createState() => _OverlayDateTimePickerState();
}
@ -222,6 +231,9 @@ class _OverlayDateTimePickerState extends State<OverlayDateTimePicker> {
showWeekDays: true,
onNextDate: nextDate,
onPreviousDate: previousDate,
dateTimeConstraint: widget.dateTimeConstraint,
onNextPageButtonChild: widget.onNextPageButtonChild,
onPreviousPageButtonChild: widget.onPreviousPageButtonChild,
),
),
),

View file

@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:flutter/material.dart';
class LockingPageScrollPhysics extends ScrollPhysics {
final bool Function() allowedNextPage;
final bool Function() allowedPreviousPage;
const LockingPageScrollPhysics({
required this.allowedNextPage,
required this.allowedPreviousPage,
ScrollPhysics? parent,
}) : super(parent: parent);
@override
ScrollPhysics applyTo(ScrollPhysics? ancestor) {
return LockingPageScrollPhysics(
allowedNextPage: allowedNextPage,
allowedPreviousPage: allowedPreviousPage,
parent: buildParent(ancestor));
}
@override
double applyBoundaryConditions(ScrollMetrics position, double value) {
bool movingLeft = value > position.pixels;
if (movingLeft && allowedNextPage()) {
return super.applyBoundaryConditions(position, value);
}
if (!movingLeft && allowedPreviousPage()) {
return super.applyBoundaryConditions(position, value);
}
return value - position.pixels;
}
}

View file

@ -18,6 +18,7 @@ class DatePicker extends StatelessWidget {
required this.onSelectDate,
required this.date,
required this.showWeekDays,
required this.dateTimeConstraint,
});
final DateTimePickerController controller;
@ -26,6 +27,7 @@ class DatePicker extends StatelessWidget {
final void Function(DateTime date) onSelectDate;
final DateTime date;
final bool showWeekDays;
final DateTimeConstraint dateTimeConstraint;
@override
Widget build(BuildContext context) {
@ -85,7 +87,8 @@ class DatePicker extends StatelessWidget {
padding: const EdgeInsets.all(2.0),
child: PickableDate(
isOffMonth: date.month != todayDate.month,
isDisabled: isDisabled(addedIndex + index, daysToSkip),
isDisabled:
isDisabled(addedIndex + index, daysToSkip, todayDate),
isSelected: controller.selectedDate == todayDate,
isToday: isToday(todayDate) && controller.highlightToday,
theme: theme,
@ -108,13 +111,14 @@ class DatePicker extends StatelessWidget {
date.day == now.day;
}
bool isDisabled(int index, int daysToSkip) {
bool isDisabled(int index, int daysToSkip, DateTime date) {
return DateTime(
date.year,
date.month,
index + 1 - daysToSkip,
).containsAny(
controller.disabledDates ?? [],
);
date.year,
date.month,
index + 1 - daysToSkip,
).containsAny(
controller.disabledDates ?? [],
) ||
!dateTimeConstraint.inRange(date);
}
}

View file

@ -5,7 +5,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
import 'package:flutter_date_time_picker/src/utils/locking_page_scroll_physics.dart';
import 'package:flutter_date_time_picker/src/widgets/overlay_date_time_picker/date_picker.dart';
import 'package:flutter_date_time_picker/src/models/date_constraint.dart';
import 'package:intl/intl.dart';
class OverlayDateTimeContent extends StatefulWidget {
@ -18,6 +20,9 @@ class OverlayDateTimeContent extends StatefulWidget {
required this.showWeekDays,
required this.onNextDate,
required this.onPreviousDate,
required this.dateTimeConstraint,
required this.onPreviousPageButtonChild,
required this.onNextPageButtonChild,
});
final DateTimePickerTheme theme;
@ -25,6 +30,11 @@ class OverlayDateTimeContent extends StatefulWidget {
final Size size;
final DateTimePickerController controller;
final bool showWeekDays;
final DateTimeConstraint dateTimeConstraint;
final Widget? onNextPageButtonChild;
final Widget? onPreviousPageButtonChild;
final void Function() onNextDate;
final void Function() onPreviousDate;
@ -34,10 +44,22 @@ class OverlayDateTimeContent extends StatefulWidget {
class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
bool usesButtons = false;
late DateTime nextDate;
late DateTime previousDate;
late final PageController _pageController;
@override
void initState() {
_pageController = PageController(initialPage: 1);
nextDate = DateTime(
widget.controller.browsingDate.year,
widget.controller.browsingDate.month + 1,
1,
);
previousDate = DateTime(
widget.controller.browsingDate.year,
widget.controller.browsingDate.month - 1,
1,
);
super.initState();
}
@ -56,16 +78,25 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: goToPreviousPage,
icon: const Icon(Icons.arrow_circle_left_outlined),
onPressed: (widget.dateTimeConstraint.inMonthRange(previousDate))
? _goToPreviousPage
: null,
icon: widget.onPreviousPageButtonChild ??
const Icon(Icons.arrow_circle_left_outlined),
color: widget.theme.barTheme.barColor,
),
Text(DateFormat.yMMMM().format(
widget.controller.browsingDate,
)),
Text(
DateFormat.yMMMM().format(
widget.controller.browsingDate,
),
style: widget.theme.baseTheme.textStyle,
),
IconButton(
onPressed: goToNextPage,
icon: const Icon(Icons.arrow_circle_right_outlined),
onPressed: (widget.dateTimeConstraint.inMonthRange(nextDate))
? _goToNextPage
: null,
icon: widget.onNextPageButtonChild ??
const Icon(Icons.arrow_circle_right_outlined),
color: widget.theme.barTheme.barColor,
),
],
@ -78,9 +109,15 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
),
Expanded(
child: PageView(
physics: LockingPageScrollPhysics(
allowedNextPage: () =>
widget.dateTimeConstraint.inMonthRange(nextDate),
allowedPreviousPage: () =>
widget.dateTimeConstraint.inMonthRange(previousDate),
),
controller: _pageController,
onPageChanged: (value) {
if (!usesButtons) movePage(1 - value);
if (!usesButtons) _movePage(1 - value);
},
pageSnapping: true,
scrollDirection: Axis.horizontal,
@ -88,34 +125,29 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
children: [
DatePicker(
controller: widget.controller,
onSelectDate: onSelectDate,
onSelectDate: _onSelectDate,
theme: widget.theme,
textStyle: widget.textStyle,
date: DateTime(
widget.controller.browsingDate.year,
widget.controller.browsingDate.month - 1,
1,
),
date: previousDate,
dateTimeConstraint: widget.dateTimeConstraint,
showWeekDays: widget.showWeekDays,
),
DatePicker(
controller: widget.controller,
onSelectDate: onSelectDate,
onSelectDate: _onSelectDate,
theme: widget.theme,
textStyle: widget.textStyle,
date: widget.controller.browsingDate,
showWeekDays: widget.showWeekDays,
dateTimeConstraint: widget.dateTimeConstraint,
),
DatePicker(
controller: widget.controller,
onSelectDate: onSelectDate,
onSelectDate: _onSelectDate,
theme: widget.theme,
textStyle: widget.textStyle,
date: DateTime(
widget.controller.browsingDate.year,
widget.controller.browsingDate.month + 1,
1,
),
date: nextDate,
dateTimeConstraint: widget.dateTimeConstraint,
showWeekDays: widget.showWeekDays,
),
],
@ -125,7 +157,7 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
);
}
void goToNextPage() async {
void _goToNextPage() async {
setState(() {
usesButtons = true;
});
@ -133,10 +165,10 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
);
nextPage();
_nextPage();
}
void goToPreviousPage() async {
void _goToPreviousPage() async {
setState(() {
usesButtons = true;
});
@ -144,41 +176,59 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
);
previousPage();
_previousPage();
}
void nextPage() {
void _nextPage() {
widget.onNextDate.call();
if (!mounted) return;
_pageController.jumpToPage(1);
setState(() {
usesButtons = false;
});
_pageController.jumpToPage(1);
_setDates();
}
void previousPage() {
void _previousPage() {
widget.onPreviousDate.call();
if (!mounted) return;
_pageController.jumpToPage(1);
setState(() {
usesButtons = false;
});
_pageController.jumpToPage(1);
_setDates();
}
void movePage(int direction) {
void _movePage(int direction) {
if (direction < 0) {
nextPage();
_nextPage();
} else if (direction > 0) {
previousPage();
_previousPage();
}
}
void onSelectDate(DateTime date) {
void _onSelectDate(DateTime date) {
if (!mounted) return;
setState(() {
widget.controller.selectedDate = date;
movePage(widget.controller.browsingDate.month - date.month);
_movePage(widget.controller.browsingDate.month - date.month);
widget.controller.onTapDayCallBack?.call(date);
});
}
void _setDates() {
if (!mounted) return;
setState(() {
nextDate = DateTime(
widget.controller.browsingDate.year,
widget.controller.browsingDate.month + 1,
1,
);
previousDate = DateTime(
widget.controller.browsingDate.year,
widget.controller.browsingDate.month - 1,
1,
);
});
}
}

View file

@ -77,6 +77,6 @@ class PickableDate extends StatelessWidget {
TextStyle? getStyle(bool isToday, bool isSelected) {
if (isToday) return theme.highlightTheme.textStyle;
if (isSelected) return theme.selectedTheme.textStyle;
return null;
return theme.baseTheme.textStyle;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

View file

@ -1,6 +1,6 @@
name: flutter_date_time_picker
description: A new Flutter package project.
version: 0.0.1
version: 2.0.0
homepage: https://iconica.nl/
environment:
@ -16,40 +16,3 @@ dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# To add assets to your package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages

View file

@ -0,0 +1,219 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:flutter_date_time_picker/src/models/date_constraint.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Date Range', () {
group('inRange()', () {
test(
'inRange() should return true when date is between min and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 06, 01)),
max: DateConstraint(date: DateTime(2022, 07, 01)),
);
expect(range.inRange(DateTime(2022, 06, 20)), true);
expect(range.inRange(DateTime(2022, 07, 20)), false);
expect(range.inRange(DateTime(2022, 05, 20)), false);
});
test(
'inRange() should return true when date is between infinity and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint.infinity,
max: DateConstraint(date: DateTime(2022, 07, 01)),
);
expect(range.inRange(DateTime(2022, 06, 20)), true);
expect(range.inRange(DateTime(2022, 07, 20)), false);
expect(range.inRange(DateTime(2022, 05, 20)), true);
});
test(
'inRange() should return true when date is between min and infinity otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 06, 01)),
max: DateConstraint.infinity,
);
expect(range.inRange(DateTime(2022, 06, 20)), true);
expect(range.inRange(DateTime(2022, 07, 20)), true);
expect(range.inRange(DateTime(2022, 05, 20)), false);
});
test('inRange() should return true when date is lower then max', () {
DateTimeConstraint range = DateTimeConstraint(
max: DateConstraint(date: DateTime(2022, 07, 01)),
);
expect(range.inRange(DateTime(2022, 06, 20)), true);
expect(range.inRange(DateTime(2022, 07, 20)), false);
expect(range.inRange(DateTime(2022, 05, 20)), true);
});
test('inRange() should return true when date is higher then min', () {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 06, 01)),
);
expect(range.inRange(DateTime(2022, 06, 20)), true);
expect(range.inRange(DateTime(2022, 07, 20)), true);
expect(range.inRange(DateTime(2022, 05, 20)), false);
});
test('inRange() should return true when date is equal to max', () {
DateTimeConstraint range = DateTimeConstraint(
max: DateConstraint(date: DateTime(2022, 06, 01)),
);
expect(range.inRange(DateTime(2022, 06, 01)), true);
expect(range.inRange(DateTime(2022, 05, 30)), true);
expect(range.inRange(DateTime(2022, 06, 02)), false);
});
test('inRange() should return true when date is equal to min', () {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 06, 01)),
);
expect(range.inRange(DateTime(2022, 06, 01)), true);
expect(range.inRange(DateTime(2022, 06, 02)), true);
expect(range.inRange(DateTime(2022, 05, 30)), false);
});
});
group('inYearRange()', () {
test(
'inYearRange() should return true when year is between min and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 1, 1)),
max: DateConstraint(date: DateTime(2024, 1, 1)),
);
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
expect(range.inYearRange(DateTime(2021, 1, 1)), false);
expect(range.inYearRange(DateTime(2025, 1, 1)), false);
});
test(
'inYearRange() should return true when year equals min or max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 1, 1)),
max: DateConstraint(date: DateTime(2023, 1, 1)),
);
expect(range.inYearRange(DateTime(2022, 1, 1)), true);
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
expect(range.inYearRange(DateTime(2021, 1, 1)), false);
expect(range.inYearRange(DateTime(2024, 1, 1)), false);
});
test(
'inYearRange() should return true when year is between min and infinity otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 1, 1)),
);
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
expect(range.inYearRange(DateTime(2025, 1, 1)), true);
expect(range.inYearRange(DateTime(2021, 1, 1)), false);
});
test(
'inYearRange() should return true when year is between infinity and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
max: DateConstraint(date: DateTime(2024, 1, 1)),
);
expect(range.inYearRange(DateTime(2023, 1, 1)), true);
expect(range.inYearRange(DateTime(2021, 1, 1)), true);
expect(range.inYearRange(DateTime(2025, 1, 1)), false);
});
});
group('inMonthRange()', () {
test(
'inMonthRange() should return true when year is between min and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 5, 1)),
max: DateConstraint(date: DateTime(2022, 7, 1)),
);
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
expect(range.inMonthRange(DateTime(2022, 3, 1)), false);
expect(range.inMonthRange(DateTime(2022, 8, 1)), false);
});
test(
'inMonthRange() should return true when year equals min or max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 5, 1)),
max: DateConstraint(date: DateTime(2022, 6, 1)),
);
expect(range.inMonthRange(DateTime(2022, 5, 1)), true);
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
expect(range.inMonthRange(DateTime(2022, 4, 1)), false);
expect(range.inMonthRange(DateTime(2022, 7, 1)), false);
});
test(
'inMonthRange() should return true when year is between min and infinity otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 5, 1)),
);
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
expect(range.inMonthRange(DateTime(2022, 8, 1)), true);
expect(range.inMonthRange(DateTime(2022, 3, 1)), false);
});
test(
'inMonthRange() should return true when year is between infinity and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
max: DateConstraint(date: DateTime(2022, 7, 1)),
);
expect(range.inMonthRange(DateTime(2022, 6, 1)), true);
expect(range.inMonthRange(DateTime(2022, 3, 1)), true);
expect(range.inMonthRange(DateTime(2022, 8, 1)), false);
});
});
group('inDateRange()', () {
test(
'inDateRange() should return true when year is between min and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 1, 4)),
max: DateConstraint(date: DateTime(2022, 1, 6)),
);
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
expect(range.inDateRange(DateTime(2022, 1, 3)), false);
expect(range.inDateRange(DateTime(2022, 1, 7)), false);
});
test(
'inDateRange() should return true when year equals min or max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 1, 4)),
max: DateConstraint(date: DateTime(2022, 1, 5)),
);
expect(range.inDateRange(DateTime(2022, 1, 4)), true);
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
expect(range.inDateRange(DateTime(2022, 1, 3)), false);
expect(range.inDateRange(DateTime(2022, 1, 6)), false);
});
test(
'inDateRange() should return true when year is between min and infinity otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
min: DateConstraint(date: DateTime(2022, 1, 4)),
);
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
expect(range.inDateRange(DateTime(2022, 1, 7)), true);
expect(range.inDateRange(DateTime(2022, 1, 3)), false);
});
test(
'inDateRange() should return true when year is between infinity and max otherwise false',
() {
DateTimeConstraint range = DateTimeConstraint(
max: DateConstraint(date: DateTime(2022, 1, 6)),
);
expect(range.inDateRange(DateTime(2022, 1, 5)), true);
expect(range.inDateRange(DateTime(2022, 1, 3)), true);
expect(range.inDateRange(DateTime(2022, 1, 7)), false);
});
});
});
}