packages feed

dates 0.1.2.0 → 0.2.0.0

raw patch · 5 files changed

+245/−85 lines, 5 files

Files

Data/Dates.hs view
@@ -18,60 +18,8 @@ import Text.Parsec.String import Data.Generics --- | Date / Time-data DateTime =-  DateTime {-    year ∷ Int,-    month ∷ Int,-    day ∷ Int,-    hour ∷ Int,-    minute ∷ Int,-    second ∷ Int }-  deriving (Eq,Ord,Data,Typeable)---- | 12 months names.-months ∷ [String]-months = ["january",-          "february",-          "march",-          "april",-          "may",-          "june",-          "july",-          "august",-          "september",-          "october",-          "november",-          "december"]---- | capitalize first letter of the string-capitalize ∷ String → String-capitalize [] = []-capitalize (x:xs) = (toUpper x):xs---- | Show name of given month-showMonth ∷  Int → String-showMonth i = capitalize $ months !! (i-1)--instance Show DateTime where-  show (DateTime y m d h mins s) = -    show d ⧺ " " ⧺ showMonth m ⧺ " " ⧺ show y ⧺ ", " ⧺-      show h ⧺ ":" ⧺ show mins ⧺ ":" ⧺ show s---- | Only time, without date-data Time = -  Time {-    tHour ∷ Int,-    tMinute ∷ Int,-    tSecond ∷ Int }-  deriving (Eq,Ord,Show,Data,Typeable)---- | Parser version of Prelude.read-tryRead :: Read a => String -> Parsec String st a-tryRead str =-  case reads str of-    [(res, "")] -> return res-    _ -> fail $ "Cannot read: " ++ str+import Data.Dates.Types+import Data.Dates.Internal  -- | Get current date and time. getCurrentDateTime ∷  IO DateTime@@ -111,35 +59,6 @@                  hour = tHour t + hour dt,                  minute = tMinute t + minute dt,                  second = tSecond t + second dt }--times ∷ Int → Parsec String st t → Parsec String st [t]-times 0 _ = return []-times n p = do-  ts ← times (n-1) p-  t ← optionMaybe p-  case t of-    Just t' → return (ts ++ [t'])-    Nothing → return ts-                               -number ∷ Int → Int → Parsec String st Int-number n m = do-  t ← tryRead =<< (n `times` digit)-  if t > m-    then fail "number too large"-    else return t--pYear ∷ Parsec String st Int-pYear = do-  y ← number 4 10000-  if y < 2000-    then return (y+2000)-    else return y--pMonth ∷ Parsec String st Int-pMonth = number 2 12--pDay ∷ Parsec String st Int-pDay = number 2 31  euroNumDate ∷ Parsec String st DateTime euroNumDate = do
+ Data/Dates/Formats.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE UnicodeSyntax, DeriveDataTypeable #-}+-- | This module allows to parse arbitrary date formats.+-- Date formats are specified as strings:+--+--  * "DD.MM.YYY"+--+--  * "YYYY\/MM\/DD"+--+--  * "DD\/MM\/YYYY, HH:mm:SS"+--+--  * and so on.+--+module Data.Dates.Formats+  (FormatElement (..), Format,+   pFormat, formatParser,+   parseDateFormat+  ) where++import Control.Applicative ((<$>))+import Data.Monoid+import Text.Parsec++import Data.Dates.Types+import Data.Dates.Internal (number)++-- | Date\/time format element+data FormatElement =+    YEAR   Int+  | MONTH  Int+  | DAY    Int+  | HOUR   Int+  | MINUTE Int+  | SECOND Int+  | Fixed String+  deriving (Eq, Show)++-- | Date\/time format+type Format = [FormatElement]++nchars ∷ Char → Parsec String st Int+nchars c = do+  s ← many1 $ char c+  return $ length s++-- | Parser for date\/time format.+pFormat ∷ Parsec String st Format+pFormat = many1 $ choice $ map try [pYear, pMonth, pDay,+                                    pHour, pMinute, pSecond,+                                    pFixed]+  where+    pYear   = YEAR   <$> nchars 'Y'+    pMonth  = MONTH  <$> nchars 'M'+    pDay    = DAY    <$> nchars 'D'+    pHour   = HOUR   <$> nchars 'H'+    pMinute = MINUTE <$> nchars 'm'+    pSecond = SECOND <$> nchars 'S'+    pFixed  = Fixed <$> (many1 $ noneOf "YMDHmS")++pYear ∷ Int → Parsec String st DateTime+pYear n = do+  y ← number n 10000+  if y < 2000+    then return $ mempty {year = y+2000}+    else return $ mempty {year = y}++pMonth ∷ Int → Parsec String st DateTime+pMonth n = do+  m ← number n 12+  return $ mempty {month = m}++pDay ∷ Int → Parsec String st DateTime+pDay n = do+  d ← number n 31+  return $ mempty {day = d}++pHour ∷ Int → Parsec String st DateTime+pHour n = do+  h ← number n 23+  return $ mempty {hour = h}++pMinute ∷ Int → Parsec String st DateTime+pMinute n = do+  m ← number n 59+  return $ mempty {minute = m}++pSecond ∷ Int → Parsec String st DateTime+pSecond n = do+  s ← number n 59+  return $ mempty {second = s}++-- | Make Parser for specified date format.+formatParser ∷ Format → Parsec String st DateTime+formatParser format = mconcat <$> mapM parser format+  where+    parser (YEAR   n) = pYear n+    parser (MONTH  n) = pMonth n+    parser (DAY    n) = pDay n+    parser (HOUR   n) = pHour n+    parser (MINUTE n) = pMinute n+    parser (SECOND n) = pSecond n+    parser (Fixed s) = string s >> return mempty++-- | Parse date\/time in specified format.+parseDateFormat :: String  -- ^ Format string, i.e. "DD.MM.YY"+                -> String  -- ^ String to parse+                -> Either ParseError DateTime+parseDateFormat formatStr str = do+  format <- runParser pFormat () "(date format string)" formatStr+  runParser (formatParser format) () "(date)" str+
+ Data/Dates/Internal.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE UnicodeSyntax, DeriveDataTypeable #-}++module Data.Dates.Internal where++import Text.Parsec+import Text.Parsec.String++-- | Parser version of Prelude.read+tryRead :: Read a => String -> Parsec String st a+tryRead str =+  case reads str of+    [(res, "")] -> return res+    _ -> fail $ "Cannot read: " ++ str++-- | Apply parser N times+times ∷ Int+     → Parsec String st t+     → Parsec String st [t]+times 0 _ = return []+times n p = do+  ts ← times (n-1) p+  t ← optionMaybe p+  case t of+    Just t' → return (ts ++ [t'])+    Nothing → return ts+                               +-- | Parse natural number of N digits+-- which is not greater than M+number ∷ Int   -- ^ Number of digits+       → Int   -- ^ Maximum value+       → Parsec String st Int+number n m = do+  t ← tryRead =<< (n `times` digit)+  if t > m+    then fail "number too large"+    else return t++pYear ∷ Parsec String st Int+pYear = do+  y ← number 4 10000+  if y < 2000+    then return (y+2000)+    else return y++pMonth ∷ Parsec String st Int+pMonth = number 2 12++pDay ∷ Parsec String st Int+pDay = number 2 31+
+ Data/Dates/Types.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE UnicodeSyntax, DeriveDataTypeable #-}++module Data.Dates.Types+  (DateTime (..),+   Time (..),+   months, capitalize+  ) where++import Prelude.Unicode+import Data.Monoid+import Data.Char+import Data.Generics++-- | Date / Time+data DateTime =+  DateTime {+    year   ∷ Int,+    month  ∷ Int,+    day    ∷ Int,+    hour   ∷ Int,+    minute ∷ Int,+    second ∷ Int }+  deriving (Eq,Ord,Data,Typeable)++-- | 12 months names.+months ∷ [String]+months = ["january",+          "february",+          "march",+          "april",+          "may",+          "june",+          "july",+          "august",+          "september",+          "october",+          "november",+          "december"]++-- | capitalize first letter of the string+capitalize ∷ String → String+capitalize [] = []+capitalize (x:xs) = (toUpper x):xs++-- | Show name of given month+showMonth ∷  Int → String+showMonth i = capitalize $ months !! (i-1)++instance Show DateTime where+  show (DateTime y m d h mins s) = +    show d ⧺ " " ⧺ showMonth m ⧺ " " ⧺ show y ⧺ ", " ⧺+      show h ⧺ ":" ⧺ show mins ⧺ ":" ⧺ show s++-- | Only time, without date+data Time = +  Time {+    tHour   ∷ Int,+    tMinute ∷ Int,+    tSecond ∷ Int }+  deriving (Eq,Ord,Show,Data,Typeable)++instance Monoid DateTime where+  mempty = DateTime 0 0 0 0 0 0+  mappend dt1 dt2 =+      DateTime (year dt1   `plus` year dt2)+               (month dt1  `plus` month dt2)+               (day dt1    `plus` day dt2)+               (hour dt1   `plus` hour dt2)+               (minute dt1 `plus` minute dt2)+               (second dt1 `plus` second dt2)+    where+      plus :: Int → Int → Int+      plus 0 x = x+      plus x _ = x+
dates.cabal view
@@ -1,5 +1,5 @@ name:                dates-version:             0.1.2.0+version:             0.2.0.0 synopsis:            Small library for parsing different dates formats. description:         This package allows to parse many different formats                      of dates. Both absolute and relative dates are supported.@@ -17,6 +17,9 @@                      .                      4-digits years may be abbreviated (such as 12 for 2012).                      Both 12-hour and 24-hour time formats are supported.+                     .+                     User-specified date formats are supported by+                     Data.Dates.Formats module.  homepage:            http://redmine.iportnov.ru/projects/dates/ license:             BSD3@@ -29,7 +32,10 @@ cabal-version:       >=1.8  library-  exposed-modules:     Data.Dates+  exposed-modules:     Data.Dates,+                       Data.Dates.Types,+                       Data.Dates.Formats,+                       Data.Dates.Internal   -- other-modules:          build-depends:       base ==4.5.*,                        base-unicode-symbols ==0.2.*,