@@ -102,20 +102,23 @@ utcTimeGood = do
102102 assertEqual "utctime" (parseWithRead "%FT%T%QZ" ts2) t2
103103 assertEqual "utctime" (parseWithRead "%F %T%QZ" ts3) t3
104104 assertEqual "utctime" (parseWithRead "%F %T%QZ" ts4) t4
105− -- timezones. Both +HHMM and +HH:MM are allowed for timezone offset
106− let ts5 = "2015-01-01T12:30:00.00+0000" :: LT.Text
105+ -- offsets. ±HH, ±HHMM, and ±HH:MM are allowed for utc offset
106+ let ts5 = "2015-01-01T12:30:00.00+00" :: LT.Text
107107 let ts6 = "2015-01-01T12:30:00.00+01:15" :: LT.Text
108108 let ts7 = "2015-01-01T12:30:00.00-0200" :: LT.Text
109109 let ts8 = "2015-01-01T22:00:00.00-03:00" :: LT.Text
110+ let ts9 = "2015-01-01T22:00:00.00-04:30" :: LT.Text
110111 let (Just (t5 :: UTCTime)) = parseWithAeson ts5
111112 let (Just (t6 :: UTCTime)) = parseWithAeson ts6
112113 let (Just (t7 :: UTCTime)) = parseWithAeson ts7
113114 let (Just (t8 :: UTCTime)) = parseWithAeson ts8
115+ let (Just (t9 :: UTCTime)) = parseWithAeson ts9
114116 assertEqual "utctime" (parseWithRead "%FT%T%QZ" "2015-01-01T12:30:00.00Z") t5
115117 assertEqual "utctime" (parseWithRead "%FT%T%QZ" "2015-01-01T11:15:00.00Z") t6
116118 assertEqual "utctime" (parseWithRead "%FT%T%QZ" "2015-01-01T14:30:00Z") t7
117119 -- ts8 wraps around to the next day in UTC
118120 assertEqual "utctime" (parseWithRead "%FT%T%QZ" "2015-01-02T01:00:00Z") t8
121+ assertEqual "utctime" (parseWithRead "%FT%T%QZ" "2015-01-02T02:30:00Z") t9
119122 where
120123 parseWithRead :: String -> LT.Text -> UTCTime
121124 parseWithRead f s =
@@ -136,6 +139,7 @@ utcTimeBad = do
136139 verifyFailParse "2015-01-01T12:30:00.00+00Z" -- no Zulu if offset given
137140 verifyFailParse "2015-01-01T12:30:00.00+00:00Z" -- no Zulu if offset given
138141 verifyFailParse "2015-01-03 12:13:00.Z" -- decimal at the end but no digits
142+ verifyFailParse "2015-01-01 13:30:00-01:60" -- malformed offset
139143 where
140144 verifyFailParse (s :: LT.Text) =
141145 let (dec :: Maybe UTCTime) = decode . LT.encodeUtf8 $ (LT.concat ["\"", s, "\""]) in