Simpler way to deal with Time and Date?
haskell
Solution
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`
- If by "week", you meant "week of the year", you may want to consult the documentation for `toWeekDate` to see exactly how that's defined.
- If you want months or days in string format, you can use the functions in `Data.Time.Format` (still in the `time` package) to format them in the current (or some other) locale.
Problem
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: - Year - Month - Week - Date (Eg: 24) - Day (Eg: Monday) - Hour - Minutes - Seconds 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 ```