hledger-lib-1.52.1: A library providing the core functionality of hledger

Safe Haskell | None
Language | GHC2021

Hledger.Data.DayPartition

Contents

- constructors
- conversions
- operations
- tests

Description

A partition of time into contiguous spans, for defining reporting periods.

Synopsis

- data DayPartition
- boundariesToDayPartition :: NonEmpty Day -> DayPartition
- boundariesToMaybeDayPartition :: [Day] -> Maybe DayPartition
- dayPartitionToNonEmpty :: DayPartition -> NonEmpty (Day, Day)
- dayPartitionToList :: DayPartition -> [(Day, Day)]
- dayPartitionToDateSpans :: DayPartition -> [DateSpan]
- dayPartitionToPeriodData :: DayPartition -> PeriodData Day
- maybeDayPartitionToDateSpans :: Maybe DayPartition -> [DateSpan]
- unionDayPartitions :: DayPartition -> DayPartition -> Maybe DayPartition
- dayPartitionStartEnd :: DayPartition -> (Day, Day)
- dayPartitionFind :: Day -> DayPartition -> (Maybe Day, Day)
- splitSpan :: Bool -> Interval -> DateSpan -> Maybe DayPartition
- intervalBoundaryBefore :: Interval -> Day -> Day
- tests_DayPartition :: TestTree

# Documentation

data DayPartition Source #

A partition of time into one or more contiguous periods, plus a historical period that precedes them. Note `DayPartition` does not store per-period data - only the periods' start/end dates.

#### Instances

Instances details

Show DayPartition Source # |
Instance details Defined in Hledger.Data.DayPartition Methods showsPrec :: Int -> DayPartition -> ShowS Source # show :: DayPartition -> String Source # showList :: [DayPartition] -> ShowS Source #
Eq DayPartition Source # |
Instance details Defined in Hledger.Data.DayPartition Methods (==) :: DayPartition -> DayPartition -> Bool Source # (/=) :: DayPartition -> DayPartition -> Bool Source #
Ord DayPartition Source # |

Instance details

Defined in Hledger.Data.DayPartition

Methods

compare :: DayPartition -> DayPartition -> Ordering Source #

(<) :: DayPartition -> DayPartition -> Bool Source #

(<=) :: DayPartition -> DayPartition -> Bool Source #

(>) :: DayPartition -> DayPartition -> Bool Source #

(>=) :: DayPartition -> DayPartition -> Bool Source #

max :: DayPartition -> DayPartition -> DayPartition Source #

min :: DayPartition -> DayPartition -> DayPartition Source #

# constructors

boundariesToDayPartition :: NonEmpty Day -> DayPartition Source #

Construct a `DayPartition` from a non-empty list of period boundary dates (start dates plus a final exclusive end date).

    >>> boundariesToDayPartition (fromGregorian 2025 01 01 :| [fromGregorian 2025 02 01])
    DayPartition {dayPartitionToPeriodData = PeriodData{ pdpre = 2024-12-31, pdperiods = fromList [(2025-01-01,2025-01-31)]}}

boundariesToMaybeDayPartition :: [Day] -> Maybe DayPartition Source #

Construct a `DayPartition` from a list of period boundary dates (start dates plus a final exclusive end date), if it's a non-empty list.

# conversions

dayPartitionToNonEmpty :: DayPartition -> NonEmpty (Day, Day) Source #

Convert `DayPartition` to a non-empty list of period start and end dates (both inclusive). Each end date will be one day before the next period's start date.

dayPartitionToList :: DayPartition -> [(Day, Day)] Source #

Convert `DayPartition` to a list (which will always be non-empty) of period start and end dates (both inclusive). Each end date will be one day before the next period's start date.

dayPartitionToDateSpans :: DayPartition -> [DateSpan] Source #

Convert `DayPartition` to a list of `DateSpan`s. Each span will end one day before the next span begins (the span's exclusive end date will be equal to the next span's start date).

dayPartitionToPeriodData :: DayPartition -> PeriodData Day Source #

maybeDayPartitionToDateSpans :: Maybe DayPartition -> [DateSpan] Source #

# operations

