module Data.Time.Calendar.WeekDate where
import Data.Time.Calendar.OrdinalDate
import Data.Time.Calendar.Days
import Data.Time.Calendar.Private
toWeekDate :: Day -> (Integer,Int,Int)
toWeekDate :: Day -> (Integer, Int, Int)
toWeekDate date :: Day
date@(ModifiedJulianDay mjd :: Integer
mjd) = (Integer
y1,Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer
w1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 1),Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
d_mod_7 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) where
(d_div_7 :: Integer
d_div_7, d_mod_7 :: Integer
d_mod_7) = Integer
d Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` 7
(y0 :: Integer
y0,yd :: Int
yd) = Day -> (Integer, Int)
toOrdinalDate Day
date
d :: Integer
d = Integer
mjd Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 2
foo :: Integer -> Integer
foo :: Integer -> Integer
foo y :: Integer
y = Integer -> Integer
bar (Day -> Integer
toModifiedJulianDay (Integer -> Int -> Day
fromOrdinalDate Integer
y 6))
bar :: Integer -> Integer
bar k :: Integer
k = Integer
d_div_7 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
k Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` 7
(y1 :: Integer
y1,w1 :: Integer
w1) = case Integer -> Integer
bar (Integer
d Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
yd Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 4) of
-1 -> (Integer
y0 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1, Integer -> Integer
foo (Integer
y0 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1))
52 -> if Integer -> Integer
foo (Integer
y0 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 1) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== 0
then (Integer
y0 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 1, 0)
else (Integer
y0, 52)
w0 :: Integer
w0 -> (Integer
y0, Integer
w0)
fromWeekDate :: Integer -> Int -> Int -> Day
fromWeekDate :: Integer -> Int -> Int -> Day
fromWeekDate y :: Integer
y w :: Int
w d :: Int
d = Integer -> Day
ModifiedJulianDay (Integer
k Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod Integer
k 7) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (((Int -> Int -> Int -> Int
forall t. Ord t => t -> t -> t -> t
clip 1 (if Bool
longYear then 53 else 52) Int
w) Int -> Int -> Int
forall a. Num a => a -> a -> a
* 7) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int -> Int -> Int -> Int
forall t. Ord t => t -> t -> t -> t
clip 1 7 Int
d))) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 10) where
k :: Integer
k = Day -> Integer
toModifiedJulianDay (Integer -> Int -> Day
fromOrdinalDate Integer
y 6)
longYear :: Bool
longYear = case Day -> (Integer, Int, Int)
toWeekDate (Integer -> Int -> Day
fromOrdinalDate Integer
y 365) of
(_,53,_) -> Bool
True
_ -> Bool
False
fromWeekDateValid :: Integer -> Int -> Int -> Maybe Day
fromWeekDateValid :: Integer -> Int -> Int -> Maybe Day
fromWeekDateValid y :: Integer
y w :: Int
w d :: Int
d = do
Int
d' <- Int -> Int -> Int -> Maybe Int
forall t. Ord t => t -> t -> t -> Maybe t
clipValid 1 7 Int
d
let
longYear :: Bool
longYear = case Day -> (Integer, Int, Int)
toWeekDate (Integer -> Int -> Day
fromOrdinalDate Integer
y 365) of
(_,53,_) -> Bool
True
_ -> Bool
False
Int
w' <- Int -> Int -> Int -> Maybe Int
forall t. Ord t => t -> t -> t -> Maybe t
clipValid 1 (if Bool
longYear then 53 else 52) Int
w
let
k :: Integer
k = Day -> Integer
toModifiedJulianDay (Integer -> Int -> Day
fromOrdinalDate Integer
y 6)
Day -> Maybe Day
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Day
ModifiedJulianDay (Integer
k Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod Integer
k 7) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Int -> Integer
forall a. Integral a => a -> Integer
toInteger ((Int
w' Int -> Int -> Int
forall a. Num a => a -> a -> a
* 7) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
d')) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 10))
showWeekDate :: Day -> String
showWeekDate :: Day -> String
showWeekDate date :: Day
date = (Integer -> String
forall t. ShowPadded t => t -> String
show4 Integer
y) String -> String -> String
forall a. [a] -> [a] -> [a]
++ "-W" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Int -> String
forall t. ShowPadded t => t -> String
show2 Int
w) String -> String -> String
forall a. [a] -> [a] -> [a]
++ "-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Int -> String
forall a. Show a => a -> String
show Int
d) where
(y :: Integer
y,w :: Int
w,d :: Int
d) = Day -> (Integer, Int, Int)
toWeekDate Day
date