I\'ve been working with Haskell\'s Date.Time modules to parse a date like 12-4-1999 or 1-31-1999. I tried:
parseDay :: String -&g
Here is some old code that contains two types of homemade dates, dates with just YMD, no time or timezones, etc.
It shows how to parse strings into dates using readDec. See the parseDate function. With readDec, read the number, it doesn't matter about leading spaces(because of filter) or leading zeros,and the parse stops at the first non-digit. Then used tail (to skip the non digit) to get to the next numerical field of the date.
It shows several ways of formatting for output, but the most flexible way is to use Text.printf. See instance Show LtDate. With printf, anything is possible!
import Char
import Numeric
import Data.Time.Calendar
import Data.Time.Clock
import Text.Printf
-- ================================================================
-- LtDate
-- ================================================================
type Date=(Int,Int,Int)
data LtDate = LtDate
{ ltYear :: Int,
ltMonth:: Int,
ltDay :: Int
}
instance Show LtDate
where show d = printf "%4d-%02d-%02d" (ltYear d) (ltMonth d) (ltDay d)
toLtDate :: Date -> LtDate
toLtDate (y,m,d)= LtDate y m d
-- =============================================================
-- Date
-- =============================================================
-- | Parse a String mm/dd/yy into tuple (y,m,d)
-- accepted formats
--
-- @
-- 12\/01\/2004
-- 12\/ 1\' 4
-- 12-01-99
-- @
parseDate :: String -> Date
parseDate s = (y,m,d)
where [(m,rest) ] = readDec (filter (not . isSpace) s)
[(d,rest1)] = readDec (tail rest)
[(y, _) ] = parseDate' rest1
-- | parse the various year formats used by Quicken dates
parseDate':: String -> [(Int,String)]
parseDate' (y:ys) =
let [(iy,rest)] = readDec ys
year=case y of '\'' -> iy + 2000
_ ->
if iy < 1900 then iy + 1900 else iy
in [(year,rest)]
-- | Note some functions sort by this format
-- | So be careful when changing it.
showDate::(Int, Int, Int) -> String
showDate (y,m,d)= yy ++ '-':mm ++ '-':dd
where dd=zpad (show d)
mm = zpad (show m)
yy = show y
zpad ds@(_:ds')
| ds'==[] = '0':ds
| otherwise = ds
-- | from LtDate to Date
fromLtDate :: LtDate -> Date
fromLtDate lt = (ltYear lt, ltMonth lt, ltDay lt)
Once you have (Y,M,D), it's easy to convert to a Haskell library type for data manipulations. Once you are done with the HS libraries, Text.printf can be used to format a date for display.