lib: use Period for rendering DateSpans

This commit is contained in:
Simon Michael 2016-07-29 11:00:29 -07:00
parent 94537f30d4
commit 7d81adcefa
4 changed files with 27 additions and 62 deletions

View File

@ -21,6 +21,8 @@ with both ends unspecified matches all dates.)
An 'Interval' is ledger's \"reporting interval\" - weekly, monthly, An 'Interval' is ledger's \"reporting interval\" - weekly, monthly,
quarterly, etc. quarterly, etc.
'Period' will probably replace DateSpan in due course.
-} -}
-- XXX fromGregorian silently clips bad dates, use fromGregorianValid instead ? -- XXX fromGregorian silently clips bad dates, use fromGregorianValid instead ?
@ -80,7 +82,6 @@ import System.Locale (TimeLocale, defaultTimeLocale)
#endif #endif
import Data.Time.Calendar import Data.Time.Calendar
import Data.Time.Calendar.OrdinalDate import Data.Time.Calendar.OrdinalDate
import Data.Time.Calendar.WeekDate
import Data.Time.Clock import Data.Time.Clock
import Data.Time.LocalTime import Data.Time.LocalTime
import Safe (headMay, lastMay, readMay) import Safe (headMay, lastMay, readMay)
@ -89,6 +90,7 @@ import Text.Megaparsec.Text
import Text.Printf import Text.Printf
import Hledger.Data.Types import Hledger.Data.Types
import Hledger.Data.Period
import Hledger.Utils import Hledger.Utils
@ -100,65 +102,10 @@ instance Show DateSpan where
showDate :: Day -> String showDate :: Day -> String
showDate = formatTime defaultTimeLocale "%0C%y/%m/%d" showDate = formatTime defaultTimeLocale "%0C%y/%m/%d"
-- XXX review for more boundary crossing issues
-- | Render a datespan as a display string, abbreviating into a -- | Render a datespan as a display string, abbreviating into a
-- compact form if possible. -- compact form if possible.
showDateSpan ds@(DateSpan (Just from) (Just to)) = showDateSpan :: DateSpan -> String
case (toGregorian from, toGregorian to) of showDateSpan = showPeriod . dateSpanAsPeriod
-- special cases we can abbreviate:
-- a year, YYYY
((fy,1,1), (ty,1,1)) | fy+1==ty -> formatTime defaultTimeLocale "%0C%y" from
-- a half, YYYYhN
((fy,1,1), (ty,7,1)) | fy==ty -> formatTime defaultTimeLocale "%0C%yh1" from
((fy,7,1), (ty,1,1)) | fy+1==ty -> formatTime defaultTimeLocale "%0C%yh2" from
-- a quarter, YYYYqN
((fy,1,1), (ty,4,1)) | fy==ty -> formatTime defaultTimeLocale "%0C%yq1" from
((fy,4,1), (ty,7,1)) | fy==ty -> formatTime defaultTimeLocale "%0C%yq2" from
((fy,7,1), (ty,10,1)) | fy==ty -> formatTime defaultTimeLocale "%0C%yq3" from
((fy,10,1), (ty,1,1)) | fy+1==ty -> formatTime defaultTimeLocale "%0C%yq4" from
-- a month, YYYY/MM
((fy,fm,1), (ty,tm,1)) | fy==ty && fm+1==tm -> formatTime defaultTimeLocale "%0C%y/%m" from
((fy,12,1), (ty,1,1)) | fy+1==ty -> formatTime defaultTimeLocale "%0C%y/%m" from
-- a week (two successive mondays),
-- YYYYwN ("week N of year YYYY")
-- _ | let ((fy,fw,fd), (ty,tw,td)) = (toWeekDate from, toWeekDate to) in fy==ty && fw+1==tw && fd==1 && td==1
-- -> formatTime defaultTimeLocale "%0f%gw%V" from
-- YYYY/MM/DDwN ("week N, starting on YYYY/MM/DD")
_ | let ((fy,fw,fd), (ty,tw,td)) = (toWeekDate from, toWeekDate (addDays (-1) to)) in fy==ty && fw==tw && fd==1 && td==7
-> formatTime defaultTimeLocale "%0C%y/%m/%dw%V" from
-- a day, YYYY/MM/DDd (d suffix is to distinguish from a regular date in register)
((fy,fm,fd), (ty,tm,td)) | fy==ty && fm==tm && fd+1==td -> formatTime defaultTimeLocale "%0C%y/%m/%dd" from
-- ((fy,fm,fd), (ty,tm,td)) | fy==ty && fm==tm && fd+1==td -> formatTime defaultTimeLocale "%0C%y/%m/%d" from -- try without the d
-- crossing a year boundary
((fy,fm,fd), (ty,tm,td)) | fy+1==ty && fm==12 && tm==1 && fd==31 && td==1 -> formatTime defaultTimeLocale "%0C%y/%m/%dd" from
-- crossing a month boundary XXX wrongly shows LEAPYEAR/2/28-LEAPYEAR/3/1 as LEAPYEAR/2/28
((fy,fm,fd), (ty,tm,td)) | fy==ty && fm+1==tm && fd `elem` fromMaybe [] (lookup fm lastdayofmonth) && td==1 -> formatTime defaultTimeLocale "%0C%y/%m/%dd" from
-- otherwise, YYYY/MM/DD-YYYY/MM/DD
_ -> showDateSpan' ds
where lastdayofmonth = [(1,[31])
,(2,[28,29])
,(3,[31])
,(4,[30])
,(5,[31])
,(6,[30])
,(7,[31])
,(8,[31])
,(9,[30])
,(10,[31])
,(11,[30])
,(12,[31])
]
showDateSpan ds = showDateSpan' ds
-- | Render a datespan as a display string like [START]-[ENDINCL]
-- (optional start date, hyphen, optional inclusive end date).
showDateSpan' (DateSpan from to) =
concat
[maybe "" showDate from
,"-"
,maybe "" (showDate . prevday) to
]
-- | Get the current local date. -- | Get the current local date.
getCurrentDay :: IO Day getCurrentDay :: IO Day

