Skip to content

Commit 0bdc09b

Browse files
authored
DateTime.shift method #71
2 parents 92f7276 + cdb7480 commit 0bdc09b

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

lib/src/extensions.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,39 @@ extension DateTimeTimeExtension on DateTime {
260260
return this;
261261
}
262262

263+
/// Adds time units to the calendar date and/or clock time.
264+
///
265+
/// Creates a new [DateTime] object with a calendar date offset from
266+
/// that of the the current one by the provided number of years, months, and/or days,
267+
/// and a wall clock time offset from that of the current one by the provided
268+
/// hours, minutes, seconds, milliseconds and/or microseconds.
269+
///
270+
/// The provided time units can be positive or negative, or any combination.
271+
/// Overflowing, say by adding more than 30 days to a any date, works like
272+
/// in the [DateTime] constructor.
273+
/// The resulting day and time must be within the supported range for
274+
/// the `DateTime` class.
275+
DateTime shift({
276+
int years = 0,
277+
int months = 0,
278+
int days = 0,
279+
int hours = 0,
280+
int minutes = 0,
281+
int seconds = 0,
282+
int milliseconds = 0,
283+
int microseconds = 0,
284+
}) =>
285+
copyWith(
286+
year: year + years,
287+
month: month + months,
288+
day: day + days,
289+
hour: hour + hours,
290+
minute: minute + minutes,
291+
second: second + seconds,
292+
millisecond: millisecond + milliseconds,
293+
microsecond: microsecond + microseconds,
294+
);
295+
263296
bool get isWeekend => (weekday == DateTime.saturday) || (weekday == DateTime.sunday);
264297

265298
bool get isWorkday => !isWeekend;

