@@ -55,6 +55,9 @@ import Data.Time.Compat (Day, FormatTime, LocalTime,
5555 secondsToNominalDiffTime)
5656import Data.Time.Format.Compat (defaultTimeLocale,
5757 iso8601DateFormat)
58+import Data.Time.Calendar.Month.Compat (Month)
59+import Data.Time.Calendar.Quarter.Compat (Quarter, QuarterOfYear (..),
60+ toYearQuarter)
5861import Data.Typeable (Typeable)
5962import qualified Data.UUID.Types as UUID
6063import Data.Version (Version, parseVersion,
@@ -516,6 +519,42 @@ instance ToHttpApiData DayOfWeek where
516519
517520 toEncodedUrlPiece = unsafeToEncodedUrlPiece
518521
522+-- |
523+-- >>> toUrlPiece Q4
524+-- "q4"
525+instance ToHttpApiData QuarterOfYear where
526+ toUrlPiece Q1 = "q1"
527+ toUrlPiece Q2 = "q2"
528+ toUrlPiece Q3 = "q3"
529+ toUrlPiece Q4 = "q4"
530+
531+-- |
532+-- >>> import Data.Time.Calendar.Quarter.Compat (Quarter (..))
533+-- >>> MkQuarter 8040
534+-- 2010-Q1
535+--
536+-- >>> toUrlPiece $ MkQuarter 8040
537+-- "2010-q1"
538+--
539+instance ToHttpApiData Quarter where
540+ toUrlPiece q = case toYearQuarter q of
541+ (y, qoy) -> T.pack (show y ++ "-" ++ f qoy)
542+ where
543+ f Q1 = "q1"
544+ f Q2 = "q2"
545+ f Q3 = "q3"
546+ f Q4 = "q4"
547+
548+-- |
549+-- >>> import Data.Time.Calendar.Month.Compat (Month (..))
550+-- >>> MkMonth 24482
551+-- 2040-03
552+--
553+-- >>> toUrlPiece $ MkMonth 24482
554+-- "2040-03"
555+--
556+instance ToHttpApiData Month where
557+ toUrlPiece = T.pack . formatTime defaultTimeLocale "%Y-%m"
519558
520559instance ToHttpApiData NominalDiffTime where
521560 toUrlPiece = toUrlPiece . nominalDiffTimeToSeconds
@@ -704,6 +743,9 @@ instance FromHttpApiData ZonedTime where parseUrlPiece = runAtto Atto.zonedTime
704743-- Right 2015-10-03 00:14:24 UTC
705744instance FromHttpApiData UTCTime where parseUrlPiece = runAtto Atto.utcTime
706745
746+-- |
747+-- >>> parseUrlPiece "Monday" :: Either Text DayOfWeek
748+-- Right Monday
707749instance FromHttpApiData DayOfWeek where
708750 parseUrlPiece t = case Map.lookup (T.toLower t) m of
709751 Just dow -> Right dow
@@ -715,6 +757,30 @@ instance FromHttpApiData DayOfWeek where
715757
716758instance FromHttpApiData NominalDiffTime where parseUrlPiece = fmap secondsToNominalDiffTime . parseUrlPiece
717759
760+-- |
761+-- >>> parseUrlPiece "2021-01" :: Either Text Month
762+-- Right 2021-01
763+instance FromHttpApiData Month where parseUrlPiece = runAtto Atto.month
764+
765+-- |
766+-- >>> parseUrlPiece "2021-q1" :: Either Text Quarter
767+-- Right 2021-Q1
768+instance FromHttpApiData Quarter where parseUrlPiece = runAtto Atto.quarter
769+
770+-- |
771+-- >>> parseUrlPiece "q2" :: Either Text QuarterOfYear
772+-- Right Q2
773+--
774+-- >>> parseUrlPiece "Q3" :: Either Text QuarterOfYear
775+-- Right Q3
776+instance FromHttpApiData QuarterOfYear where
777+ parseUrlPiece t = case T.toLower t of
778+ "q1" -> return Q1
779+ "q2" -> return Q2
780+ "q3" -> return Q3
781+ "q4" -> return Q4
782+ _ -> Left "Invalid quarter of year"
783+
718784instance FromHttpApiData All where parseUrlPiece = coerce (parseUrlPiece :: Text -> Either Text Bool)
719785instance FromHttpApiData Any where parseUrlPiece = coerce (parseUrlPiece :: Text -> Either Text Bool)
720786