hledger icon indicating copy to clipboard operation
hledger copied to clipboard

"every Nth day" periodic rule violating start date

Open simonmichael opened this issue 1 year ago • 4 comments
trafficstars

Reported on the mail list by LucaBH. Here's a small repro:

~ every 31st day from 2024-07 to 2024-09
  (a)  1
$ hledger -f a.j print --forecast=2024
2024-06-30       ;  <- we don't expect this one to be generated
    (a)               1

2024-07-31
    (a)               1

2024-08-31
    (a)               1

simonmichael avatar Aug 24 '24 18:08 simonmichael

This is caused by

splitSpan _ (DayOfMonth dom)  ds = splitspan (nthdayofmonthcontaining dom) (addGregorianMonthsToMonthday dom) 1 ds

Namely, nthdayofmonthcontaining shifts start date back to 30th:

nthdayofmonthcontaining :: MonthDay -> Day -> Day
nthdayofmonthcontaining mdy date
  -- PARTIAL:
  | not (validDay mdy) = error' $ "nthdayofmonthcontaining: invalid day "  ++show mdy
  | nthOfSameMonth <= date = nthOfSameMonth
  | otherwise = nthOfPrevMonth
  where nthOfSameMonth = nthdayofmonth mdy s
        nthOfPrevMonth = nthdayofmonth mdy $ prevmonth s
        s = startofmonth date

Note that splitSpan explicitly calls for this behavior, but I don't know why this behavior is desired:

-- | Split a DateSpan into consecutive exact spans of the specified Interval.
-- If the first argument is true and the interval is Weeks, Months, Quarters or Years,
-- the start date will be adjusted backward if needed to nearest natural interval boundary
-- (a monday, first of month, first of quarter or first of year).

adept avatar Aug 24 '24 22:08 adept

The fix, i think, would be to filter the output of splitSpan here: https://github.com/simonmichael/hledger/blob/f001b23114c43776b31681b1bc5d85b0238a39d7/hledger-lib/Hledger/Data/PeriodicTransaction.hs#L233

and reject first returned subspans if they are from before the start of ptiterval

adept avatar Aug 24 '24 22:08 adept

Assuming that there is no need/desire to change the behavior of splitSpan, I pushed a simple fix to periodic transaction generator (that is described above)

adept avatar Aug 24 '24 22:08 adept

Thanks! I imagine the splitSpan behaviour was to support https://hledger.org/dev/hledger.html#date-adjustments . But that shifted a bit in the last year. Your fix may be all that's needed, I'll test a bit more as well.

simonmichael avatar Aug 25 '24 09:08 simonmichael

I've pushed #2221, which fixes the start date in these cases:

  • every Nth day of month from DATE with periodic transactions
  • every M/D from DATE
  • every M/D from DATE with periodic transactions
  • every Nth WEEKDAY from DATE

and brings new docs and tests:

  • https://hledger.org/dev/hledger.html#date-adjustments
  • https://hledger.org/dev/hledger.html#period-headings
  • https://github.com/simonmichael/hledger/blob/master/hledger/test/register/intervals.test#L140-L248

simonmichael avatar Sep 04 '24 14:09 simonmichael

Fixed by #2221.

simonmichael avatar Sep 04 '24 15:09 simonmichael