Scope Week to a year and create DayPeriod instance
felixminom opened this issue · comments
As there's two abstractions for Weeks: WeekOfYear
which returns the week of the year as and Integer and DayOfWeek
that is basically to build days of the week. I'd like to have something like Week
as it exists for Month where the month is scoped to a year. I think having the same abstraction for weeks will be useful since we could create an instance of DayPeriod
(introduced in 1.12.1) and have some useful functions as: periodFirstDay
, periodFirstDay
and periodAllDays
. The idea will be to have something like this (year * 12) + (weekOfYear - 1)
. Please let me know if this makes sense to you, so I could open a PR with these changes. Thanks
The reasons I haven't done this are:
- There is no canonical sequential numbering of weeks. Note that all the current instances of
DayPeriod
are sequential, that is,succ x
gives the period afterx
. Your formula (I think you meant 52 or 53) is not sequential. - It's not clear when the start of the week is (which is why
DayOfWeek
has a circularEnum
instance and noBounded
instance). The traditional start of the week is Sunday ("the First Day"), but the common understanding, and ISO 8601, is Monday. The functions inData.Time.Calendar.WeekDate
allow you to pick any day. TheWeekOfYear
type is ambiguous ("by various reckonings").
@AshleyYakeley thank you for bringing this up, I didn't notice the addition of Ord
as a type constraint to DayPeriod
on the other hand as you mentioned: "there is no canonical sequential numbering of weeks". I talked with @felixminom and another friend about this and maybe a helper function that returns a standard week of 7 days based on a given day and a DayOfWeek
could be useful, the type signature would look as follows:
weekAllDays :: DayOfWeek -> Day -> [Day]
The output would look like this:
λ> weekAllDays Monday (YearMonthDay 2021 11 1)
[2021-11-01,2021-11-02,2021-11-03,2021-11-04,2021-11-05,2021-11-06,2021-11-07]
λ> weekAllDays Tuesday (YearMonthDay 2021 11 1)
[2021-10-26,2021-10-27,2021-10-28,2021-10-29,2021-10-30,2021-10-31,2021-11-01]
λ> weekAllDays Wednesday (YearMonthDay 2021 11 1)
[2021-10-27,2021-10-28,2021-10-29,2021-10-30,2021-10-31,2021-11-01,2021-11-02]
λ> weekAllDays Thursday (YearMonthDay 2021 11 1)
[2021-10-28,2021-10-29,2021-10-30,2021-10-31,2021-11-01,2021-11-02,2021-11-03]
λ> weekAllDays Friday (YearMonthDay 2021 11 1)
[2021-10-29,2021-10-30,2021-10-31,2021-11-01,2021-11-02,2021-11-03,2021-11-04]
λ> weekAllDays Saturday (YearMonthDay 2021 11 1)
[2021-10-30,2021-10-31,2021-11-01,2021-11-02,2021-11-03,2021-11-04,2021-11-05]
λ> weekAllDays Sunday (YearMonthDay 2021 11 1)
[2021-10-31,2021-11-01,2021-11-02,2021-11-03,2021-11-04,2021-11-05,2021-11-06]
Similar to periodAllDays but without implementing a DayPeriod
instance for weeks for the reasons you explained above. What do you think?
Might add something like this for 1.12.2.
@AshleyYakeley - @felixminom and I are more than happy to submit a PR for this, in fact, we already had something in place that we use to post the output above. If you don't mind we would like to carry this on.