@@ -0,0 +1,207 @@
14+ , module Data.Time.LocalTime.Short
27+ , module Data.Time.Utils
30+import Control.DeepSeq
33+import Control.Monad.Fail
36+import Data.Function (on)
37+import qualified Data.Text as T
39+import Data.Time.LocalTime.Short
40+import Data.Time.Utils
41+import GHC.Generics (Generic)
42+import Test.QuickCheck
43+import Test.QuickCheck.Arbitrary.Generic
47+ = Minutes { unMinutes :: Int
48+ } deriving (Show, Eq, Ord, Arbitrary, Generic, FromJSON, ToJSON)
50+instance NFData Minutes
55+ = Hours { unHours :: Int
56+ } deriving (Show, Eq, Ord, Arbitrary, Generic, FromJSON, ToJSON)
62+duration :: ShortZonedTime -> ShortZonedTime -> Minutes
63+duration t1 t2 = Minutes (timeDiff `div` 60)
65+ calcDiff = diffUTCTime `on` zonedTimeToUTC . unShortZonedTime
66+ timeDiff = round (calcDiff t1 t2)
68+durationLocal :: LocalTime -> LocalTime -> Minutes
69+durationLocal t1 t2 = Minutes (timeDiff `div` 60)
71+ calcDiff = diffUTCTime `on` localTimeToUTC utc
72+ timeDiff = round (calcDiff t1 t2)
74+minutesToNDF :: Minutes -> NominalDiffTime
75+minutesToNDF (Minutes mins) = 60 * realToFrac mins
77+-- UTCTime with lexically correct show instance.
78+-- Motivation: using ppShow.
79+newtype UTCTime' = UTCTime' { unUTCTime' :: UTCTime }
80+ deriving (Eq, Ord, Generic, Binary, NFData)
84+instance Show UTCTime' where
87+ . formatTime defaultTimeLocale (iso8601DateFormat Nothing)
90+instance Arbitrary UTCTime' where
91+ arbitrary = UTCTime' <$> do
93+ <$> (ModifiedJulianDay <$> choose (55000, 58000))
96+-- TODO: do not store the time, only the date
100+ } deriving (Eq, Ord)
104+instance NFData UTCDate where
105+ rnf (UTCDate d) = d `seq` () -- NOTE: not very good
107+instance Binary UTCDate where
108+ put (UTCDate t) = put d
110+ UTCTime (ModifiedJulianDay d) _ = t
113+ return $ UTCDate (UTCTime (ModifiedJulianDay d) 0)
115+instance Show UTCDate where
116+-- I hope no code was depending on this instance!
117+-- show = formatTime defaultTimeLocale "%d-%B-%y" . utcTime
120+ . formatTime defaultTimeLocale "%d-%B-%y"
123+instance ToJSON UTCDate where
124+ toJSON (UTCDate t) = String $ T.pack iso8601
125+ where iso8601 = formatTime defaultTimeLocale (iso8601DateFormat Nothing) t
127+instance FromJSON UTCDate where
128+ parseJSON (String s) = return $ UTCDate date
130+ date = parseTimeOrError True defaultTimeLocale format string
131+ format = iso8601DateFormat Nothing
135+instance Arbitrary UTCDate where
137+ dayNum <- choose (55000, 58000)
138+ return(UTCDate $ UTCTime (ModifiedJulianDay dayNum) (secondsToDiffTime 0))
140+toApiDate :: UTCDate -> T.Text
141+toApiDate (UTCDate t) = T.pack iso8601
143+ iso8601 = formatTime defaultTimeLocale (iso8601DateFormat Nothing) t
145+fromApiDate :: (MonadFail m) => T.Text -> m UTCDate
146+fromApiDate t = UTCDate <$> parseTimeM
149+ (iso8601DateFormat Nothing)
152+apiDate :: Prism' T.Text UTCDate
153+apiDate = prism' toApiDate fromApiDate
155+mskTimeZone :: TimeZone
156+mskTimeZone = TimeZone (3 * 60) False "MSK"
158+toAPITimeMSK :: UTCTime -> ShortZonedTime
159+toAPITimeMSK = shortZonedTime . utcToZonedTime mskTimeZone
164+ deriving (Eq, Show, Generic)
166+instance Binary TimeFrameType
168+instance Arbitrary TimeFrameType where
169+ arbitrary = genericArbitrary
170+ shrink = genericShrink
172+data TimeFrame = TimeFrame
173+ { _tfFrom :: !TimeOfDay
174+ , _tfTo :: !TimeOfDay
175+ , _tfType :: !TimeFrameType
177+ deriving (Eq, Show, Generic)
179+makeLenses ''TimeFrame
181+instance Binary TimeFrame
183+instance Arbitrary TimeFrame where
184+ arbitrary = genericArbitrary
185+ shrink = genericShrink
187+mkTimeFrame :: TimeOfDay -> TimeOfDay -> TimeFrameType -> Maybe TimeFrame
188+mkTimeFrame fromTof toTof tft = if toTof >= fromTof
189+ then Just $ TimeFrame fromTof toTof tft
192+data DateRange = DateRange
193+ { _drFromDate :: Day
195+ } deriving (Eq, Show, Read, Generic)
197+makeLenses ''DateRange
199+mkDateRange :: Day -> Day -> DateRange
200+mkDateRange a b | b < a = DateRange b a
201+mkDateRange a b = DateRange a b
203+instance Arbitrary DateRange where
204+ arbitrary = mkDateRange <$> arbitrary <*> arbitrary
205+ shrink = genericShrink
207+instance Binary DateRange