0b36ecb091b3e45a443feb4ec924ec6cd4b13d36
[packages/time.git] / lib / Data / Time / Calendar / JulianYearDay.hs
1 module Data.Time.Calendar.JulianYearDay
2 (
3 -- * Year and day format
4 module Data.Time.Calendar.JulianYearDay
5 ) where
6
7 import Data.Time.Calendar.Days
8 import Data.Time.Calendar.Private
9
10 -- | Convert to proleptic Julian year and day format. First element of result is year (proleptic Julian calendar),
11 -- second is the day of the year, with 1 for Jan 1, and 365 (or 366 in leap years) for Dec 31.
12 toJulianYearAndDay :: Day -> (Integer,Int)
13 toJulianYearAndDay (ModifiedJulianDay mjd) = (year,yd) where
14 a = mjd + 678577
15 quad = div a 1461
16 d = mod a 1461
17 y = min (div d 365) 3
18 yd = fromInteger (d - (y * 365) + 1)
19 year = quad * 4 + y + 1
20
21 -- | Convert from proleptic Julian year and day format.
22 -- Invalid day numbers will be clipped to the correct range (1 to 365 or 366).
23 fromJulianYearAndDay :: Integer -> Int -> Day
24 fromJulianYearAndDay year day = ModifiedJulianDay mjd where
25 y = year - 1
26 mjd = (fromIntegral (clip 1 (if isJulianLeapYear year then 366 else 365) day)) + (365 * y) + (div y 4) - 678578
27
28 -- | Convert from proleptic Julian year and day format.
29 -- Invalid day numbers will return Nothing
30 fromJulianYearAndDayValid :: Integer -> Int -> Maybe Day
31 fromJulianYearAndDayValid year day = do
32 day' <- clipValid 1 (if isJulianLeapYear year then 366 else 365) day
33 let
34 y = year - 1
35 mjd = (fromIntegral day') + (365 * y) + (div y 4) - 678578
36 return (ModifiedJulianDay mjd)
37
38 -- | Show in proleptic Julian year and day format (yyyy-ddd)
39 showJulianYearAndDay :: Day -> String
40 showJulianYearAndDay date = (show4 y) ++ "-" ++ (show3 d) where
41 (y,d) = toJulianYearAndDay date
42
43 -- | Is this year a leap year according to the proleptic Julian calendar?
44 isJulianLeapYear :: Integer -> Bool
45 isJulianLeapYear year = (mod year 4 == 0)