-- English ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ module FuzzyTime.English (showFuzzyTimeEn) where import {-# SOURCE #-} FuzzyTime import Data.Char (toLower, toUpper) import Data.List (intersperse) import Prelude hiding (min) -- showFuzzyTimeEn ---------------------------------------------------------------------------------------------------------------------------------------------------------------- showFuzzyTimeEn :: FuzzyTime -> String -- FuzzyClock showFuzzyTimeEn fc@(FuzzyClock _ caps clock hour _ min style) | min == 0 = capsize $ if getHour hour `elem` ["midnight", "noon"] then getHour hour else getHour hour ++ " o’clock" | min <= 30 = capsize $ getMin min ++ " past " ++ getHour hour | min > 30 = capsize $ getMin (60-min) ++ " to " ++ getHour (nextFTHour fc) | otherwise = "Oops, looks like it's " ++ show hour ++ ":" ++ show min ++ "." where capsize :: String -> String capsize s | caps == 0 = map toLower s | caps == 1 = concat . intersperse " " $ map (\w -> if w `elem` ["o’clock","past","to"] then w else toUpper (head w) : tail w) (words s) | caps == 2 = concat . intersperse " " $ map (\w -> toUpper (head w) : tail w) (words s) | caps == 3 = map toUpper s | otherwise = "Oops, looks like caps = " ++ show caps ++ "." getHour :: Int -> String getHour h | h `elem` [0, 24] = if style==1 then numeralEn clock else "midnight" | h == 12 = if style==1 then numeralEn 12 else "noon" | otherwise = numeralEn h getMin :: Int -> String getMin m | m == 30 = "half" | m `elem` [15, 45] = "quarter" | otherwise = numeralEn m -- FuzzyTimer showFuzzyTimeEn (FuzzyTimer _ mins) | mins > 0 = "in " ++ showHelper | mins == 0 = "now!" | mins < 0 = "! " ++ showHelper ++ " ago !" where showHelper :: String showHelper | mm > 90 = numeralEn hours ++ (if half then " and a half" else "") ++ " hours" | mm == 90 = "an hour and a half" | mm == 75 = "an hour and a quarter" | mm == 60 = "an hour" | mm == 45 = "three quarters" | mm == 30 = "half an hour" | mm == 15 = "a quarter" | mm > 1 = numeralEn mm ++ " minutes" | mm == 1 = "a minute" | otherwise = "Oops, it looks like there's " ++ show mins ++ " left." hours :: Int hours = round $ (fromIntegral mm :: Float) / 60 mm :: Int mm = abs mins half :: Bool half = mm `mod` 60 == 30 -- numeralEn ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- numeralEn :: Int -> String numeralEn n | n < 20 = numeralEnHelper1 n | n `mod` 10 == 0 = numeralEnHelper10 (n `div` 10) | otherwise = numeralEnHelper10 (n `div` 10) ++ "-" ++ numeralEnHelper1 (n `mod` 10) where numeralEnHelper1 :: Int -> String numeralEnHelper1 i = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"] !! (i-1) numeralEnHelper10 :: Int -> String numeralEnHelper10 i = ["twenty", "thirty", "forty", "fifty"] !! (i-2)