summaryrefslogtreecommitdiff
path: root/src/Diddo.hs
blob: 2100b257dba6a14dc503ebc83f6d15580e53b5a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
{-# LANGUAGE OverloadedStrings #-}

module Diddo
( LogEntry(LogEntry)
, Diddo(Diddo)
, formatDiddo
, parseDiddoLogline
, logToDiddo
, parseToZonedTime
) where

import Data.Maybe( fromMaybe )
import Data.Time.Clock( UTCTime(), NominalDiffTime(), diffUTCTime )
import Data.Time.Format( FormatTime(), parseTime, formatTime )
import Data.Time.LocalTime( TimeZone(), ZonedTime(..), zonedTimeToUTC, utcToZonedTime )
import Text.Parsec
import System.Locale
import Text.Printf( printf )
import qualified Data.Text as T

data LogEntry = LogEntry
    { timestamp     :: UTCTime
    , timezone      :: TimeZone
    , text          :: T.Text
    }

data Diddo = Diddo
    { startTime     :: ZonedTime
    , endTime       :: ZonedTime
    , comment       :: T.Text
    }

getTimestamp :: Diddo -> UTCTime
getTimestamp = zonedTimeToUTC . endTime

formatDiddo :: String -> Diddo -> T.Text
formatDiddo format (Diddo start end text) = T.intercalate ";" diddoline
    where
        diddoline           = [startZonedString, endZonedString, delta, text]
        startZonedString    = timeToText format start
        endZonedString      = timeToText format end
        startUTC            = zonedTimeToUTC start
        endUTC              = zonedTimeToUTC end
        delta               = diffTimeToHMSString $ diffUTCTime endUTC startUTC

timeToText :: FormatTime a => String -> a -> T.Text
timeToText format = T.pack . formatTime defaultTimeLocale format

logToDiddo :: UTCTime -> LogEntry -> Diddo
logToDiddo startutc logentry = Diddo startZoned endZoned $ text logentry
    where
        startZoned = utcToZonedTime (timezone logentry) startutc
        endZoned = utcToZonedTime (timezone logentry) $ timestamp logentry

-- parseDiddoLogline' :: T.Text -> (UTCTime, LogEntry)
-- parseDiddoLogline' line = (ts, LogEntry ts tz string)

parseDiddoLogline :: T.Text -> (UTCTime, LogEntry)
parseDiddoLogline line = (ts, LogEntry ts tz string)
    where
        (timestring:strings)    = T.splitOn ";" line
        string                  = T.intercalate ";" strings
        time                    = parseISOsecondsTime timestring
        (ts,tz)                 = (zonedTimeToUTC time, zonedTimeZone time)

parseToZonedTime :: String -> String -> ZonedTime
parseToZonedTime format string = zt
    where
        zt = fromMaybe (error $ "Input data broken: " ++ string) parsedTime
        parsedTime = parseTime defaultTimeLocale format string

parseISOsecondsTime :: T.Text -> ZonedTime
parseISOsecondsTime timestring = parseToZonedTime (iso8601DateFormat $ Just "%T%z") $ T.unpack timestring

diffTimeToHMSString :: NominalDiffTime -> T.Text
diffTimeToHMSString delta = T.pack $ printf "%d:%02d:%02d" h m s
    where
        (mLeft, s) = floor delta `divMod` 60 :: (Int, Int)
        (h, m)     = mLeft `divMod` 60