pathikrit
pathikrit

Reputation: 33489

Haskell - How to extract TimeOfDay and DayOfWeek from ZonedTime

I am looking at the time module and I want something like this:

import Data.Time.LocalTime

timeOfDayAndDayOfWeek :: ZonedTime -> (TimeOfDay, DayOfWeek)

How do I do that?

Upvotes: 0

Views: 883

Answers (2)

Chris Stryczynski
Chris Stryczynski

Reputation: 34061

You can go from ZonedTime to LocalTime to Day.

With Day you can use https://hackage.haskell.org/package/time-1.9.3/docs/Data-Time-Calendar.html#t:DayOfWeek to get a DayOfWeek enum.

And use localTimeOfDay to go from LocalTime to TimeOfDay.

Upvotes: 1

Davislor
Davislor

Reputation: 15164

Does this work for you?

import Data.Time.LocalTime
  (ZonedTime, TimeOfDay, getZonedTime, localDay, localTimeOfDay,
   zonedTimeToLocalTime)
import Data.Time.Calendar.WeekDate (toWeekDate)

-- toWeekDate numbers the days 1 for Monday to 7 for Sunday.
data DayOfWeek = Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday
  deriving (Eq, Read, Show)

instance Enum DayOfWeek where
  toEnum 0 = Sunday
  toEnum 1 = Monday
  toEnum 2 = Tuesday
  toEnum 3 = Wednesday
  toEnum 4 = Thursday
  toEnum 5 = Friday
  toEnum 6 = Saturday
  toEnum 7 = Sunday -- Yes, twice.
  toEnum n = toEnum (n `mod` 7)

  fromEnum Monday = 1
  fromEnum Tuesday = 2
  fromEnum Wednesday = 3
  fromEnum Thursday = 4
  fromEnum Friday = 5
  fromEnum Saturday = 6
  fromEnum Sunday = 7

timeOfDayAndDayOfWeek :: ZonedTime -> (TimeOfDay, DayOfWeek)
timeOfDayAndDayOfWeek zt = let
    lt = zonedTimeToLocalTime zt
    day = localDay lt
    (_, _, weekDayNumber) = toWeekDate day
    dow = toEnum weekDayNumber
    tod = localTimeOfDay lt
  in
    (tod, dow)

main :: IO ()
main = do
  zt <- getZonedTime
  let (tod, dow) = timeOfDayAndDayOfWeek zt
  print tod
  print dow

You might prefer this version with a wrapper function instead of boilerplate, suggested by 4castle. (Especially if you’d have to use more than one mapping from integers to the Enum.)

import Data.Time.LocalTime
  (ZonedTime, TimeOfDay, getZonedTime, localDay, localTimeOfDay,
   zonedTimeToLocalTime)
import Data.Time.Calendar.WeekDate (toWeekDate)

data DayOfWeek = Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday
  deriving (Enum, Eq, Read, Show)

-- toWeekDate numbers the days 1 for Monday to 7 for Sunday.
weekDateToDayOfWeek :: (Integer, Int, Int) -> DayOfWeek
weekDateToDayOfWeek (_, _, d) = toEnum (d-1)

timeOfDayAndDayOfWeek :: ZonedTime -> (TimeOfDay, DayOfWeek)
timeOfDayAndDayOfWeek zt = let
    lt = zonedTimeToLocalTime zt
    dow = (weekDateToDayOfWeek . toWeekDate . localDay) lt
    tod = localTimeOfDay lt
  in
    (tod, dow)

main :: IO ()
main = do
  zt <- getZonedTime
  let (tod, dow) = timeOfDayAndDayOfWeek zt
  print tod
  print dow

Upvotes: 1

Related Questions