lib: Fix splitSpan for nthdayof{week,month} - start of DateSpan was not covered
Demonstration:
Consider year-test.journal:
```
2015/02/01 first half
expenses $1
assets
2015/07/01 second half
expenses $2
assets
2016/02/01 first half
expenses $4
assets
2016/07/01 second half
expenses $8
assets
2017/02/01 first half
expenses $16
assets
2017/07/01 second half
expenses $32
assets
```
Year balances are good:
```
$ hledger balance -f year-test.journal -p yearly
Balance changes in 2015/01/01-2017/12/31:
|| 2015 2016 2017
==========++==================
assets || $-3 $-12 $-48
expenses || $3 $12 $48
----------++------------------
|| 0 0 0
```
Note how first transaction in 2015 is not included. Note that this is old period expression, so this bug exsits in master:
```$ hledger balance -f year-test.journal -p 'every 2nd day of month'
Balance changes in 2015/07/02-2017/07/01:
|| 2015/07/02-2015/08/01 2015/08/02-2015/09/01 2015/09/02-2015/10/01 2015/10/02-2015/11/01 2015/11/02-2015/12/01 2015/12/02-2016/01/01 2016/01/02-2016/02/01 2016/02/02-2016/03/01 2016/03/02-2016/04/01 2016/04/02-2016/05/01 2016/05/02-2016/06/01 2016/06/02-2016/07/01 2016/07/02-2016/08/01 2016/08/02-2016/09/01 2016/09/02-2016/10/01 2016/10/02-2016/11/01 2016/11/02-2016/12/01 2016/12/02-2017/01/01 2017/01/02-2017/02/01 2017/02/02-2017/03/01 2017/03/02-2017/04/01 2017/04/02-2017/05/01 2017/05/02-2017/06/01 2017/06/02-2017/07/01
==========++========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
assets || 0 0 0 0 0 0 $-4 0 0 0 0 $-8 0 0 0 0 0 0 $-16 0 0 0 0 $-32
expenses || 0 0 0 0 0 0 $4 0 0 0 0 $8 0 0 0 0 0 0 $16 0 0 0 0 $32
----------++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
```
Note how 2015 is absent entirely. This is new expression, but i think that general nature of bug is the same...
```
$ hledger balance -f year-test.journal -p 'every 4th Apr'
Balance changes in 2016/04/04-2018/04/03:
|| 2016/04/04-2017/04/03 2017/04/04-2018/04/03
==========++==============================================
assets || $-24 $-32
expenses || $24 $32
----------++----------------------------------------------
|| 0 0
```
This commit is contained in:
parent
fbd28be6cb
commit
4049455f26
@ -165,9 +165,9 @@ spansSpan spans = DateSpan (maybe Nothing spanStart $ headMay spans) (maybe Noth
|
|||||||
-- >>> t (Weeks 2) "2008/01/01" "2008/01/15"
|
-- >>> t (Weeks 2) "2008/01/01" "2008/01/15"
|
||||||
-- [DateSpan 2007/12/31-2008/01/13,DateSpan 2008/01/14-2008/01/27]
|
-- [DateSpan 2007/12/31-2008/01/13,DateSpan 2008/01/14-2008/01/27]
|
||||||
-- >>> t (DayOfMonth 2) "2008/01/01" "2008/04/01"
|
-- >>> t (DayOfMonth 2) "2008/01/01" "2008/04/01"
|
||||||
-- [DateSpan 2008/01/02-2008/02/01,DateSpan 2008/02/02-2008/03/01,DateSpan 2008/03/02-2008/04/01]
|
-- [DateSpan 2007/12/02-2008/01/01,DateSpan 2008/01/02-2008/02/01,DateSpan 2008/02/02-2008/03/01,DateSpan 2008/03/02-2008/04/01]
|
||||||
-- >>> t (DayOfWeek 2) "2011/01/01" "2011/01/15"
|
-- >>> t (DayOfWeek 2) "2011/01/01" "2011/01/15"
|
||||||
-- [DateSpan 2011/01/04-2011/01/10,DateSpan 2011/01/11-2011/01/17]
|
-- [DateSpan 2010/12/28-2011/01/03,DateSpan 2011/01/04-2011/01/10,DateSpan 2011/01/11-2011/01/17]
|
||||||
--
|
--
|
||||||
splitSpan :: Interval -> DateSpan -> [DateSpan]
|
splitSpan :: Interval -> DateSpan -> [DateSpan]
|
||||||
splitSpan _ (DateSpan Nothing Nothing) = [DateSpan Nothing Nothing]
|
splitSpan _ (DateSpan Nothing Nothing) = [DateSpan Nothing Nothing]
|
||||||
@ -461,16 +461,51 @@ prevyear = startofyear . addGregorianYearsClip (-1)
|
|||||||
nextyear = startofyear . addGregorianYearsClip 1
|
nextyear = startofyear . addGregorianYearsClip 1
|
||||||
startofyear day = fromGregorian y 1 1 where (y,_,_) = toGregorian day
|
startofyear day = fromGregorian y 1 1 where (y,_,_) = toGregorian day
|
||||||
|
|
||||||
nthdayofmonthcontaining n d | d1 >= d = d1
|
-- | For given date d find month-long interval that starts on nth day of month
|
||||||
| otherwise = d2
|
-- and covers it.
|
||||||
where d1 = addDays (fromIntegral n-1) s
|
--
|
||||||
d2 = addDays (fromIntegral n-1) $ nextmonth s
|
-- Examples: lets take 2017-11-22. Month-long intervals covering it that
|
||||||
|
-- start on 1st-22nd of month will start in Nov. However
|
||||||
|
-- intervals that start on 23rd-30th of month should start in Oct:
|
||||||
|
-- >>> let wed22nd = parsedate "2017-11-22"
|
||||||
|
-- >>> nthdayofmonthcontaining 1 wed22nd
|
||||||
|
-- 2017-11-01
|
||||||
|
-- >>> nthdayofmonthcontaining 12 wed22nd
|
||||||
|
-- 2017-11-12
|
||||||
|
-- >>> nthdayofmonthcontaining 22 wed22nd
|
||||||
|
-- 2017-11-22
|
||||||
|
-- >>> nthdayofmonthcontaining 23 wed22nd
|
||||||
|
-- 2017-10-23
|
||||||
|
-- >>> nthdayofmonthcontaining 30 wed22nd
|
||||||
|
-- 2017-10-30
|
||||||
|
nthdayofmonthcontaining n d | nthOfSameMonth <= d = nthOfSameMonth
|
||||||
|
| otherwise = nthOfPrevMonth
|
||||||
|
where nthOfSameMonth = addDays (fromIntegral n-1) s
|
||||||
|
nthOfPrevMonth = addDays (fromIntegral n-1) $ prevmonth s
|
||||||
s = startofmonth d
|
s = startofmonth d
|
||||||
|
|
||||||
nthdayofweekcontaining n d | d1 >= d = d1
|
|
||||||
| otherwise = d2
|
-- | For given date d find week-long interval that starts on nth day of week
|
||||||
where d1 = addDays (fromIntegral n-1) s
|
-- and covers it.
|
||||||
d2 = addDays (fromIntegral n-1) $ nextweek s
|
--
|
||||||
|
-- Examples: 2017-11-22 is Wed. Week-long intervals that cover it and
|
||||||
|
-- start on Mon, Tue or Wed will start in the same week. However
|
||||||
|
-- intervals that start on Thu or Fri should start in prev week:
|
||||||
|
-- >>> let wed22nd = parsedate "2017-11-22"
|
||||||
|
-- >>> nthdayofweekcontaining 1 wed22nd
|
||||||
|
-- 2017-11-20
|
||||||
|
-- >>> nthdayofweekcontaining 2 wed22nd
|
||||||
|
-- 2017-11-21
|
||||||
|
-- >>> nthdayofweekcontaining 3 wed22nd
|
||||||
|
-- 2017-11-22
|
||||||
|
-- >>> nthdayofweekcontaining 4 wed22nd
|
||||||
|
-- 2017-11-16
|
||||||
|
-- >>> nthdayofweekcontaining 5 wed22nd
|
||||||
|
-- 2017-11-17
|
||||||
|
nthdayofweekcontaining n d | nthOfSameWeek <= d = nthOfSameWeek
|
||||||
|
| otherwise = nthOfPrevWeek
|
||||||
|
where nthOfSameWeek = addDays (fromIntegral n-1) s
|
||||||
|
nthOfPrevWeek = addDays (fromIntegral n-1) $ prevweek s
|
||||||
s = startofweek d
|
s = startofweek d
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user