1 module Data.Time.Calendar.JulianYearDay
2 (
3 -- * Year and day format
4 module Data.Time.Calendar.JulianYearDay
5 ) where
7 import Data.Time.Calendar.Days
8 import Data.Time.Calendar.Private
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)
14 where
15 a = mjd + 678577
16 quad = div a 1461
17 d = mod a 1461
18 y = min (div d 365) 3
19 yd = fromInteger (d - (y * 365) + 1)
20 year = quad * 4 + y + 1
22 -- | Convert from proleptic Julian year and day format.
23 -- Invalid day numbers will be clipped to the correct range (1 to 365 or 366).
24 fromJulianYearAndDay :: Integer -> Int -> Day
25 fromJulianYearAndDay year day = ModifiedJulianDay mjd
26 where
27 y = year - 1
28 mjd =
29 (fromIntegral
30 (clip
31 1
32 (if isJulianLeapYear year
33 then 366
34 else 365)
35 day)) +
36 (365 * y) +
37 (div y 4) -
38 678578
40 -- | Convert from proleptic Julian year and day format.
41 -- Invalid day numbers will return Nothing
42 fromJulianYearAndDayValid :: Integer -> Int -> Maybe Day
43 fromJulianYearAndDayValid year day = do
44 day' <-
45 clipValid
46 1
47 (if isJulianLeapYear year
48 then 366
49 else 365)
50 day
51 let
52 y = year - 1
53 mjd = (fromIntegral day') + (365 * y) + (div y 4) - 678578
54 return (ModifiedJulianDay mjd)
56 -- | Show in proleptic Julian year and day format (yyyy-ddd)
57 showJulianYearAndDay :: Day -> String
58 showJulianYearAndDay date = (show4 y) ++ "-" ++ (show3 d)
59 where
60 (y, d) = toJulianYearAndDay date
62 -- | Is this year a leap year according to the proleptic Julian calendar?
63 isJulianLeapYear :: Integer -> Bool
64 isJulianLeapYear year = (mod year 4 == 0)