packages feed

hebrew-time 0.0.0 → 0.0.1

raw patch · 3 files changed

+157/−26 lines, 3 filesdep +failuredep +safe-failuredep −bytestring-classdep ~data-objectdep ~timenew-component:exe:runtestsPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: failure, safe-failure

Dependencies removed: bytestring-class

Dependency ranges changed: data-object, time

API changes (from Hackage documentation)

- Data.Time.Calendar.Hebrew: instance Arbitrary Chalakim
- Data.Time.Calendar.Hebrew: instance Arbitrary Days
- Data.Time.Calendar.Hebrew: instance Arbitrary HebrewDate
- Data.Time.Calendar.Hebrew: instance Arbitrary YearLeap
- Data.Time.Calendar.Hebrew: instance Arbitrary YearType
- Data.Time.Calendar.Hebrew: instance Arbitrary Years
- Data.Time.Calendar.Hebrew: instance FromObject Month
- Data.Time.Calendar.Hebrew: instance FromScalar Month
- Data.Time.Calendar.Hebrew: instance ToObject Month
- Data.Time.Calendar.Hebrew: instance ToScalar Month
- Data.Time.Calendar.Hebrew: testSuite :: Test
+ Data.Time.Calendar.Hebrew: anniversaryInYear :: Int -> HebrewDate -> HebrewDate
+ Data.Time.Calendar.Hebrew: instance ConvertAttempt String Month
+ Data.Time.Calendar.Hebrew: instance ConvertSuccess Month String
+ Data.Time.Calendar.Hebrew: instance Exception InvalidHebrewMonth
+ Data.Time.Calendar.Hebrew: instance Show InvalidHebrewMonth
+ Data.Time.Calendar.Hebrew: instance Typeable InvalidHebrewMonth
+ Data.Time.Calendar.Hebrew: nextAnniversary :: HebrewDate -> HebrewDate -> HebrewDate

Files

