haskell / time

A time library

Home Page:http://hackage.haskell.org/package/time

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

  1. 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 after x. Your formula (I think you meant 52 or 53) is not sequential.
  2. It's not clear when the start of the week is (which is why DayOfWeek has a circular Enum instance and no Bounded instance). The traditional start of the week is Sunday ("the First Day"), but the common understanding, and ISO 8601, is Monday. The functions in Data.Time.Calendar.WeekDate allow you to pick any day. The WeekOfYear 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.