{-# OPTIONS -Wall -Werror #-}

module Main where

import Data.Time

monthBeginning :: TimeZone -> Integer -> Int -> UTCTime
monthBeginning zone year month = localTimeToUTC zone
	(LocalTime (fromGregorian year month 1) midnight)

findTransition :: UTCTime -> UTCTime -> IO [(UTCTime,TimeZone,TimeZone)]
findTransition a b = do
	za <- getTimeZone a
	zb <- getTimeZone b
	if za == zb then return [] else do
		let c = addUTCTime ((diffUTCTime b a) / 2) a
		if a == c then return [(b,za,zb)] else do
			tp <- findTransition a c
			tq <- findTransition c b
			return (tp ++ tq)

showZoneTime :: TimeZone -> UTCTime -> String
showZoneTime zone time = show (utcToZonedTime zone time)

showTransition :: (UTCTime,TimeZone,TimeZone) -> String
showTransition (time,zone1,zone2) = (showZoneTime zone1 time) ++ " => " ++ (showZoneTime zone2 time)

main :: IO ()
main = do
	now <- getCurrentTime
	zone <- getTimeZone now
	let (year,_,_) = toGregorian (localDay (utcToLocalTime zone now))
	putStrLn ("DST adjustments for " ++ show year ++ ":")
	let t0 = monthBeginning zone year 1
	let t1 = monthBeginning zone year 4
	let t2 = monthBeginning zone year 7
	let t3 = monthBeginning zone year 10
	let t4 = monthBeginning zone (year + 1) 1
	tr1 <- findTransition t0 t1
	tr2 <- findTransition t1 t2
	tr3 <- findTransition t2 t3
	tr4 <- findTransition t3 t4
	mapM_ (putStrLn . showTransition) (tr1 ++ tr2 ++ tr3 ++ tr4)