unionDayPartitions :: DayPartition -> DayPartition -> Maybe DayPartition Source #

Return the union of two `DayPartition`s if that is a valid `DayPartition`, or `Nothing` otherwise.

dayPartitionStartEnd :: DayPartition -> (Day, Day) Source #

Get this DayPartition's overall start date and end date (both inclusive).

dayPartitionFind :: Day -> DayPartition -> (Maybe Day, Day) Source #

Find the start and end dates of the period within a `DayPartition` which contains a given day. If the day is after the end of the last period, it is assumed to be within the last period. If the day is before the start of the first period (ie, in the historical period), only the historical period's end date is returned.

splitSpan :: Bool -> Interval -> DateSpan -> Maybe DayPartition Source #

Split a `DateSpan` into a `DayPartition` consisting of consecutive exact spans of the specified Interval, or `Nothing` if the span is invalid. If no interval is specified, the original span is returned. If the original span is the null date span, ie unbounded, `Nothing` is returned. If the original span is empty, eg if the end date is <= the start date, `Nothing` is returned.

#### Date adjustment

Some intervals respect the "adjust" flag (years, quarters, months, weeks, every Nth weekday of month seem to be the ones that need it). This will move the start date earlier, if needed, to the previous natural interval boundary (first of year, first of quarter, first of month, monday, previous Nth weekday of month). Related: #1982 #2218

The end date is always moved later if needed to the next natural interval boundary, so that the last period is the same length as the others.

#### Examples

    >>> let t i y1 m1 d1 y2 m2 d2 = fmap dayPartitionToNonEmpty . splitSpan True i $ DateSpan (Just $ Flex $ fromGregorian y1 m1 d1) (Just $ Flex $ fromGregorian y2 m2 d2)
    >>> t NoInterval 2008 01 01 2009 01 01
    Just ((2008-01-01,2008-12-31) :| [])
    >>> t (Quarters 1) 2008 01 01 2009 01 01
    Just ((2008-01-01,2008-03-31) :| [(2008-04-01,2008-06-30),(2008-07-01,2008-09-30),(2008-10-01,2008-12-31)])
    >>> splitSpan True (Quarters 1) nulldatespan
    Nothing
    >>> t (Days 1) 2008 01 01 2008 01 01  -- an empty datespan
    Nothing
    >>> t (Quarters 1) 2008 01 01 2008 01 01
    Nothing
    >>> t (Months 1) 2008 01 01 2008 04 01
    Just ((2008-01-01,2008-01-31) :| [(2008-02-01,2008-02-29),(2008-03-01,2008-03-31)])
    >>> t (Months 2) 2008 01 01 2008 04 01
    Just ((2008-01-01,2008-02-29) :| [(2008-03-01,2008-04-30)])
    >>> t (Weeks 1) 2008 01 01 2008 01 15
    Just ((2007-12-31,2008-01-06) :| [(2008-01-07,2008-01-13),(2008-01-14,2008-01-20)])
    >>> t (Weeks 2) 2008 01 01 2008 01 15
    Just ((2007-12-31,2008-01-13) :| [(2008-01-14,2008-01-27)])
    >>> t (MonthDay 2) 2008 01 01 2008 04 01
    Just ((2008-01-02,2008-02-01) :| [(2008-02-02,2008-03-01),(2008-03-02,2008-04-01)])
    >>> t (NthWeekdayOfMonth 2 4) 2011 01 01 2011 02 15
    Just ((2010-12-09,2011-01-12) :| [(2011-01-13,2011-02-09),(2011-02-10,2011-03-09)])
    >>> t (DaysOfWeek [2]) 2011 01 01 2011 01 15
    Just ((2010-12-28,2011-01-03) :| [(2011-01-04,2011-01-10),(2011-01-11,2011-01-17)])
    >>> t (MonthAndDay 11 29) 2012 10 01 2013 10 15
    Just ((2012-11-29,2013-11-28) :| [])

intervalBoundaryBefore :: Interval -> Day -> Day Source #

Get the natural start for the given interval that falls on or before the given day, when applicable. Works for Weeks, Months, Quarters, Years, eg.

# tests

tests_DayPartition :: TestTree Source #