module Data.Icao.Time
(
Hhmm(hour, minute)
, DayTime(dayOfMonth, time)
, Date(year, month, day)
, hhmmParser
, dateParser
, dayTimeParser
, parseHhmm
, parseDate
, parseDayTime
, mkHhmm
, mkDate
, mkDayTime
) where
import Control.Monad.Fail
import Prelude hiding (fail)
import Data.Aeromess.Parser
import Data.Either ()
data Hhmm = Hhmm
{ hour :: Int
, minute :: Int
} deriving (Eq, Show)
data Date = Date
{ year :: Int
, month :: Int
, day :: Int
} deriving (Eq, Show)
data DayTime = DayTime
{ dayOfMonth :: Int
, time :: Hhmm
} deriving (Eq, Show)
hhmmParser :: Parser Hhmm
hhmmParser = do
hh <- natural 2
mm <- natural 2
mkHhmm hh mm
dateParser :: Parser Date
dateParser = do
yy <- natural 2
mm <- natural 2
dd <- natural 2
mkDate yy mm dd
dayTimeParser :: Parser DayTime
dayTimeParser = do
dd <- natural 2
hhmm <- hhmmParser
mkDayTime dd (hour hhmm) (minute hhmm)
parseHhmm :: String -> Either Error Hhmm
parseHhmm = runParser hhmmParser
parseDate :: String -> Either Error Date
parseDate = runParser dateParser
parseDayTime :: String -> Either Error DayTime
parseDayTime = runParser dayTimeParser
mkHhmm
:: (MonadFail m)
=> Int -> Int -> m Hhmm
mkHhmm hh mm
| hh < 0 || hh > 23 = fail ("invalid hour=" ++ show hh)
| mm < 0 || mm > 59 = fail ("invalid minute=" ++ show mm)
| otherwise = return (Hhmm hh mm)
mkDate
:: (MonadFail m)
=> Int -> Int -> Int -> m Date
mkDate yy mm dd
| yy < 0 || yy > 99 = fail ("invalid year=" ++ show yy)
| mm < 1 || mm > 12 = fail ("invalid month=" ++ show mm)
| dd < 1 || dd > 31 = fail ("invalid day=" ++ show dd)
| otherwise = return (Date yy mm dd)
mkDayTime
:: (MonadFail m)
=> Int -> Int -> Int -> m DayTime
mkDayTime dd hh mm
| dd < 1 || dd > 31 = fail ("invalid day=" ++ show dd)
| otherwise = fmap (DayTime dd) (mkHhmm hh mm)