diff --git a/lib/src/time/util.dart b/lib/src/time/util.dart index 072e030b..ff9a2066 100644 --- a/lib/src/time/util.dart +++ b/lib/src/time/util.dart @@ -54,3 +54,51 @@ int clampDayOfMonth({ required int day, }) => day.clamp(1, daysInMonth(year, month)); + +///return the day which is xth [weekDay] from yth [week] of zth [month] of a [year] +///eg. DateTime.Friday from 2nd week of DateTime.july of a 2022 year. +/// [weekDay] ranges from 1 to 7. 1 = monday and 7 = sunday. +/// [week] ranges from 1 to 4 or 5 month depending upon the month. +/// [month] ranges from 1 to 12. 1 is january and 12 is december. +/// [year] the year in which you are calculating +/// if the number of week is more than the weeks in specific month day will be from another month +DateTime nthDayOnNthWeekOfAMonth( + int weekDay, + int week, + int month, + int year, +) { + final firstDateOfMonth = DateTime(year, month, 1); + return firstDateOfMonth.add( + Duration( + days: 7 * (week - 1) + + ((firstDateOfMonth.weekday > weekDay ? 7 : 0) + + weekDay - + firstDateOfMonth.weekday), + ), + ); +} + +///return the day which is xth last [weekDay] from yth [week] of zth [month] of a [year] +///eg. DateTime.Friday from 2nd last week of DateTime.july of a 2022 year. +/// [weekDay] ranges from 1 to 7. 1 = monday and 7 = sunday. +/// [week] ranges from 1 to 4 or 5 month depending upon the month. +/// [month] ranges from 1 to 12. 1 is january and 12 is december. +/// [year] the year in which you are calculating +/// if the number of week is more than the weeks in specific month day will be from another month +DateTime lastNthDayOnNthWeekOfAMonth( + int weekDay, + int week, + int month, + int year, +) { + final lastDateOfMonth = DateTime(year, month, daysInMonth(year, month)); + + return lastDateOfMonth.subtract( + Duration( + days: (7 - weekDay) + + 7 * (week - 1) - + (lastDateOfMonth.weekday < weekDay ? 7 : 0), + ), + ); +} diff --git a/test/time/all_tests.dart b/test/time/all_tests.dart index 2f5bbd58..f01a89f4 100644 --- a/test/time/all_tests.dart +++ b/test/time/all_tests.dart @@ -15,7 +15,9 @@ library quiver.time.all_tests; import 'clock_test.dart' as clock; +import 'util_test.dart' as util; void main() { clock.main(); + util.main(); } diff --git a/test/time/util_test.dart b/test/time/util_test.dart new file mode 100644 index 00000000..ecdea175 --- /dev/null +++ b/test/time/util_test.dart @@ -0,0 +1,39 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the 'License'); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +library quiver.time.util_test; + +import 'package:quiver/src/time/util.dart'; +import 'package:test/test.dart'; + +void expectDate(DateTime date, int y, [int m = 1, int d = 1]) { + expect(date, DateTime(y, m, d)); +} + +void main() { + group('util', () { + test('should return the date of friday from 2nd week of july of 2022', () { + final calculatedDate = + nthDayOnNthWeekOfAMonth(DateTime.friday, 2, DateTime.july, 2022); + expectDate(calculatedDate, 2022, 7, 8); + }); + + test('should return the date of friday from 2nd last week of feb of 2022', + () { + final calculatedDate = lastNthDayOnNthWeekOfAMonth( + DateTime.friday, 2, DateTime.february, 2022); + expectDate(calculatedDate, 2022, 2, 26); + }); + }); +}