@@ -32,6 +32,9 @@ module Data.Time.LocalTime.TimeZone.Olson.Render
3232where
3333
3434import Data.Time.LocalTime.TimeZone.Olson.Types
35+import Data.Time.LocalTime.TimeZone.Series (TimeZoneSeries(TimeZoneSeries))
36+import Data.Time (TimeZone(TimeZone, timeZoneSummerOnly, timeZoneName))
37+import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds)
3538import Data.Binary.Put (Put, runPut, putByteString, putWord8, flush,
3639 putWord32be, putWord64be)
3740import qualified Data.ByteString as B
@@ -39,10 +42,37 @@ import qualified Data.ByteString.Lazy as L
3942import Data.List (partition, sortBy, sort, group)
4043import Data.Ord (comparing)
4144import Data.Word (Word8)
42−import Data.Maybe (listToMaybe, maybeToList, isNothing, fromMaybe)
45+import Data.Maybe (listToMaybe, maybeToList, isNothing, fromMaybe, catMaybes)
4346import Data.Monoid (mempty)
4447import Control.Monad (guard, replicateM_)
4548
49+-- | Render a @TimeZoneSeries@ as a binary Olson timezone file.
50+renderTimeZoneSeriesToOlsonFile :: FilePath -> TimeZoneSeries -> IO ()
51+renderTimeZoneSeriesToOlsonFile fp = renderOlsonToFile fp .
52+ fromMaybe (error "Cannot render TimeZoneSeries: default is summer time") .
53+ timeZoneSeriesToOlson
54+
55+-- | Convert a @TimeZoneSeries@ to @OlsonData@ for rendering.
56+timeZoneSeriesToOlson :: TimeZoneSeries -> Maybe OlsonData
57+timeZoneSeriesToOlson (TimeZoneSeries dflt pairs)
58+ | timeZoneSummerOnly dflt && not (all timeZoneSummerOnly $ map snd pairs)
59+ = Nothing
60+ | otherwise = Just $
61+ OlsonData
62+ [Transition secs ttinfo |
63+ (t, tzs) <- pairs,
64+ let secs = round $ utcTimeToPOSIXSeconds t,
65+ ttinfo <- maybeToList $ lookup (mkTT tzs) ttAssocs]
66+ ttinfos
67+ []
68+ Nothing
69+ where
70+ mkTT (TimeZone offset issdst abbr) =
71+ TtInfo (offset*60) issdst Wall abbr
72+ dfltTT = mkTT dflt
73+ ttAssocs = (dfltTT, 0) :
74+ zip (filter (/= dfltTT) $ map (mkTT . snd) pairs) [1..]
75+ ttinfos = map fst ttAssocs
4676
4777-- | Render Olson timezone data as a binary Olson timezone file
4878renderOlsonToFile :: FilePath -> OlsonData -> IO ()