test/time_test.dart

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,145 @@ void main() {
716716
expect(it.isWorkday, isFalse);
717717
});
718718
});
719+
720+
group('Shift', () {
721+
group('empty parameters', () {
722+
test('local', () {
723+
final it = DateTime(2024, DateTime.january, 3, 2, 24, 12, 123, 456);
724+
expect(it.shift(), it);
725+
});
726+
test('utc', () {
727+
final it = DateTime.utc(2024, DateTime.january, 3, 2, 24, 12, 123, 456);
728+
expect(it.shift(), it);
729+
});
730+
});
731+
group('adding parameters', () {
732+
final it = DateTime(2000, 1, 1, 1, 1, 1, 1, 1);
733+
test('can shift years', () {
734+
expect(it.shift(years: 1), DateTime(2001, 1, 1, 1, 1, 1, 1, 1));
735+
});
736+
test('can shift months', () {
737+
expect(it.shift(months: 1), DateTime(2000, 2, 1, 1, 1, 1, 1, 1));
738+
});
739+
test('can shift days', () {
740+
expect(it.shift(days: 1), DateTime(2000, 1, 2, 1, 1, 1, 1, 1));
741+
});
742+
test('can shift hours', () {
743+
expect(it.shift(hours: 1), DateTime(2000, 1, 1, 2, 1, 1, 1, 1));
744+
});
745+
test('can shift minutes', () {
746+
expect(it.shift(minutes: 1), DateTime(2000, 1, 1, 1, 2, 1, 1, 1));
747+
});
748+
test('can shift seconds', () {
749+
expect(it.shift(seconds: 1), DateTime(2000, 1, 1, 1, 1, 2, 1, 1));
750+
});
751+
test('can shift milliseconds', () {
752+
expect(it.shift(milliseconds: 1), DateTime(2000, 1, 1, 1, 1, 1, 2, 1));
753+
});
754+
test('can shift microseconds', () {
755+
expect(it.shift(microseconds: 1), DateTime(2000, 1, 1, 1, 1, 1, 1, 2));
756+
});
757+
});
758+
group('subtracting parameters', () {
759+
final it = DateTime(2000, 1, 1, 1, 1, 1, 1, 1);
760+
test('can shift years', () {
761+
expect(it.shift(years: -1), DateTime(1999, 1, 1, 1, 1, 1, 1, 1));
762+
});
763+
test('can shift months', () {
764+
expect(it.shift(months: -1), DateTime(1999, 12, 1, 1, 1, 1, 1, 1));
765+
});
766+
test('can shift days', () {
767+
expect(it.shift(days: -1), DateTime(1999, 12, 31, 1, 1, 1, 1, 1));
768+
});
769+
test('can shift hours', () {
770+
expect(it.shift(hours: -1), DateTime(2000, 1, 1, 0, 1, 1, 1, 1));
771+
});
772+
test('can shift minutes', () {
773+
expect(it.shift(minutes: -1), DateTime(2000, 1, 1, 1, 0, 1, 1, 1));
774+
});
775+
test('can shift seconds', () {
776+
expect(it.shift(seconds: -1), DateTime(2000, 1, 1, 1, 1, 0, 1, 1));
777+
});
778+
test('can shift milliseconds', () {
779+
expect(it.shift(milliseconds: -1), DateTime(2000, 1, 1, 1, 1, 1, 0, 1));
780+
});
781+
test('can shift microseconds', () {
782+
expect(it.shift(microseconds: -1), DateTime(2000, 1, 1, 1, 1, 1, 1, 0));
783+
});
784+
});
785+
group('overflow', () {
786+
group('months', () {
787+
test('adding', () {
788+
final it = DateTime(2023, 11);
789+
expect(it.shift(months: 2), DateTime(2024));
790+
});
791+
test('subtracting', () {
792+
final it = DateTime(2023);
793+
expect(it.shift(months: -2), DateTime(2022, 11));
794+
});
795+
});
796+
group('days', () {
797+
test('adding', () {
798+
final it = DateTime(2023, 2, 27);
799+
expect(it.shift(days: 2), DateTime(2023, 3, 1));
800+
});
801+
test('subtracting', () {
802+
final it = DateTime(2023, 2, 1);
803+
expect(it.shift(days: -2), DateTime(2023, 1, 30));
804+
});
805+
});
806+
group('hours', () {
807+
test('adding', () {
808+
final it = DateTime(2023, 2, 1, 23);
809+
expect(it.shift(hours: 2), DateTime(2023, 2, 2, 1));
810+
});
811+
test('subtracting', () {
812+
final it = DateTime(2023, 2, 2, 1);
813+
expect(it.shift(hours: -2), DateTime(2023, 2, 1, 23));
814+
});
815+
});
816+
group('minutes', () {
817+
test('adding', () {
818+
final it = DateTime(2023, 2, 1, 1, 59);
819+
expect(it.shift(minutes: 2), DateTime(2023, 2, 1, 2, 1));
820+
});
821+
test('subtracting', () {
822+
final it = DateTime(2023, 2, 1, 1);
823+
expect(it.shift(minutes: -2), DateTime(2023, 2, 1, 0, 58));
824+
});
825+
});
826+
group('seconds', () {
827+
test('adding', () {
828+
final it = DateTime(2023, 2, 1, 1, 1, 59);
829+
expect(it.shift(seconds: 2), DateTime(2023, 2, 1, 1, 2, 1));
830+
});
831+
test('subtracting', () {
832+
final it = DateTime(2023, 2, 1, 1, 1);
833+
expect(it.shift(seconds: -2), DateTime(2023, 2, 1, 1, 0, 58));
834+
});
835+
});
836+
group('milliseconds', () {
837+
test('adding', () {
838+
final it = DateTime(2023, 2, 1, 1, 1, 1, 999);
839+
expect(it.shift(milliseconds: 2), DateTime(2023, 2, 1, 1, 1, 2, 1));
840+
});
841+
test('subtracting', () {
842+
final it = DateTime(2023, 2, 1, 1, 1, 1, 1);
843+
expect(it.shift(milliseconds: -2), DateTime(2023, 2, 1, 1, 1, 0, 999));
844+
});
845+
});
846+
group('microseconds', () {
847+
test('adding', () {
848+
final it = DateTime(2023, 2, 1, 1, 1, 1, 1, 999);
849+
expect(it.shift(microseconds: 2), DateTime(2023, 2, 1, 1, 1, 1, 2, 1));
850+
});
851+
test('subtracting', () {
852+
final it = DateTime(2023, 2, 1, 1, 1, 1, 1, 1);
853+
expect(it.shift(microseconds: -2), DateTime(2023, 2, 1, 1, 1, 1, 0, 999));
854+
});
855+
});
856+
});
857+
});
719858
});
720859

721860
group('Duration', () {

0 commit comments

Comments
 (0)