mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-07 21:15:19 +03:00
gather date stuff together, FuzzyDate -> SmartDate
This commit is contained in:
parent
52ab3372b8
commit
884ebf2979
@ -10,6 +10,7 @@ module Ledger (
|
||||
module Ledger.AccountName,
|
||||
module Ledger.Amount,
|
||||
module Ledger.Commodity,
|
||||
module Ledger.Dates,
|
||||
module Ledger.Entry,
|
||||
module Ledger.Ledger,
|
||||
module Ledger.Parse,
|
||||
@ -25,6 +26,7 @@ import Ledger.Account
|
||||
import Ledger.AccountName
|
||||
import Ledger.Amount
|
||||
import Ledger.Commodity
|
||||
import Ledger.Dates
|
||||
import Ledger.Entry
|
||||
import Ledger.Ledger
|
||||
import Ledger.Parse
|
||||
|
215
Ledger/Dates.hs
215
Ledger/Dates.hs
@ -1,21 +1,16 @@
|
||||
{-|
|
||||
|
||||
Types for Dates and DateTimes, implemented in terms of UTCTime
|
||||
'Date' and 'DateTime' are a helper layer on top of the standard UTCTime,
|
||||
Day etc.
|
||||
|
||||
A 'SmartDate' is a date which may be partially-specified or relative.
|
||||
Eg 2008/12/31, but also 2008/12, 12/31, tomorrow, last week, next year.
|
||||
We represent these as a triple of strings like ("2008","12",""),
|
||||
("","","tomorrow"), ("","last","week").
|
||||
|
||||
-}
|
||||
|
||||
module Ledger.Dates
|
||||
--(
|
||||
-- Date,
|
||||
-- DateTime,
|
||||
-- mkDate,
|
||||
-- mkDateTime,
|
||||
-- parsedatetime,
|
||||
-- parsedate,
|
||||
-- datetimeToDate,
|
||||
-- elapsedSeconds,
|
||||
-- today
|
||||
-- )
|
||||
where
|
||||
|
||||
import Data.Time.Clock
|
||||
@ -25,12 +20,12 @@ import Data.Time.LocalTime
|
||||
import System.Locale (defaultTimeLocale)
|
||||
import Text.Printf
|
||||
import Data.Maybe
|
||||
import Text.ParserCombinators.Parsec
|
||||
import Text.ParserCombinators.Parsec.Char
|
||||
import Text.ParserCombinators.Parsec.Combinator
|
||||
import Ledger.Types
|
||||
import Ledger.Utils
|
||||
|
||||
newtype Date = Date UTCTime
|
||||
deriving (Ord, Eq)
|
||||
|
||||
newtype DateTime = DateTime UTCTime
|
||||
deriving (Ord, Eq)
|
||||
|
||||
instance Show Date where
|
||||
show (Date t) = formatTime defaultTimeLocale "%Y/%m/%d" t
|
||||
@ -38,12 +33,6 @@ instance Show Date where
|
||||
instance Show DateTime where
|
||||
show (DateTime t) = formatTime defaultTimeLocale "%Y/%m/%d %H:%M:%S" t
|
||||
|
||||
-- | A fuzzy date is either a partially-specified or a relative date.
|
||||
-- We represent it as a triple of strings such as
|
||||
-- ("2008","01","01") or ("2008","","") or ("","","tomorrow") or
|
||||
-- ("","last|this|next","day|week|month|quarter|year").
|
||||
type FuzzyDate = (String,String,String)
|
||||
|
||||
mkDate :: Day -> Date
|
||||
mkDate day = Date (localTimeToUTC utc (LocalTime day midnight))
|
||||
|
||||
@ -58,23 +47,6 @@ today = do
|
||||
now :: IO DateTime
|
||||
now = fmap DateTime getCurrentTime
|
||||
|
||||
-- | Parse a date-time string to a time type, or raise an error.
|
||||
parsedatetime :: String -> DateTime
|
||||
parsedatetime s = DateTime $
|
||||
parsetimewith "%Y/%m/%d %H:%M:%S" s $
|
||||
error $ printf "could not parse timestamp \"%s\"" s
|
||||
|
||||
-- | Parse a date string to a time type, or raise an error.
|
||||
parsedate :: String -> Date
|
||||
parsedate s = Date $
|
||||
parsetimewith "%Y/%m/%d" s $
|
||||
error $ printf "could not parse date \"%s\"" s
|
||||
|
||||
-- | Parse a time string to a time type using the provided pattern, or
|
||||
-- return the default.
|
||||
parsetimewith :: ParseTime t => String -> String -> t -> t
|
||||
parsetimewith pat s def = fromMaybe def $ parseTime defaultTimeLocale pat s
|
||||
|
||||
datetimeToDate :: DateTime -> Date
|
||||
datetimeToDate (DateTime (UTCTime{utctDay=day})) = Date (UTCTime day 0)
|
||||
|
||||
@ -92,3 +64,166 @@ dateDay date = d where (_,_,d) = dateComponents date
|
||||
|
||||
-- dateMonth :: Date -> Day
|
||||
dateMonth date = m where (_,m,_) = dateComponents date
|
||||
|
||||
-- | Convert a fuzzy date string to an explicit yyyy/mm/dd string using
|
||||
-- the provided date as reference point.
|
||||
fixSmartDateStr :: Date -> String -> String
|
||||
fixSmartDateStr t s = printf "%04d/%02d/%02d" y m d
|
||||
where
|
||||
pdate = fromparse $ parsewith smartdate $ map toLower s
|
||||
(y,m,d) = dateComponents $ fixSmartDate t pdate
|
||||
|
||||
-- | Convert a SmartDate to an absolute date using the provided date as
|
||||
-- reference point.
|
||||
fixSmartDate :: Date -> SmartDate -> Date
|
||||
fixSmartDate refdate sdate = mkDate $ fromGregorian y m d
|
||||
where
|
||||
(y,m,d) = fix sdate
|
||||
fix :: SmartDate -> (Integer,Int,Int)
|
||||
fix ("","","today") = (ry, rm, rd)
|
||||
fix ("","this","day") = (ry, rm, rd)
|
||||
fix ("","","yesterday") = dateComponents $ lastday refdate
|
||||
fix ("","last","day") = dateComponents $ lastday refdate
|
||||
fix ("","","tomorrow") = dateComponents $ nextday refdate
|
||||
fix ("","next","day") = dateComponents $ nextday refdate
|
||||
fix ("","last","week") = dateComponents $ lastweek refdate
|
||||
fix ("","this","week") = dateComponents $ thisweek refdate
|
||||
fix ("","next","week") = dateComponents $ nextweek refdate
|
||||
fix ("","",d) = (ry, rm, read d)
|
||||
fix ("",m,d) = (ry, read m, read d)
|
||||
fix (y,m,d) = (read y, read m, read d)
|
||||
(ry,rm,rd) = dateComponents refdate
|
||||
|
||||
lastday, nextday :: Date -> Date
|
||||
lastday = mkDate . (addDays (-1)) . utctDay . dateToUTC
|
||||
nextday = mkDate . (addDays 1) . utctDay . dateToUTC
|
||||
lastweek = mkDate . (addDays (-7)) . utctDay . dateToUTC
|
||||
thisweek = mkDate . (addDays 0) . utctDay . dateToUTC
|
||||
nextweek = mkDate . (addDays 7) . utctDay . dateToUTC
|
||||
|
||||
----------------------------------------------------------------------
|
||||
-- parsing
|
||||
|
||||
-- | Parse a date-time string to a time type, or raise an error.
|
||||
parsedatetime :: String -> DateTime
|
||||
parsedatetime s = DateTime $
|
||||
parsetimewith "%Y/%m/%d %H:%M:%S" s $
|
||||
error $ printf "could not parse timestamp \"%s\"" s
|
||||
|
||||
-- | Parse a date string to a time type, or raise an error.
|
||||
parsedate :: String -> Date
|
||||
parsedate s = Date $
|
||||
parsetimewith "%Y/%m/%d" s $
|
||||
error $ printf "could not parse date \"%s\"" s
|
||||
|
||||
-- | Parse a time string to a time type using the provided pattern, or
|
||||
-- return the default.
|
||||
parsetimewith :: ParseTime t => String -> String -> t -> t
|
||||
parsetimewith pat s def = fromMaybe def $ parseTime defaultTimeLocale pat s
|
||||
|
||||
{-|
|
||||
Parse a date in any of the formats allowed in ledger's period expressions,
|
||||
and maybe some others:
|
||||
|
||||
> 2004
|
||||
> 2004/10
|
||||
> 2004/10/1
|
||||
> 10/1
|
||||
> 21
|
||||
> october, oct
|
||||
> yesterday, today, tomorrow
|
||||
> (not yet) this/next/last week/day/month/quarter/year
|
||||
|
||||
Returns a SmartDate, to be converted to a full date later (see fixSmartDate).
|
||||
Assumes any text in the parse stream has been lowercased.
|
||||
-}
|
||||
smartdate :: Parser SmartDate
|
||||
smartdate = do
|
||||
let dateparsers = [ymd, ym, md, y, d, month, mon, today', yesterday, tomorrow
|
||||
-- lastthisnextthing
|
||||
]
|
||||
(y,m,d) <- choice $ map try dateparsers
|
||||
return $ (y,m,d)
|
||||
|
||||
datesepchar = oneOf "/-."
|
||||
|
||||
ymd :: Parser SmartDate
|
||||
ymd = do
|
||||
y <- many1 digit
|
||||
datesepchar
|
||||
m <- many1 digit
|
||||
guard (read m <= 12)
|
||||
datesepchar
|
||||
d <- many1 digit
|
||||
guard (read d <= 31)
|
||||
return (y,m,d)
|
||||
|
||||
ym :: Parser SmartDate
|
||||
ym = do
|
||||
y <- many1 digit
|
||||
guard (read y > 12)
|
||||
datesepchar
|
||||
m <- many1 digit
|
||||
guard (read m <= 12)
|
||||
return (y,m,"1")
|
||||
|
||||
y :: Parser SmartDate
|
||||
y = do
|
||||
y <- many1 digit
|
||||
guard (read y >= 1000)
|
||||
return (y,"1","1")
|
||||
|
||||
d :: Parser SmartDate
|
||||
d = do
|
||||
d <- many1 digit
|
||||
guard (read d <= 31)
|
||||
return ("","",d)
|
||||
|
||||
md :: Parser SmartDate
|
||||
md = do
|
||||
m <- many1 digit
|
||||
guard (read m <= 12)
|
||||
datesepchar
|
||||
d <- many1 digit
|
||||
guard (read d <= 31)
|
||||
return ("",m,d)
|
||||
|
||||
months = ["january","february","march","april","may","june",
|
||||
"july","august","september","october","november","december"]
|
||||
|
||||
mons = ["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]
|
||||
|
||||
month :: Parser SmartDate
|
||||
month = do
|
||||
m <- choice $ map string months
|
||||
let i = maybe 0 (+1) $ (map toLower m) `elemIndex` months
|
||||
return ("",show i,"1")
|
||||
|
||||
mon :: Parser SmartDate
|
||||
mon = do
|
||||
m <- choice $ map string mons
|
||||
let i = maybe 0 (+1) $ (map toLower m) `elemIndex` mons
|
||||
return ("",show i,"1")
|
||||
|
||||
today',yesterday,tomorrow :: Parser SmartDate
|
||||
today' = string "today" >> return ("","","today")
|
||||
yesterday = string "yesterday" >> return ("","","yesterday")
|
||||
tomorrow = string "tomorrow" >> return ("","","tomorrow")
|
||||
|
||||
lastthisnextthing :: Parser SmartDate
|
||||
lastthisnextthing = do
|
||||
r <- choice [
|
||||
string "last"
|
||||
,string "this"
|
||||
,string "next"
|
||||
]
|
||||
many1 spacenonewline
|
||||
p <- choice [
|
||||
string "day"
|
||||
,string "week"
|
||||
,string "month"
|
||||
,string "quarter"
|
||||
,string "year"
|
||||
]
|
||||
return ("",r,p)
|
||||
|
||||
|
@ -9,6 +9,7 @@ module Ledger.Entry
|
||||
where
|
||||
import Ledger.Utils
|
||||
import Ledger.Types
|
||||
import Ledger.Dates
|
||||
import Ledger.RawTransaction
|
||||
import Ledger.Amount
|
||||
|
||||
|
119
Ledger/Parse.hs
119
Ledger/Parse.hs
@ -15,6 +15,7 @@ import System.IO
|
||||
import qualified Data.Map as Map
|
||||
import Ledger.Utils
|
||||
import Ledger.Types
|
||||
import Ledger.Dates
|
||||
import Ledger.Amount
|
||||
import Ledger.Entry
|
||||
import Ledger.Commodity
|
||||
@ -412,18 +413,6 @@ numberpartsstartingwithpoint = do
|
||||
return ("",frac)
|
||||
|
||||
|
||||
spacenonewline :: Parser Char
|
||||
spacenonewline = satisfy (\c -> c `elem` " \v\f\t")
|
||||
|
||||
restofline :: Parser String
|
||||
restofline = anyChar `manyTill` newline
|
||||
|
||||
whiteSpace1 :: Parser ()
|
||||
whiteSpace1 = do space; whiteSpace
|
||||
|
||||
nonspace = satisfy (not . isSpace)
|
||||
|
||||
|
||||
{-| Parse a timelog file. Here is the timelog grammar, from timeclock.el 2.6:
|
||||
|
||||
@
|
||||
@ -483,111 +472,6 @@ ledgerfromtimelog = do
|
||||
|
||||
-- misc parsing
|
||||
|
||||
{-|
|
||||
Parse a date in any of the formats allowed in ledger's period expressions,
|
||||
and maybe some others:
|
||||
|
||||
> 2004
|
||||
> 2004/10
|
||||
> 2004/10/1
|
||||
> 10/1
|
||||
> 21
|
||||
> october, oct
|
||||
> yesterday, today, tomorrow
|
||||
> (not yet) this/next/last week/day/month/quarter/year
|
||||
|
||||
Returns a FuzzyDate, to be converted to a full date later, in the IO
|
||||
layer. Note: assumes any text in the parse stream has been lowercased.
|
||||
-}
|
||||
smartdate :: Parser FuzzyDate
|
||||
smartdate = do
|
||||
let dateparsers = [ymd, ym, md, y, d, month, mon, today', yesterday, tomorrow]
|
||||
(y,m,d) <- choice $ map try dateparsers
|
||||
return $ (y,m,d)
|
||||
|
||||
datesepchar = oneOf "/-."
|
||||
|
||||
ymd :: Parser FuzzyDate
|
||||
ymd = do
|
||||
y <- many1 digit
|
||||
datesepchar
|
||||
m <- many1 digit
|
||||
guard (read m <= 12)
|
||||
datesepchar
|
||||
d <- many1 digit
|
||||
guard (read d <= 31)
|
||||
return (y,m,d)
|
||||
|
||||
ym :: Parser FuzzyDate
|
||||
ym = do
|
||||
y <- many1 digit
|
||||
guard (read y > 12)
|
||||
datesepchar
|
||||
m <- many1 digit
|
||||
guard (read m <= 12)
|
||||
return (y,m,"1")
|
||||
|
||||
y :: Parser FuzzyDate
|
||||
y = do
|
||||
y <- many1 digit
|
||||
guard (read y >= 1000)
|
||||
return (y,"1","1")
|
||||
|
||||
d :: Parser FuzzyDate
|
||||
d = do
|
||||
d <- many1 digit
|
||||
guard (read d <= 31)
|
||||
return ("","",d)
|
||||
|
||||
md :: Parser FuzzyDate
|
||||
md = do
|
||||
m <- many1 digit
|
||||
guard (read m <= 12)
|
||||
datesepchar
|
||||
d <- many1 digit
|
||||
guard (read d <= 31)
|
||||
return ("",m,d)
|
||||
|
||||
months = ["january","february","march","april","may","june",
|
||||
"july","august","september","october","november","december"]
|
||||
|
||||
mons = ["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]
|
||||
|
||||
month :: Parser FuzzyDate
|
||||
month = do
|
||||
m <- choice $ map string months
|
||||
let i = maybe 0 (+1) $ (map toLower m) `elemIndex` months
|
||||
return ("",show i,"1")
|
||||
|
||||
mon :: Parser FuzzyDate
|
||||
mon = do
|
||||
m <- choice $ map string mons
|
||||
let i = maybe 0 (+1) $ (map toLower m) `elemIndex` mons
|
||||
return ("",show i,"1")
|
||||
|
||||
today',yesterday,tomorrow :: Parser FuzzyDate
|
||||
today' = string "today" >> return ("","","today")
|
||||
yesterday = string "yesterday" >> return ("","","yesterday")
|
||||
tomorrow = string "tomorrow" >> return ("","","tomorrow")
|
||||
|
||||
lastthisnextthing :: Parser FuzzyDate
|
||||
lastthisnextthing = do
|
||||
r <- choice [
|
||||
string "last"
|
||||
,string "this"
|
||||
,string "next"
|
||||
]
|
||||
many1 spacenonewline
|
||||
p <- choice [
|
||||
string "day"
|
||||
,string "week"
|
||||
,string "month"
|
||||
,string "quarter"
|
||||
,string "year"
|
||||
]
|
||||
return ("",r,p)
|
||||
|
||||
|
||||
-- | Parse a --display expression which is a simple date predicate, like
|
||||
-- "d>[DATE]" or "d<=[DATE]", and return a transaction-matching predicate.
|
||||
datedisplayexpr :: Parser (Transaction -> Bool)
|
||||
@ -609,3 +493,4 @@ datedisplayexpr = do
|
||||
return matcher
|
||||
|
||||
compareop = choice $ map (try . string) ["<=",">=","==","<","=",">"]
|
||||
|
||||
|
@ -10,6 +10,7 @@ module Ledger.TimeLog
|
||||
where
|
||||
import Ledger.Utils
|
||||
import Ledger.Types
|
||||
import Ledger.Dates
|
||||
import Ledger.Commodity
|
||||
import Ledger.Amount
|
||||
|
||||
|
@ -9,6 +9,7 @@ module Ledger.Transaction
|
||||
where
|
||||
import Ledger.Utils
|
||||
import Ledger.Types
|
||||
import Ledger.Dates
|
||||
import Ledger.Entry
|
||||
import Ledger.RawTransaction
|
||||
import Ledger.Amount
|
||||
|
@ -1,7 +1,8 @@
|
||||
{-|
|
||||
|
||||
All the main data types, defined here to avoid import cycles.
|
||||
See the corresponding modules for documentation.
|
||||
This is the next layer up from Ledger.Utils. All main data types are
|
||||
defined here to avoid import cycles; see the corresponding modules for
|
||||
documentation.
|
||||
|
||||
-}
|
||||
|
||||
@ -11,6 +12,10 @@ import Ledger.Utils
|
||||
import qualified Data.Map as Map
|
||||
|
||||
|
||||
newtype Date = Date UTCTime deriving (Ord, Eq)
|
||||
newtype DateTime = DateTime UTCTime deriving (Ord, Eq)
|
||||
type SmartDate = (String,String,String)
|
||||
|
||||
type AccountName = String
|
||||
|
||||
data Side = L | R deriving (Eq,Show,Ord)
|
||||
|
@ -1,6 +1,7 @@
|
||||
{-|
|
||||
|
||||
Provide a number of standard modules and utilities.
|
||||
Provide a number of standard modules and utilities needed everywhere (or
|
||||
somewhere low in the module tree). The "hledger prelude".
|
||||
|
||||
-}
|
||||
|
||||
@ -20,7 +21,6 @@ module Text.Printf,
|
||||
module Text.Regex,
|
||||
module Text.RegexPR,
|
||||
module Test.HUnit,
|
||||
module Ledger.Dates,
|
||||
)
|
||||
where
|
||||
import Char
|
||||
@ -34,12 +34,10 @@ import Data.Time.Clock
|
||||
import Data.Time.Calendar
|
||||
import Debug.Trace
|
||||
import Test.HUnit
|
||||
-- import Test.QuickCheck hiding (test, Testable)
|
||||
import Text.Printf
|
||||
import Text.Regex
|
||||
import Text.RegexPR
|
||||
import Text.ParserCombinators.Parsec (parse)
|
||||
import Ledger.Dates
|
||||
import Text.ParserCombinators.Parsec
|
||||
|
||||
|
||||
-- strings
|
||||
@ -203,8 +201,20 @@ p = putStr
|
||||
assertequal e a = assertEqual "" e a
|
||||
assertnotequal e a = assertBool "expected inequality, got equality" (e /= a)
|
||||
|
||||
-- parsewith :: Parser a
|
||||
-- parsing
|
||||
|
||||
parsewith :: Parser a -> String -> Either ParseError a
|
||||
parsewith p ts = parse p "" ts
|
||||
|
||||
fromparse :: Either ParseError a -> a
|
||||
fromparse = either (\_ -> error "parse error") id
|
||||
|
||||
nonspace :: Parser Char
|
||||
nonspace = satisfy (not . isSpace)
|
||||
|
||||
spacenonewline :: Parser Char
|
||||
spacenonewline = satisfy (\c -> c `elem` " \v\f\t")
|
||||
|
||||
restofline :: Parser String
|
||||
restofline = anyChar `manyTill` newline
|
||||
|
||||
|
44
Options.hs
44
Options.hs
@ -5,8 +5,9 @@ import System.Console.GetOpt
|
||||
import System.Directory
|
||||
import Text.Printf
|
||||
import Ledger.Parse
|
||||
import Ledger.Dates
|
||||
import Ledger.Utils
|
||||
import Ledger.Types
|
||||
import Ledger.Dates
|
||||
|
||||
|
||||
defaultfile = "~/.ledger"
|
||||
@ -84,51 +85,24 @@ parseArguments = do
|
||||
args <- getArgs
|
||||
let order = if "--options-anywhere" `elem` args then Permute else RequireOrder
|
||||
case (getOpt order options args) of
|
||||
(opts,cmd:args,[]) -> do {opts' <- fixDates opts; return (opts',cmd,args)}
|
||||
(opts,[],[]) -> do {opts' <- fixDates opts; return (opts',[],[])}
|
||||
(opts,cmd:args,[]) -> do {opts' <- fixOptDates opts; return (opts',cmd,args)}
|
||||
(opts,[],[]) -> do {opts' <- fixOptDates opts; return (opts',[],[])}
|
||||
(opts,_,errs) -> ioError (userError (concat errs ++ usage))
|
||||
|
||||
-- | Convert any fuzzy dates within these option values to explicit ones,
|
||||
-- based on today's date.
|
||||
fixDates :: [Opt] -> IO [Opt]
|
||||
fixDates opts = do
|
||||
fixOptDates :: [Opt] -> IO [Opt]
|
||||
fixOptDates opts = do
|
||||
t <- today
|
||||
return $ map (fixopt t) opts
|
||||
where
|
||||
fixopt t (Begin s) = Begin $ fixdatestr t s
|
||||
fixopt t (End s) = End $ fixdatestr t s
|
||||
fixopt t (Begin s) = Begin $ fixSmartDateStr t s
|
||||
fixopt t (End s) = End $ fixSmartDateStr t s
|
||||
fixopt t (Display s) = -- hacky
|
||||
Display $ gsubRegexPRBy "\\[.+?\\]" fixbracketeddatestr s
|
||||
where fixbracketeddatestr s = "[" ++ (fixdatestr t $ init $ tail s) ++ "]"
|
||||
where fixbracketeddatestr s = "[" ++ (fixSmartDateStr t $ init $ tail s) ++ "]"
|
||||
fixopt _ o = o
|
||||
|
||||
-- | Convert a fuzzy date string to an explicit yyyy/mm/dd string using
|
||||
-- the provided date as reference point.
|
||||
fixdatestr :: Date -> String -> String
|
||||
fixdatestr t s = printf "%04d/%02d/%02d" y m d
|
||||
where
|
||||
pdate = fromparse $ parsewith smartdate $ map toLower s
|
||||
(y,m,d) = dateComponents $ fixFuzzyDate t pdate
|
||||
|
||||
-- | Convert a FuzzyDate to an absolute date using the provided date as
|
||||
-- reference point.
|
||||
fixFuzzyDate :: Date -> FuzzyDate -> Date
|
||||
fixFuzzyDate refdate pdate = mkDate $ fromGregorian y m d
|
||||
where
|
||||
(y,m,d) = fix pdate
|
||||
fix :: FuzzyDate -> (Integer,Int,Int)
|
||||
fix ("","","today") = (ry, rm, rd)
|
||||
fix ("","","yesterday") = dateComponents $ lastday refdate
|
||||
fix ("","","tomorrow") = dateComponents $ nextday refdate
|
||||
fix ("","",d) = (ry, rm, read d)
|
||||
fix ("",m,d) = (ry, read m, read d)
|
||||
fix (y,m,d) = (read y, read m, read d)
|
||||
(ry,rm,rd) = dateComponents refdate
|
||||
|
||||
lastday, nextday :: Date -> Date
|
||||
lastday = mkDate . (addDays (-1)) . utctDay . dateToUTC
|
||||
nextday = mkDate . (addDays 1) . utctDay . dateToUTC
|
||||
|
||||
-- | Get the ledger file path from options, an environment variable, or a default
|
||||
ledgerFilePathFromOpts :: [Opt] -> IO String
|
||||
ledgerFilePathFromOpts opts = do
|
||||
|
5
Tests.hs
5
Tests.hs
@ -100,7 +100,7 @@ misc_tests = TestList [
|
||||
"smartparsedate" ~: do
|
||||
t <- today
|
||||
let (ty,tm,td) = dateComponents t
|
||||
let str `gives` datestr = assertequal datestr (fixdatestr t str)
|
||||
let str `gives` datestr = assertequal datestr (fixSmartDateStr t str)
|
||||
"1999-12-02" `gives` "1999/12/02"
|
||||
"1999.12.02" `gives` "1999/12/02"
|
||||
"1999/3/2" `gives` "1999/03/02"
|
||||
@ -112,10 +112,13 @@ misc_tests = TestList [
|
||||
"January" `gives` (printf "%04d/01/01" ty)
|
||||
"feb" `gives` (printf "%04d/02/01" ty)
|
||||
"today" `gives` (printf "%04d/%02d/%02d" ty tm td)
|
||||
-- "this day" `gives` (printf "%04d/%02d/%02d" ty tm td)
|
||||
let (y,m,d) = toGregorian $ addDays (-1) $ fromGregorian ty tm td
|
||||
"yesterday" `gives` (printf "%04d/%02d/%02d" y m d)
|
||||
-- "last day" `gives` (printf "%04d/%02d/%02d" y m d)
|
||||
let (y,m,d) = toGregorian $ addDays 1 $ fromGregorian ty tm td
|
||||
"tomorrow" `gives` (printf "%04d/%02d/%02d" y m d)
|
||||
-- "next day" `gives` (printf "%04d/%02d/%02d" y m d)
|
||||
]
|
||||
|
||||
balancereportacctnames_tests = TestList
|
||||
|
Loading…
Reference in New Issue
Block a user