begin smart date parsing

This commit is contained in:
Simon Michael 2008-11-22 12:18:19 +00:00
parent 60b4610c2f
commit 7362fbd730
5 changed files with 96 additions and 11 deletions

View File

@ -4,16 +4,19 @@ Types for Dates and DateTimes, implemented in terms of UTCTime
-} -}
module Ledger.Dates( module Ledger.Dates
Date, --(
DateTime, -- Date,
mkDate, -- DateTime,
mkDateTime, -- mkDate,
parsedatetime, -- mkDateTime,
parsedate, -- parsedatetime,
datetimeToDate, -- parsedate,
elapsedSeconds -- datetimeToDate,
) where -- elapsedSeconds,
-- today
-- )
where
import Data.Time.Clock import Data.Time.Clock
import Data.Time.Format import Data.Time.Format
@ -64,3 +67,17 @@ datetimeToDate (DateTime (UTCTime{utctDay=day})) = Date (UTCTime day 0)
elapsedSeconds :: Fractional a => DateTime -> DateTime -> a elapsedSeconds :: Fractional a => DateTime -> DateTime -> a
elapsedSeconds (DateTime dt1) (DateTime dt2) = realToFrac $ diffUTCTime dt1 dt2 elapsedSeconds (DateTime dt1) (DateTime dt2) = realToFrac $ diffUTCTime dt1 dt2
today :: IO Date
today = getCurrentTime >>= return . Date
dateToUTC :: Date -> UTCTime
dateToUTC (Date u) = u
dateComponents :: Date -> (Integer,Int,Int)
dateComponents = toGregorian . utctDay . dateToUTC
-- dateDay :: Date -> Day
dateDay date = d where (_,_,d) = dateComponents date
-- dateMonth :: Date -> Day
dateMonth date = m where (_,m,_) = dateComponents date

View File

@ -479,3 +479,61 @@ ledgerfromtimelog = do
tl <- timelog tl <- timelog
return $ ledgerFromTimeLog tl return $ ledgerFromTimeLog tl
-- misc parsing
{-|
Parse a date in any of the formats allowed in ledger's period expressions:
> 2004
> 2004/10
> 2004/10/1
> 10/1
> october
> oct
> this week # or day, month, quarter, year
> next week
> last week
-}
smartdate :: Parser (String,String,String)
smartdate = do
(y,m,d) <- (
try ymd
<|> try ym
<|> try y
-- <|> try md
-- <|> try month
-- <|> try mon
-- <|> try thiswhatever
-- <|> try nextwhatever
-- <|> try lastwhatever
)
return $ (y,m,d)
datesep = oneOf "/-."
ymd :: Parser (String,String,String)
ymd = do
y <- many digit
datesep
m <- many digit
datesep
d <- many digit
return (y,m,d)
ym :: Parser (String,String,String)
ym = do
y <- many digit
datesep
m <- many digit
return (y,m,"1")
y :: Parser (String,String,String)
y = do
y <- many digit
return (y,"1","1")
-- | Parse a flexible date string, with awareness of the current time,
-- | and return a Date or raise an error.
smartparsedate :: String -> Date
smartparsedate s = parsedate $ printf "%04s/%02s/%02s" y m d
where (y,m,d) = fromparse $ parsewith smartdate s

View File

@ -12,6 +12,8 @@ module Data.List,
module Data.Maybe, module Data.Maybe,
module Data.Ord, module Data.Ord,
module Data.Tree, module Data.Tree,
module Data.Time.Clock,
module Data.Time.Calendar,
module Debug.Trace, module Debug.Trace,
module Ledger.Utils, module Ledger.Utils,
module Text.Printf, module Text.Printf,
@ -27,6 +29,8 @@ import Data.List
import Data.Maybe import Data.Maybe
import Data.Ord import Data.Ord
import Data.Tree import Data.Tree
import Data.Time.Clock
import Data.Time.Calendar
import Debug.Trace import Debug.Trace
import Test.HUnit import Test.HUnit
import Test.QuickCheck hiding (test, Testable) import Test.QuickCheck hiding (test, Testable)

3
NOTES
View File

@ -13,8 +13,9 @@ implementations were its consequences." --Niklaus Wirth
*** display mixed amounts vertically, not horizontally *** display mixed amounts vertically, not horizontally
** features ** features
*** flexible date expressions, for easier time reports *** flexible date expressions, for easier time reports
**** use Dates for -b/-e
*** commodity @ rate, for tracking client hours in main ledger *** commodity @ rate, for tracking client hours in main ledger
*** actual/effective entry & txn dates, for ... *** actual/effective entry & txn dates, for ?
*** --display, for reconciling recent transactions with real balance *** --display, for reconciling recent transactions with real balance
*** more ledger features from README *** more ledger features from README
*** new features *** new features

View File

@ -92,6 +92,11 @@ misc_tests = TestList [
, ,
"timeLog" ~: do "timeLog" ~: do
assertparseequal timelog1 (parsewith timelog timelog1_str) assertparseequal timelog1 (parsewith timelog timelog1_str)
,
"smartparsedate" ~: do
assertequal (1999,12,13) (dateComponents $ smartparsedate "1999/12/13")
assertequal (2008,2,1) (dateComponents $ smartparsedate "2008-2")
assertequal (2008,1,1) (dateComponents $ smartparsedate "2008")
] ]
balancereportacctnames_tests = TestList balancereportacctnames_tests = TestList