So I am trying to learn Haskell, so I am sorry if this has already been asked, but I could not find a question that properly answered my doubts.
So my question is given UTCTime
what is the easiest and straightforward way of getting the following:
Also if there is convenient way of converting UTCTime
to some local time using just Asia/Tokyo
or similar strings.
I couldn't find a single library that gave all of these features and got confused and to be quite honest irritated that I need to convert between different types and use multiple libraries to achieve the above. Maybe I was not looking properly.
My effort so far:
import Data.Time
-- Difference between JST and UTC in seconds
-- JST is 9 hours ahead of UTC
utcJSTDiff :: Int
utcJSTDiff = 32400
getHour :: UTCTime -> Int
getHour time = todHour (timeToTimeOfDay (utctDayTime time))
getMinutes :: UTCTime -> Int
getMinutes time = todMin (timeToTimeOfDay (utctDayTime time))
isReminderHour :: Int -> Bool
isReminderHour hour
| hour == morningReminderHour || hour == eveningReminderHour = True
| otherwise = False
isReminderMins :: Int -> Bool
isReminderMins mins
| mins <= reminderMinuteLimit = True
| otherwise = False
timeforReminder :: UTCTime -> Bool
timeforReminder time
| isReminderHour (getHour time) && isReminderMins (getMinutes time) = True
| otherwise = False
utcToJST :: UTCTime -> UTCTime
utcToJST = addUTCTime (realToFrac utcJSTDiff)
main :: IO()
main = do
currentTime <- getCurrentTime
let jstTime = utcToJST currentTime
if timeforReminder jstTime
then action1
else action2
Edit: Fixed to use timezone-olson
/ timezone-series
for correct timezone processing.
You should be able to do almost everything with the time
package, except that proper timezone processing will require timezone-olson
and timezone-series
packages on Linux systems; I'm not sure how to do it on Windows systems. Maybe someone else has a better way.
Here's the code:
module Time where
import Data.Time -- package "time"
import Data.Time.Calendar.WeekDate -- package "time"
import Data.Time.LocalTime.TimeZone.Olson -- package "timezone-olson"
import Data.Time.LocalTime.TimeZone.Series -- package "timezone-series"
-- |POSIX-specific timezone lookup
lookupTimeZone :: String -> IO TimeZoneSeries
lookupTimeZone tz =
getTimeZoneSeriesFromOlsonFile ("/usr/share/zoneinfo/" ++ tz)
data MyTime = MyTime
{ year :: Integer
, month :: Int
, week :: Int
, dayOfMonth :: Int
, dayOfWeek :: Int
, hour :: Int
, minutes :: Int
, seconds :: Int
} deriving (Show)
getMyTime :: TimeZoneSeries -> UTCTime -> MyTime
getMyTime tz t =
let LocalTime day (TimeOfDay hh mm ss) = utcToLocalTime' tz t
(yr, mn, dom) = toGregorian day
(_, wk, dow) = toWeekDate day
in MyTime yr mn wk dom dow hh mm (round ss)
main :: IO ()
main = do
currentTime <- getCurrentTime
-- Note: if you want time in local timezone, use:
-- tz <- getTimeZoneSeriesFromOlsonFile "/etc/localtime"
tz <- lookupTimeZone "Asia/Tokyo"
print $ getMyTime tz currentTime
A few cautionary notes:
lookupTimeZone
will throw an exception if it can't find the timezone file at /usr/share/zoneinfo/your/timezone
toWeekDate
to see exactly how that's defined.Data.Time.Format
(still in the time
package) to format them in the current (or some other) locale.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With