存在する日付かどうかチェックする(Haskell)。

fromGregorian 関数は Day 型を作る。存在しない日付が指定されると一番近い存在する日付の Day を返す。
Day 型に変換してから、Gregorian に戻して比較して同じ日付ならば存在する日付。

import Data.Time.Calendar
import Test.HUnit

isExistingDate :: Integer -> Int -> Int -> Bool
isExistingDate year month day = (year, month, day) == (toGregorian $ fromGregorian year month day)


-- runTestTT isExistingDateTests
isExistingDateTests = "isExistingDateTests" ~:
           test [ isExistingDate 2000  0 (-1) ~?= False,
                  isExistingDate 2010  2 29 ~?= False,
                  isExistingDate 2010  2 28 ~?= True,
                  isExistingDate 2010 13 28 ~?= False,
                  isExistingDate 2004  2 29 ~?= True,
                  isExistingDate 2000  2 29 ~?= True,
                  isExistingDate 2100  2 29 ~?= False,
                  isExistingDate 2400  2 29 ~?= True,
                  isExistingDate    0  1  1 ~?= True,
                  isExistingDate (-100) 1 1 ~?= True,
                  isExistingDate 2000  0  0 ~?= False,
                  isExistingDate    0  0  0 ~?= False,
                  isExistingDate (-999) 0 (-99) ~?= False]

{-
> runTestTT isExistingDateTests
Cases: 13  Tried: 13  Errors: 0  Failures: 0
Counts {cases = 13, tried = 13, errors = 0, failures = 0}
-}