Skip to content

Commit

Permalink
feat: add function to get datetime from ISO week calendar
Browse files Browse the repository at this point in the history
Accepts year, week number and optional week day, returns a datetime
  • Loading branch information
Maistho committed Jul 30, 2023
1 parent f8a7f95 commit 85e20f3
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
22 changes: 22 additions & 0 deletions lib/datetime_from_week_number.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/// Create a DateTime based on ISO year, week number, and optional week day.
///
/// Allows overflowing/underflowing the week numbers. For example: year 2023,
/// week 53 doesn't exist and will overflow to year 2024, week 1
DateTime dateTimeFromWeekNumber(
int year,
int weekNumber, [
int weekDay = DateTime.monday,
]) {
// January 4th is always in week 1
final fourthJanuary = DateTime(year, 1, 4);

// removing the weekday from January 4th returns the monday of week 1, which could be in the preceding year.
final firstDayOfWeek1 = DateTime(year, 1, 4 - (fourthJanuary.weekday - 1));

// Not using DateTime.add() since that adds a duration which takes things such as daylight savings into account, which could introduce errors.
return DateTime(
firstDayOfWeek1.year,
firstDayOfWeek1.month,
firstDayOfWeek1.day + 7 * (weekNumber - 1) + (weekDay - 1),
);
}
1 change: 1 addition & 0 deletions lib/week_of_year.dart
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export './date_week_extensions.dart';
export './datetime_from_week_number.dart';
66 changes: 66 additions & 0 deletions test/datetime_from_week_number_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:test/test.dart';
import 'package:week_of_year/datetime_from_week_number.dart';

void t(int year, List<DateTime> expectations) {
group('$year', () {
test('w1 monday', () {
expect(
expectations[0],
dateTimeFromWeekNumber(year, 1, DateTime.monday),
);
});
test('w10 thursday', () {
expect(
expectations[1],
dateTimeFromWeekNumber(year, 10, DateTime.thursday),
);
});
test('w52 saturday', () {
expect(
expectations[2],
dateTimeFromWeekNumber(year, 52, DateTime.saturday),
);
});
test('w53 wednesday', () {
expect(
expectations[3],
dateTimeFromWeekNumber(year, 53, DateTime.wednesday),
);
});
});
}

void main() {
group('dateTimeFromWeekNumber', () {
t(2020, [
DateTime(2019, 12, 30),
DateTime(2020, 03, 05),
DateTime(2020, 12, 26),
DateTime(2020, 12, 30),
]);
t(2021, [
DateTime(2021, 01, 04),
DateTime(2021, 03, 11),
DateTime(2022, 01, 01),
DateTime(2022, 01, 05),
]);
t(2022, [
DateTime(2022, 01, 03),
DateTime(2022, 03, 10),
DateTime(2022, 12, 31),
DateTime(2023, 01, 04),
]);
t(2023, [
DateTime(2023, 01, 02),
DateTime(2023, 03, 09),
DateTime(2023, 12, 30),
DateTime(2024, 01, 03),
]);
t(2024, [
DateTime(2024, 01, 01),
DateTime(2024, 03, 07),
DateTime(2024, 12, 28),
DateTime(2025, 01, 01),
]);
});
}

0 comments on commit 85e20f3

Please sign in to comment.