#!/usr/bin/env stack
>
> module ParseTime (
> count_down_time,
> subtract_second,
> asTimePeriod
> )
> where
>
> data TimePeriod = TimePeriod Integer Integer deriving (ReadPrec [TimePeriod]
ReadPrec TimePeriod
Int -> ReadS TimePeriod
ReadS [TimePeriod]
(Int -> ReadS TimePeriod)
-> ReadS [TimePeriod]
-> ReadPrec TimePeriod
-> ReadPrec [TimePeriod]
-> Read TimePeriod
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [TimePeriod]
$creadListPrec :: ReadPrec [TimePeriod]
readPrec :: ReadPrec TimePeriod
$creadPrec :: ReadPrec TimePeriod
readList :: ReadS [TimePeriod]
$creadList :: ReadS [TimePeriod]
readsPrec :: Int -> ReadS TimePeriod
$creadsPrec :: Int -> ReadS TimePeriod
Read)
>
> split :: (Char -> Bool) -> String -> [String]
> split :: (Char -> Bool) -> String -> [String]
split Char -> Bool
p String
s = case (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
p String
s of
> String
"" -> []
> String
s' -> String
w String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Char -> Bool) -> String -> [String]
split Char -> Bool
p String
s''
> where (String
w, String
s'') = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break Char -> Bool
p String
s'
>
>
>
>
>
> split_by_colon :: String -> [String]
> split_by_colon :: String -> [String]
split_by_colon String
timeString = (Char -> Bool) -> String -> [String]
split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
':') String
timeString
>
>
>
> many_to_int :: [String] -> [Integer]
> many_to_int :: [String] -> [Integer]
many_to_int [] = []
> many_to_int (String
x:[String]
xs) = (String -> Integer
forall a. Read a => String -> a
read (String -> Integer) -> String -> Integer
forall a b. (a -> b) -> a -> b
$ String
x :: Integer)Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
:([String] -> [Integer]
many_to_int [String]
xs)
>
>
>
> list_to_time_periods :: [Integer] -> [TimePeriod]
> list_to_time_periods :: [Integer] -> [TimePeriod]
list_to_time_periods [Integer
m,Integer
s] = [Integer -> Integer -> TimePeriod
TimePeriod Integer
m Integer
s]
> list_to_time_periods [Integer]
_ = []
>
>
>
> subtract_second :: TimePeriod -> TimePeriod
> subtract_second :: TimePeriod -> TimePeriod
subtract_second (TimePeriod Integer
0 Integer
0) = Integer -> Integer -> TimePeriod
TimePeriod Integer
0 Integer
0
> subtract_second (TimePeriod Integer
0 Integer
s) = Integer -> Integer -> TimePeriod
TimePeriod Integer
0 (Integer
sInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
> subtract_second (TimePeriod Integer
m Integer
0) = Integer -> Integer -> TimePeriod
TimePeriod (Integer
mInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) Integer
59
> subtract_second (TimePeriod Integer
m Integer
s) = Integer -> Integer -> TimePeriod
TimePeriod Integer
m (Integer
sInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
>
>
>
> asTimePeriod :: String -> TimePeriod
> asTimePeriod :: String -> TimePeriod
asTimePeriod String
s = [TimePeriod] -> TimePeriod
forall a. [a] -> a
head ([TimePeriod] -> TimePeriod) -> [TimePeriod] -> TimePeriod
forall a b. (a -> b) -> a -> b
$ [Integer] -> [TimePeriod]
list_to_time_periods ([Integer] -> [TimePeriod]) -> [Integer] -> [TimePeriod]
forall a b. (a -> b) -> a -> b
$ [String] -> [Integer]
many_to_int ([String] -> [Integer]) -> [String] -> [Integer]
forall a b. (a -> b) -> a -> b
$ String -> [String]
split_by_colon String
s
>
>
>
>
>
> count_down_time :: String -> String
> count_down_time :: String -> String
count_down_time = TimePeriod -> String
forall a. Show a => a -> String
show (TimePeriod -> String)
-> (String -> TimePeriod) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimePeriod -> TimePeriod
subtract_second (TimePeriod -> TimePeriod)
-> (String -> TimePeriod) -> String -> TimePeriod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> TimePeriod
asTimePeriod
>
>
>
> show_two_digits :: Integer -> String
> show_two_digits :: Integer -> String
show_two_digits Integer
x
> | Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
10 = String
"0" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
x
> | Bool
otherwise = Integer -> String
forall a. Show a => a -> String
show Integer
x
>
>
>
> instance Show TimePeriod where
> show :: TimePeriod -> String
show (TimePeriod Integer
m Integer
s) = Integer -> String
show_two_digits Integer
m String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
show_two_digits Integer
s
Related materials:
1. Generic time processing example: https://stackoverflow.com/a/14006938