commit c8d6c65f3c5ff4101808c707b94d75cdde17c7fa Author: Yann Esposito Date: Thu Aug 13 16:47:36 2015 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c17bb9b --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.cabal-sandbox +cabal.sandbox.config +dist +*.log +*.swp +*~ +.ghci +.stack-work +container/.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c086761 --- /dev/null +++ b/LICENSE @@ -0,0 +1,30 @@ +Copyright Example Yann Esposito (c) 2015 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Yann Esposito nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Setup.hs b/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/human-readable-duration.cabal b/human-readable-duration.cabal new file mode 100644 index 0000000..ee47f3a --- /dev/null +++ b/human-readable-duration.cabal @@ -0,0 +1,32 @@ +name: human-readable-duration +version: 0.1.0.0 +synopsis: Provide duration helper +description: Please see README.md +homepage: http://github.com/yogsototh/human-readable-duration#readme +license: BSD3 +license-file: LICENSE +author: Yann Esposito +maintainer: yann.esposito@gmail.com +category: Time +build-type: Simple +-- extra-source-files: +cabal-version: >=1.10 + +library + hs-source-dirs: src + exposed-modules: Data.Duration + build-depends: base >= 4.7 && < 5 + default-language: Haskell2010 + +-- test-suite human-readable-duration-test +-- type: exitcode-stdio-1.0 +-- hs-source-dirs: test +-- main-is: Spec.hs +-- build-depends: base +-- , human-readable-duration +-- ghc-options: -threaded -rtsopts -with-rtsopts=-N +-- default-language: Haskell2010 + +source-repository head + type: git + location: https://github.com/yogstoth/human-readable-duration diff --git a/src/Data/Duration.hs b/src/Data/Duration.hs new file mode 100644 index 0000000..d3a5c6d --- /dev/null +++ b/src/Data/Duration.hs @@ -0,0 +1,80 @@ +module Data.Duration + ( humanReadableDuration + -- durations + , oneSecond + , minute + , hour + , day + , year + -- Retrieve + , getMs + , getSeconds + , getMinutes + , getHours + , getDays + , getYears + ) where + + +-- | `humanReadableDuration` take some time in micro-seconds and render a human readable duration. +-- Typically: +-- humanReadableDuration (10^6 * 60) --> 1 min +-- This isn't made to be fast. It uses String. +humanReadableDuration :: Int -> String +humanReadableDuration n + | n < oneSecond = let ms = getMs n in if ms > 0 then show ms ++ "ms" else "" + | n < minute = let s = getSeconds n in if s > 0 then show s ++ "s " ++ humanReadableDuration (n `rem` oneSecond) else "" + | n < hour = let m = getMinutes n in if m > 0 then show m ++ " min " ++ humanReadableDuration (n `rem` minute) else "" + | n < day = let h = getHours n in if h > 0 then show h ++ " hours " ++ humanReadableDuration (n `rem` hour) else "" + | n < year = let d = getDays n in if d > 0 then show d ++ " days " ++ humanReadableDuration (n `rem` day) else "" + | otherwise = let y = getYears n in if y > 0 then show y ++ " years " ++ humanReadableDuration (n `rem` year) else "" + +-------------------------------------------------------------------------------- +-- Durations +-------------------------------------------------------------------------------- +-- | number of micro seconds in one second +oneSecond :: Int +oneSecond = 10^(6 :: Integer) + +-- | number of micro seconds in one minute +minute :: Int +minute = 60 * oneSecond + +-- | number of micro seconds in one hour +hour :: Int +hour = 60 * minute + +-- | number of micro seconds in one day +day :: Int +day = 24 * hour + +-- | number of micro seconds in one year +year :: Int +year = 365 * day + +-------------------------------------------------------------------------------- +-- Retrieve some durations +-------------------------------------------------------------------------------- +-- | number of milli seconds given a duration in micro seconds +getMs :: Int -> Int +getMs n = (n `rem` oneSecond) `div` 1000 + +-- | number of seconds given a duration in micro seconds +getSeconds :: Int -> Int +getSeconds n = (n `rem` minute) `div` oneSecond + +-- | number of minutes given a duration in micro seconds +getMinutes :: Int -> Int +getMinutes n = (n `rem` hour) `div` minute + +-- | number of hours given a duration in micro seconds +getHours :: Int -> Int +getHours n = n `div` hour + +-- | number of days given a duration in micro seconds +getDays :: Int -> Int +getDays n = n `div` day + +-- | number of years given a duration in micro seconds +getYears :: Int -> Int +getYears n = n `div` year diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..809bd2e --- /dev/null +++ b/stack.yaml @@ -0,0 +1,5 @@ +flags: {} +packages: +- '.' +extra-deps: [] +resolver: lts-2.22 diff --git a/test/Spec.hs b/test/Spec.hs new file mode 100644 index 0000000..cd4753f --- /dev/null +++ b/test/Spec.hs @@ -0,0 +1,2 @@ +main :: IO () +main = putStrLn "Test suite not yet implemented"