2013-10-17 3 views
11

Ich kann nicht bekommen, einen UTCTime-Wert zu analysieren. Ich habe versucht zu encodieren und ihn zurück, aber das hat nicht funktioniert:Parsing utctime mit AESON

Prelude Data.Aeson Data.Time.Clock> getCurrentTime >>= (print . encode) 
"\"2013-10-17T09:42:49.007Z\"" 
Prelude Data.Aeson Data.Time.Clock> decode "2013-10-17T09:42:49.007Z" :: Maybe UTCTime 
Nothing 
Prelude Data.Aeson Data.Time.Clock> decode "\"2013-10-17T09:42:49.007Z\"" :: Maybe UTCTime 
Nothing 

indem die fromJson Instanz des UTCTime Typs ist die folgende (ref):

instance FromJSON UTCTime where 
    parseJSON = withText "UTCTime" $ \t -> 
     case parseTime defaultTimeLocale "%FT%T%QZ" (unpack t) of 
      Just d -> pure d 
      _  -> fail "could not parse ISO-8601 date" 

nach der Formatbeschreibung gefunden here, sollte alles in Ordnung sein. Was vermisse ich?

Antwort

17
Prelude Data.Aeson Data.Time> decode (encode [x]) :: Maybe [UTCTime] 
Just [2013-10-17 10:06:59.542 UTC] 

Notiere die "Fallen" in der Haddocks:

beachte, dass die JSON Standard verlangt, dass die Top-Level-Wert entweder ein Array oder ein Objekt sein. Wenn Sie versuchen, dekodieren zu verwenden, mit einem Ergebnis Typ, der nicht in JSON als ein Array oder ein Objekt dargestellt wird, der Code wird typecheck, aber es wird immer „nicht bestanden“ zur Laufzeit:

...

bleiben also auf Objekte (zB Karten in Haskell) oder Arrays (Listen oder Vektoren in Haskell):

+0

ich diesen Abschnitt gelesen hatte. Mein Gehirn hat die Verbindung jedoch nicht hergestellt. Vielen Dank! – Simon

+0

Ein praktischer Trick, um dies zu umgehen, besteht darin, Ihre Typen einfach in eine Listenebene zu packen: 'decode '..." :: FromJSON a => Maybe [a] '. Ich benutze dies die ganze Zeit für die schnelle Überprüfung von Subparsern. Es ist * viel * einfacher als der Versuch, die inneren Aeson-Parser neu zu verdrahten, um nicht-standardmäßiges JSON-Verhalten zu erhalten. –

+2

Wenn Sie den Parser 'value' von' Data.Aeson.Parser' verwenden, können Sie die Spezifikation überschreiben. Anforderung, nur JSON-Objekt/Arrays der obersten Ebene zu analysieren und einzelne Werte zu analysieren. Benutze es mit attoparsec. –