Convertible UTCTime <=> W3CDateTime
authorPHO <pho@cielonegro.org>
Thu, 11 Mar 2010 05:50:42 +0000 (14:50 +0900)
committerPHO <pho@cielonegro.org>
Thu, 11 Mar 2010 05:50:42 +0000 (14:50 +0900)
Data/Time/W3CDateTime.hs

index a0de70ee8d554b19a22eff6f2d83e4772d4bedbf..550547456ae42cf0743b6f0185ba664a9a3b24f7 100644 (file)
@@ -23,33 +23,60 @@ data W3CDateTime
       }
     deriving (Show, Eq, Typeable)
 
-empty :: W3CDateTime
-empty = W3CDateTime {
-          w3cYear     = 0
-        , w3cMonth    = Nothing
-        , w3cDay      = Nothing
-        , w3cHour     = Nothing
-        , w3cMinute   = Nothing
-        , w3cSecond   = Nothing
-        , w3cTimeZone = Nothing
-        }
-
 instance Convertible Day W3CDateTime where
     safeConvert day
         = case toGregorian day of
-            (y, m, d) -> return empty {
-                           w3cYear  = y
-                         , w3cMonth = Just m
-                         , w3cDay   = Just d
-                         }
+            (y, m, d) -> return W3CDateTime {
+                                       w3cYear     = y
+                                     , w3cMonth    = Just m
+                                     , w3cDay      = Just d
+                                     , w3cHour     = Nothing
+                                     , w3cMinute   = Nothing
+                                     , w3cSecond   = Nothing
+                                     , w3cTimeZone = Nothing
+                                     }
+
+fetch :: (Show a, Typeable a, Typeable b) =>
+         String
+      -> (a -> Maybe b)
+      -> a
+      -> ConvertResult b
+fetch name f a
+    = case f a of
+        Nothing -> convError ("No " ++ name ++ " information in the given value") a
+        Just b  -> return b
 
 instance Convertible W3CDateTime Day where
     safeConvert w3c
         = do let y = w3cYear w3c
-             m <- case w3cMonth w3c of
-                    Just m  -> return m
-                    Nothing -> convError "No month info" w3c
-             d <- case w3cDay w3c of
-                    Just d  -> return d
-                    Nothing -> convError "No day info" w3c
-             return $ fromGregorian y m d
\ No newline at end of file
+             m <- fetch "month" w3cMonth w3c
+             d <- fetch "day"   w3cDay   w3c
+             return (fromGregorian y m d)
+
+instance Convertible UTCTime W3CDateTime where
+    safeConvert u
+        = let (y, m, d) = toGregorian (utctDay u)
+              hms       = timeToTimeOfDay (utctDayTime u)
+          in
+            return W3CDateTime {
+                         w3cYear     = y
+                       , w3cMonth    = Just m
+                       , w3cDay      = Just d
+                       , w3cHour     = Just (todHour hms)
+                       , w3cMinute   = Just (todMin  hms)
+                       , w3cSecond   = Just (todSec  hms)
+                       , w3cTimeZone = Just utc
+                       }
+
+instance Convertible W3CDateTime UTCTime where
+    safeConvert w3c
+        = do day <- safeConvert w3c
+             tod <- do h   <- fetch "hour"   w3cHour   w3c
+                       m   <- fetch "minute" w3cMinute w3c
+                       s   <- fetch "second" w3cSecond w3c
+                       case makeTimeOfDayValid h m s of
+                         Just tod -> return tod
+                         Nothing  -> convError "Invalid time of day" w3c
+             tz  <- fetch "timezone" w3cTimeZone w3c
+             let lt = LocalTime day tod
+             return (localTimeToUTC tz lt)