Data/Time/Calendar/Hebrew.hs view
@@ -1,4 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE CPP #-} --------------------------------------------------------- -- -- Module        : Data.Time.Calendar.Hebrew@@ -17,23 +21,34 @@     , Month (..)     , fromHebrew     , toHebrew+      -- * Anniversaries+    , anniversaryInYear+    , nextAnniversary+#if TEST       -- * Testing     , testSuite+#endif     ) where  import Control.Applicative ((<$>)) import Control.Arrow+import Control.Monad import Data.Time.Calendar (Day (..), fromGregorian) import Data.Time.Calendar.WeekDate (toWeekDate)+import Data.Typeable (Typeable)+import Control.Exception (Exception)+import qualified Safe.Failure as SF+import Control.Failure +#if TEST import Test.Framework (testGroup, Test) import Test.Framework.Providers.HUnit import Test.Framework.Providers.QuickCheck (testProperty) import Test.HUnit hiding (Test) import Test.QuickCheck+#endif  import Data.Object-import Data.ByteString.Class  ------ data definitions data Month = Tishrei | Cheshvan | Kislev | Tevet | Shevat@@ -45,6 +60,27 @@ data YearLeap = Leap | NonLeap     deriving (Eq, Ord, Show, Enum) +{- FIXME use some translation package+instance CanTranslate Month where+    tryTranslate x "en" = Just $ convertSuccess $ show x+    tryTranslate Tishrei "he" = Just "תשרי"+    tryTranslate Cheshvan "he" = Just "חשון"+    tryTranslate Kislev "he" = Just "כסלו"+    tryTranslate Tevet "he" = Just "טבת"+    tryTranslate Shevat "he" = Just "שבט"+    tryTranslate Adar "he" = Just "אדר"+    tryTranslate Adar1 "he" = Just "אדר א"+    tryTranslate Adar2 "he" = Just "אדר ב"+    tryTranslate Nissan "he" = Just "ניסן"+    tryTranslate Iyar "he" = Just "אייר"+    tryTranslate Sivan "he" = Just "סיון"+    tryTranslate Tammuz "he" = Just "תמוז"+    tryTranslate Av "he" = Just "אב"+    tryTranslate Elul "he" = Just "אלול"++    defaultTranslate = convertSuccess . show+-}+ ------ newtypes newtype Chalakim = Chalakim Integer     deriving (Eq, Ord, Show, Enum, Num, Real, Integral)@@ -103,20 +139,24 @@         (w, d) = weeksFromDays d'      in (w, d, s, c) +#if TEST case_splitChalakim :: Assertion case_splitChalakim = do     splitChalakim 1080 @=? (0, 0, 1, 0)     splitChalakim (15 * 24 * 1080) @=? (2, 1, 0, 0)+#endif  joinChalakim :: Weeks -> Days -> Shaot -> Chalakim -> TotalChalakim joinChalakim w d s c =     chalakimFromShaot (shaotFromDays (daysFromWeeks w + d) + s) + c +#if TEST prop_joinSplitChalakim :: TotalChalakim -> Bool prop_joinSplitChalakim tc = tc == uncurry4 joinChalakim (splitChalakim tc)     where         uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e         uncurry4 f (a, b, c, d) = f a b c d+#endif  ------ year dependent constants isLeapYear :: Years -> YearLeap@@ -167,6 +207,7 @@         extra = extraMonthCount $ Years y      in base + extra +#if TEST case_monthsTilTishrei :: Assertion case_monthsTilTishrei = do     0 @=? monthsTilTishrei 1@@ -177,6 +218,7 @@  prop_monthsTilTishrei :: Years -> Bool prop_monthsTilTishrei y = monthsTilTishrei y == monthsTilTishreiLong y+#endif  firstTishrei :: TotalChalakim firstTishrei = joinChalakim 0 1 5 204@@ -184,6 +226,7 @@ moladTishrei :: Years -> TotalChalakim moladTishrei y = chalakimFromMonths (monthsTilTishrei y) + firstTishrei +#if TEST case_moladTishrei :: Assertion case_moladTishrei = do     let testMolad w x y z = do@@ -204,6 +247,7 @@     testMolad 18 0 15 414     testMolad 19 5 0 210     testMolad 20 3 21 799+#endif  monthLength :: YearLeap -> YearType -> Month -> Days monthLength _ _ Tishrei = 30@@ -246,9 +290,11 @@             | otherwise = helper (succ m) (j - ml m)      in helper Tishrei j' +#if TEST prop_dateToFromJulian :: YearLeap -> YearType -> Julian -> Bool prop_dateToFromJulian yl yt j =     j == uncurry (julianFromDate yl yt) (dateFromJulian yl yt j)+#endif  ------ determining year stuff roshHashana :: Years -> TotalDays@@ -277,24 +323,30 @@                s == 15 && c > 589) = 2             | otherwise = 0 +#if TEST case_firstRoshHashana :: Assertion case_firstRoshHashana = roshHashana 1 @?= 1+#endif  dayOfWeek :: TotalDays -> Weekday dayOfWeek t =     let (_, w) = weeksFromDays t      in w +#if TEST prop_validRoshHashanaDay :: Years -> Bool prop_validRoshHashanaDay = (`elem` [1, 2, 4, 6]) . dayOfWeek . roshHashana+#endif  yearLength :: Years -> TotalDays yearLength y = roshHashana (y + 1) - roshHashana y +#if TEST prop_yearLength :: Years -> Bool prop_yearLength y =     let l = yearLength y      in l `elem` [353, 354, 355, 383, 384, 385]+#endif  julianFromDays :: TotalDays -> (Years, Julian) julianFromDays td = uncurry helper $ approx td where@@ -309,8 +361,10 @@             rem' = Days $ td' - rh + 1          in (minYears, rem') +#if TEST prop_roshHashana_julianFromDays :: Years -> Bool prop_roshHashana_julianFromDays y = (y, 1) == julianFromDays (roshHashana y)+#endif  yearDef :: TotalDays -> TotalDays -> (YearLeap, YearType) yearDef a b = case b - a of@@ -358,6 +412,7 @@         ds = fromIntegral $ sum $ map ml [Tishrei ..m]      in rh + ds + fromIntegral d - fromIntegral (ml m) - 1 +#if TEST prop_fromToHebrew :: Integer -> Bool prop_fromToHebrew d' =     let d = ModifiedJulianDay d'@@ -385,7 +440,66 @@     fromGregorian 1984 9 27 @=? fromHebrew (HebrewDate 5745 Tishrei 1)     fromGregorian 1985 1 12 @=? fromHebrew (HebrewDate 5745 Tevet 19)     fromGregorian 1986 9 8 @=? fromHebrew (HebrewDate 5746 Elul 4)+#endif +clip :: HebrewDate -> HebrewDate+clip (HebrewDate y m d) =+    let y' = Years $ fromIntegral y+        (yl, yt) = yearDef (roshHashana y') (roshHashana $ y' + 1)+        m' = adjustMonth yl m+        ml = fromIntegral $ monthLength yl yt m'+        d' = if d > ml then ml else d+     in HebrewDate y m' d'++adjustMonth :: YearLeap -> Month -> Month+adjustMonth Leap Adar = Adar2+adjustMonth Leap x = x+adjustMonth NonLeap Adar1 = Adar+adjustMonth NonLeap Adar2 = Adar+adjustMonth NonLeap x = x++anniversaryInYear :: Int -- ^ year+                  -> HebrewDate+                  -> HebrewDate+anniversaryInYear y (HebrewDate _ m d) = clip $ HebrewDate y m d++#if TEST+caseAnniversaryInYear :: IO ()+caseAnniversaryInYear = do+    -- Year 5770 is just the current year at time of writing+    -- Year 3 is a chaser leap year+    -- Year 4 is a leap year+    HebrewDate 5770 Tishrei 1 @=?+        anniversaryInYear 5770 (HebrewDate 1 Tishrei 1)+    HebrewDate 3 Cheshvan 29 @=?+        anniversaryInYear 3 (HebrewDate 1 Cheshvan 30)+    HebrewDate 3 Kislev 29 @=?+        anniversaryInYear 3 (HebrewDate 1 Kislev 30)+    HebrewDate 3 Adar2 1 @=?+        anniversaryInYear 3 (HebrewDate 1 Adar 1)+    HebrewDate 4 Adar 1 @=?+        anniversaryInYear 4 (HebrewDate 1 Adar1 1)+    HebrewDate 4 Adar 1 @=?+        anniversaryInYear 4 (HebrewDate 1 Adar2 1)+    HebrewDate 4 Adar 29 @=?+        anniversaryInYear 4 (HebrewDate 1 Adar1 30)+#endif++nextAnniversary :: HebrewDate -- ^ so to say current date+                -> HebrewDate -- ^ date of event+                -> HebrewDate -- ^ first anniversary of event after current+nextAnniversary (HebrewDate cy cm cd) hd@(HebrewDate y m d)+    | cm > m || cm == m && cd > d = anniversaryInYear (cy + 1) hd+    | otherwise = anniversaryInYear cy hd++#if TEST+caseNextAnniversary :: IO ()+caseNextAnniversary = do+    HebrewDate 5770 Tishrei 2 @=?+        nextAnniversary (HebrewDate 5770 Tishrei 1) (HebrewDate 1 Tishrei 2)+    HebrewDate 5771 Tishrei 2 @=?+        nextAnniversary (HebrewDate 5770 Tishrei 3) (HebrewDate 1 Tishrei 2)+ ------ testing testSuite :: Test testSuite = testGroup "Data.Time.Calendar.Hebrew"@@ -403,6 +517,8 @@     , testProperty "greg/hebrew same weekday" prop_sameWeekday     , testCase "integral date spot check" case_integralSpotCheck     , testCase "individual date spot checks" case_spotChecks+    , testCase "caseAnniversaryInYear" caseAnniversaryInYear+    , testCase "caseNextAnniversary" caseNextAnniversary     ]  instance Arbitrary Chalakim where@@ -438,20 +554,13 @@         y <- (+ 1) . (`mod` 6000) <$> arbitrary         day <- (+ 1) . (`mod` 29) <$> arbitrary         return $! HebrewDate y m day+#endif ------ Data.Object instances-instance ToScalar Month where-    toScalar = toScalar . show-instance ToObject Month where-    toObject = toObject . toScalar-readM :: (Read r, Monad m) => String -> m r-readM s = case reads s of-            ((x, _):_) -> return x-            _ -> fail $ "Unable to read: " ++ s-instance FromScalar Month where-    fromScalar bs =-      case readM $ fromLazyByteString bs of-          Just x -> return x-          Nothing -> fail $ "Invalid hebrew month: " ++ fromLazyByteString bs-instance FromObject Month where-    fromObject o = fromObject o >>= fromScalar+----- Data.Object.Text instances+instance ConvertSuccess Month String where+    convertSuccess = show+instance ConvertAttempt String Month where+    convertAttempt s = wrapFailure (\_ -> InvalidHebrewMonth s) $ SF.read s+data InvalidHebrewMonth = InvalidHebrewMonth String+    deriving (Show, Typeable)+instance Exception InvalidHebrewMonth
hebrew-time.cabal view
@@ -1,5 +1,5 @@ name:            hebrew-time-version:         0.0.0+version:         0.0.1 license:         BSD3 license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>@@ -12,15 +12,29 @@ build-type:      Simple homepage:        http://github.com/snoyberg/hebrew-time/tree/master +flag buildtests+  description: Build the executable to run unit tests+  default: False+ library     build-depends:   base >= 4 && < 5,-                     time >= 1.1.3,-                     test-framework,-                     test-framework-quickcheck,-                     test-framework-hunit,-                     HUnit,-                     QuickCheck >= 1 && < 2,-                     bytestring-class,-                     data-object >= 0.0.2+                     time >= 1.1.3 && < 1.2,+                     data-object >= 0.2.0 && < 0.3,+                     failure >= 0.0.0 && < 0.1,+                     safe-failure >= 0.4.0 && < 0.5     exposed-modules: Data.Time.Calendar.Hebrew     ghc-options:     -Wall++executable           runtests+    if flag(buildtests)+        Buildable: True+        cpp-options:     -DTEST+        build-depends:   test-framework,+                         test-framework-quickcheck,+                         test-framework-hunit,+                         HUnit,+                         QuickCheck >= 1 && < 2+    else+        Buildable: False+    ghc-options:     -Wall+    main-is:         runtests.hs
+ runtests.hs view
@@ -0,0 +1,8 @@+import Test.Framework (defaultMain)++import qualified Data.Time.Calendar.Hebrew++main :: IO ()+main = defaultMain+    [ Data.Time.Calendar.Hebrew.testSuite+    ]