haskell勉強用プログラムその…2?
5/10に酔った勢いで書いた一発ネタプログラムです。おそらくhaskell初めて2つめとか3つめのプログラム。
基本以下の2つしか計算しないという単純なモノです。
- 日付と日付の間の日数計算
- ある日付から日数経過後の日付
使用方法は限定しないので、どんどん好きなように。
公開はしたけれど、後悔はしてない。
module LAdjust where import Prelude import Text.ParserCombinators.Parsec import Data.Char import Control.Exception as Exp hiding (try, catch) data Date = K{ year :: Int, month:: Int, day :: Int } instance Show Date where show (K y m d) = show y ++ "/" ++ show m ++ "/" ++ show d dateParse :: Parser (Date) dateParse = do y <- many1 digit string "/" m <- many1 digit string "/" d <- many1 digit return (K (atoi y) (atoi m) (atoi d)) where atoi l = foldl (\a b -> (a*10)+digitToInt b) 0 l isLeapY year = if (year `mod` 4 == 0 && year `mod` 100 /= 0 || year `mod` 400 == 0) then True else False getMDay year = [0, 31, if isLeapY year then 29 else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] getYDay year = foldl (\x y -> x + y) 0 (getMDay year) getMD year (m1, d1) (m2, d2) = if m1 == m2 then d2 - d1 else d3 where m' m1 m2 k = if m1 == m2 then k else m' (m1+1) m2 (((getMDay year) !! m1) + k) d3 = ((getMDay year) !! m1) - d1 + d2 + m' m1 (m2-1) 0 calcDate (K y1 m1 d1) (K y2 m2 d2) = if y1 == y2 then getMD y1 (m1, d1) (m2, d2) else getMD y1 (m1, d1) (12, 31) + calcY (y1+1) y2 0 + getMD y2 (1,1) (m2, d2) where calcY y1 y2 k = if y1 == y2 then k else calcY (y1+1) y2 (k + getYDay y1) getDay str1 str2 = calcDate d1 d2 where d1 = case parse dateParse "" str1 of Left err -> throw (ErrorCall "parse error") Right xs -> xs d2 = case parse dateParse "" str2 of Left err -> throw (ErrorCall "parse error") Right xs -> xs plusDay k 0 = k plusDay (K y1 m1 d1) days = if (days > yend) then plusDay (K (y1+1) 1 1) (days - yend) else if (days > mend) then plusDay (K y1 (m1+1) 1) (days - mend - 1) else (K y1 m1 (d1+days)) where yend = getMD y1 (m1, d1) (12,31) mend = getMD y1 (m1, d1) (m1, (getMDay y1) !! m1) plus str1 d = plusDay d1 d where d1 = case parse dateParse "" str1 of Left err -> throw (ErrorCall "parse error") Right xs -> xs -- usage: ans "1949/5/3" "1978/9/9" "1979/9/14" ans str1 str2 str3 = plus str3 (getDay str1 str2)