View File

@ -1,7 +1,7 @@
{-| {-|
Manipulating the time periods typically used for reports Manipulate the time periods typically used for reports with Period,
using Period, a richer abstraction than DateSpan. a richer abstraction that will probably replace DateSpan.
See also Types and Dates. See also Types and Dates.
-} -}
@ -11,9 +11,10 @@ where
import Data.Time.Calendar import Data.Time.Calendar
import Data.Time.Calendar.WeekDate import Data.Time.Calendar.WeekDate
import Data.Time.Format
import Text.Printf
import Hledger.Data.Types import Hledger.Data.Types
import Hledger.Data.Dates () -- DateSpan Show instance
-- | Convert Periods to DateSpans. -- | Convert Periods to DateSpans.
-- --
@ -116,3 +117,18 @@ isLastDayOfMonth y m d =
12 -> d==31 12 -> d==31
_ -> False _ -> False
-- | Render a period as a compact display string suitable for user output.
--
-- >>> showPeriod (WeekPeriod (fromGregorian 2016 7 25))
-- "2016/07/25w30"
showPeriod (DayPeriod b) = formatTime defaultTimeLocale "%0C%y/%m/%dd" b -- DATEd
showPeriod (WeekPeriod b) = formatTime defaultTimeLocale "%0C%y/%m/%dw%V" b -- STARTDATEwYEARWEEK
showPeriod (MonthPeriod y m) = printf "%04d/%02d" y m -- YYYY/MM
showPeriod (QuarterPeriod y q) = printf "%04dq%d" y q -- YYYYqN
showPeriod (YearPeriod y) = printf "%04d" y -- YYYY
showPeriod (PeriodBetween b e) = formatTime defaultTimeLocale "%0C%y/%m/%d" b
++ formatTime defaultTimeLocale "-%0C%y/%m/%d" (addDays (-1) e) -- STARTDATE-INCLUSIVEENDDATE
showPeriod (PeriodFrom b) = formatTime defaultTimeLocale "%0C%y/%m/%d-" b -- STARTDATE-
showPeriod (PeriodTo e) = formatTime defaultTimeLocale "-%0C%y/%m/%d" (addDays (-1) e) -- -INCLUSIVEENDDATE
showPeriod PeriodAll = "-"

View File

@ -120,9 +120,10 @@ library:
- Hledger.Data.Dates - Hledger.Data.Dates
- Hledger.Data.Journal - Hledger.Data.Journal
- Hledger.Data.Ledger - Hledger.Data.Ledger
- Hledger.Data.StringFormat - Hledger.Data.Period
- Hledger.Data.Posting - Hledger.Data.Posting
- Hledger.Data.RawOptions - Hledger.Data.RawOptions
- Hledger.Data.StringFormat
- Hledger.Data.Timeclock - Hledger.Data.Timeclock
- Hledger.Data.Transaction - Hledger.Data.Transaction
- Hledger.Data.Types - Hledger.Data.Types

View File

@ -109,6 +109,7 @@ library
Hledger.Data.Dates Hledger.Data.Dates
Hledger.Data.Journal Hledger.Data.Journal
Hledger.Data.Ledger Hledger.Data.Ledger
Hledger.Data.Period
Hledger.Data.StringFormat Hledger.Data.StringFormat
Hledger.Data.Posting Hledger.Data.Posting
Hledger.Data.RawOptions Hledger.Data.RawOptions