2014-05-03 145 views
2

我想爲Data.Time.Calendar的日期類型做一個FromJSON實例。我對這些類型感到困惑,這似乎是一個普遍的情況,應該解決。Haskell日期解析

所以Day類型表示修改後的Julian日期。 Data.Time.Calendar模塊定義了「showGregorian」,它將修改的Julian日期轉換爲公曆日期並輸出String ISO 8601表示。

問題是,Data.Time.Calendar沒有一個好的方法來將ISO 8601解析爲公曆。如果我使用ParseTime類,則只能傳遞字符串格式,而不能使用字符串表示日期的日曆。所以,實際上,我會傳遞'20140502',ParseTime類會將該字符串視爲修改的Julian日期的字符串表示形式。

看來這應該是一個解決的問題。理想情況下,我想要一個不使用日期時間的解決方案。我的模型使用公曆日期,因爲這是我所需要的,而那些是我將要比較,搜索等等的東西。

當然,當我只需要日曆日期時使用日曆日的全部原因是這樣的我不必考慮如何比較和轉換它們,但我認爲這是另一天的抱怨。

附錄:

天被定義爲:

-- | The Modified Julian Day is a standard count of days, with zero being the day 1858-11-17. 
newtype Day = ModifiedJulianDay {toModifiedJulianDay :: Integer} deriving (Eq,Ord) 

這使我相信,每天不是物理的日子,但在MJD日曆天(原則下的暴露文檔應告訴我們什麼類型代表,而不是類型的表示)。

+0

我不太確定,如果我明白你到底是什麼。最近我正在處理日期解析的痛苦,我發現這個庫工作得非常好。 https://github.com/singpolyma/git-date-haskell希望這有助於 – Ecognium

+0

我所追求的是將ISO 8601日期解析爲'Day'的無憂方式,該日期使用修改後的Julian日曆。它看起來像Yesod犯了我想要避免的錯誤(我正在查看它的代碼示例) – nomen

回答

2

爲什麼parseTime完全符合你的要求? parseTime defaultTimeLocale "%F"正好與showGregorian相反(最多Just),如以下代碼片段所示,您可以將其粘貼到GHCi中。

import System.Locale 
import Data.Time.Format 
import Data.Time.Calendar 

let test = parseTime defaultTimeLocale "%F" . showGregorian :: Day -> Maybe Day 
let notIdentity x = case test x of { Nothing -> True; Just x' -> x /= x' } 
filter notIdentity [fromGregorian 0 1 1..fromGregorian 3000 12 31] 
+0

它確實按照我的要求進行了操作,正如您演示的那樣。但文件不清楚。特別是,'%F'只是一種「格式」 - 一種解析和呈現日期的方式。這不是日曆。圖書館**必須假定格式化日期爲格里高利。這是一個違規的假設,違反了Day類型的陳述意圖。它仍然意味着圖書館已經壞了,因爲這意味着我無法將parseTime放入修改後的Julian日期日曆中。感謝您的幫助,我想我正在把它帶到咖啡廳。 – nomen

+0

'時間'文件可能很難被批准。不過,我不明白你爲什麼認爲有一個錯誤。你能證明一些馬車行爲?一天不是「格里高利」或「朱利安」。這只是一天。但是,可以有格里高利或朱利安*表示。 –

+0

請參閱問題的附錄。基本上,文件說**日**是MJD,而不是實際的日子。 – nomen

2

GHC.Generics模塊使得這類問題很容易解決。

{-# language DeriveGeneriC#-} 
{-# language StandaloneDeriving #-} 

import Data.Aeson 
import Data.Time.Calendar 

import GHC.Generics 

deriving instance Generic Day 

instance ToJSON Day 
instance FromJSON Day 

雖然在閱讀您的評論:

The thing I'm after is a bugless way to parse an ISO 8601 date into a 'Day', which uses the modified Julian calendar. 

這可能不是您正在尋找的解決方案。