Skip to content

Commit

Permalink
Fix daylight-saving issue
Browse files Browse the repository at this point in the history
  • Loading branch information
devj3ns committed Apr 2, 2021
1 parent fd02273 commit a30ee0f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 33 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.1

* Fix daylight-saving issue

## 1.1.0

* Stable null safety release
Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# isoweek

A lightweight Dart package which provides the class Week (based on the ISO 8601 format). Instances represent specific weeks spanning Monday to Sunday.
A lightweight Dart package which provides the class Week (based on the local time). Instances represent specific weeks spanning Monday to Sunday.
An ISO week-numbering year has 52 or 53 full weeks. Week 1 is defined to be the first week with 4 or more days in January.

See also: https://en.wikipedia.org/wiki/ISO_week_date

(This package is inspired by the isoweek Python package: https://pypi.org/project/isoweek/)
It’s called isoweek because this is the week definition of [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date).
This package is inspired by the [isoweek Python package](https://pypi.org/project/isoweek/).

### Example

Expand All @@ -14,12 +13,15 @@ import 'package:isoweek/isoweek.dart';
void main() {
Week currentWeek = Week.current();
print(currentWeek);
print('Current week: $currentWeek');
//OUTPUT: 2021W13
print('Days of current week: ${currentWeek.days}');
//OUTPUT: [2021-03-29 00:00:00.000, 2021-03-30 00:00:00.000, ...]
Week nextWeek = currentWeek.next;
print('Days of next week: ${nextWeek.days}');
//OUTPUT: Days of next week: [2021-04-05 01:00:00.000, 2021-04-06 01:00:00.000, ...]
//OUTPUT: Days of next week: [2021-04-05 00:00:00.000, 2021-04-06 00:00:00.000, ...]
Week previousWeek = currentWeek.previous;
print('Days of previous week: ${previousWeek.days}');
Expand All @@ -29,19 +31,17 @@ void main() {
print('5 weeks ahead: $futureWeek');
//OUTPUT: 5 weeks ahead: 2021W18
DateTime myBirthday = DateTime.utc(2020, 11, 16);
Week birthdayWeek = Week.fromDate(myBirthday);
Week birthdayWeek = Week.fromDate(DateTime(2020, 11, 16));
print(
'The week number of my birthday in 2020 was ${birthdayWeek.weekNumber}');
//OUTPUT: The week number of my birthday in 2020 was 47
String isoWeek = '2021W25';
Week weekFromIso = Week.fromIsoString(isoWeek);
print('Week from ISO: $weekFromIso');
Week weekFromIso = Week.fromISOString('2021W25');
print('Week from ISO string: $weekFromIso');
//OUTPUT: Week from ISO: 2021W25
DateTime firstDay = weekFromIso.day(0);
print('The Week $weekFromIso starts with $firstDay');
//OUTPUT: The Week 2021W25 starts with 2021-06-21 01:00:00.000
//OUTPUT: The Week 2021W25 starts with 2021-06-21 00:00:00.000
}
```
17 changes: 9 additions & 8 deletions example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import 'package:isoweek/isoweek.dart';

void main() {
Week currentWeek = Week.current();
print(currentWeek);
print('Current week: $currentWeek');
//OUTPUT: 2021W13

print('Days of current week: ${currentWeek.days}');
//OUTPUT: [2021-03-29 00:00:00.000, 2021-03-30 00:00:00.000, ...]

Week nextWeek = currentWeek.next;
print('Days of next week: ${nextWeek.days}');
//OUTPUT: Days of next week: [2021-04-05 01:00:00.000, 2021-04-06 01:00:00.000, ...]
//OUTPUT: Days of next week: [2021-04-05 00:00:00.000, 2021-04-06 00:00:00.000, ...]

Week previousWeek = currentWeek.previous;
print('Days of previous week: ${previousWeek.days}');
Expand All @@ -17,18 +20,16 @@ void main() {
print('5 weeks ahead: $futureWeek');
//OUTPUT: 5 weeks ahead: 2021W18

DateTime myBirthday = DateTime.utc(2020, 11, 16);
Week birthdayWeek = Week.fromDate(myBirthday);
Week birthdayWeek = Week.fromDate(DateTime(2020, 11, 16));
print(
'The week number of my birthday in 2020 was ${birthdayWeek.weekNumber}');
//OUTPUT: The week number of my birthday in 2020 was 47

String isoWeek = '2021W25';
Week weekFromIso = Week.fromISOString(isoWeek);
print('Week from ISO: $weekFromIso');
Week weekFromIso = Week.fromISOString('2021W25');
print('Week from ISO string: $weekFromIso');
//OUTPUT: Week from ISO: 2021W25

DateTime firstDay = weekFromIso.day(0);
print('The Week $weekFromIso starts with $firstDay');
//OUTPUT: The Week 2021W25 starts with 2021-06-21 01:00:00.000
//OUTPUT: The Week 2021W25 starts with 2021-06-21 00:00:00.000
}
54 changes: 42 additions & 12 deletions lib/isoweek.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,20 @@ class Week extends Equatable {

/// Return the week that many number of weeks into the future.
Week addWeeks(int weeks) {
return Week.fromDate(day(0).add(Duration(days: 7 * weeks)));
return Week.fromDate(day(0).addWeeks(weeks));
}

/// Return the week that many number of weeks in the past.
Week subtractWeeks(int weeks) {
return Week.fromDate(day(0).subtract(Duration(days: 7 * weeks)));
return Week.fromDate(day(0).subtractWeeks(weeks));
}

/// Return a day of the week as a DateTime object based on the provided day index. Day 0 is Monday.
DateTime day(int day) {
// According to ISO the Jan 4th must be in week 1
final d = DateTime(year, 1, 4);
return d.add(Duration(days: (weekNumber - 1) * 7 + (-d.weekday + day) + 1));
final addDays =
(weekNumber - 1) * 7 + (-DateTime(year, 1, 4).weekday + day) + 1;
return DateTime(year, 1, 4).addDays(addDays);
}

/// Return the next week.
Expand All @@ -93,16 +94,45 @@ class Week extends Equatable {
Week get previous => subtractWeeks(1);

/// Return a list of all days in the week.
List<DateTime> get days {
final monday = day(0);
final days = <DateTime>[];
for (var i in [0, 1, 2, 3, 4, 5, 6]) {
days.add(monday.add(Duration(days: i)));
}
return days;
}
List<DateTime> get days => List.generate(7, (i) => day(0).addDays(i));

/// Return an ISO formatted string like "2020W01".
@override
String toString() => '${year}W${weekNumber.toString().padLeft(2, '0')}';
}

extension DateTimeUtils on DateTime {
/// Alternative to add(days: x) because of daylight-saving issues.
DateTime addDays(int days) => copyWith(day: day + days);

/// Alternative to add(days: x * 7) because of daylight-saving issues.
DateTime addWeeks(int weeks) => copyWith(day: day + weeks * 7);

/// Alternative to subtract(days: 7) because of daylight-saving issues.
DateTime subtractDays(int days) => copyWith(day: day - days);

/// Alternative to subtract(days: x * 7) because of daylight-saving issues.
DateTime subtractWeeks(int weeks) => copyWith(day: day - weeks * 7);

DateTime copyWith({
int? year,
int? month,
int? day,
int? hour,
int? minute,
int? second,
int? millisecond,
int? microsecond,
}) {
return DateTime(
year ?? this.year,
month ?? this.month,
day ?? this.day,
hour ?? this.hour,
minute ?? this.minute,
second ?? this.second,
millisecond ?? this.millisecond,
microsecond ?? this.microsecond,
);
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: isoweek
description: A lightweight Dart package which provides the class Week (based on the ISO 8601 format).
version: 1.1.0
version: 1.1.1
homepage: https://jensbecker.dev
repository: https://github.com/devj3ns/isoweek
issue_tracker: https://github.com/devj3ns/isoweek/issues
Expand Down
10 changes: 10 additions & 0 deletions test/isoweek_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,14 @@ void main() {
expect(monday, equals(monday2));
},
);

test(
'Test if all DateTimes in the days getter have a time of 00:00:00.',
() {
final daysWithTimeEqualToZero = Week.current().days.where(
(date) => date.hour == 0 && date.minute == 0 && date.second == 0);

expect(daysWithTimeEqualToZero.length, equals(7));
},
);
}

0 comments on commit a30ee0f

Please sign in to comment.