summaryrefslogtreecommitdiff
path: root/assignment-7/DateExtensions.icl
blob: fa9ebb0a9d59fc957695c0e7461edbf39315e8bf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
implementation module DateExtensions

import _SystemArray
from StdFunc import flip

from Data.Func import $
import System.Time

import iTasks
import iTasks.Extensions.DateTime

derive class iTask Day

instance toString Day
where
	toString Sunday    = "Sunday"
	toString Monday    = "Monday"
	toString Tuesday   = "Tuesday"
	toString Wednesday = "Wednesday"
	toString Thursday  = "Thursday"
	toString Friday    = "Friday"
	toString Saturday  = "Saturday"

(+~) infixl 6 :: Timestamp Int -> Timestamp
(+~) (Timestamp t) i = Timestamp (t+i)

(-~) infixl 6 :: Timestamp Int -> Timestamp
(-~) (Timestamp t) i = Timestamp (t-i)

timestampToGmDate :: (Timestamp -> Date)
timestampToGmDate = toDate o timestampToGmDateTime

nextHour :: DateTime -> DateTime
nextHour t = timestampToGmDateTime (Timestamp ts`)
where
	(Timestamp ts) = utcDateTimeToTimestamp t
	ts` = ts + 3600 - (ts rem 3600)

nextDay :: (Date -> Date)
nextDay = timestampToGmDate o (flip (+~) 86400) o utcDateToTimestamp

// https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Schwerdtfeger.27s_method
dayOfWeek :: Date -> Day
dayOfWeek date = days.[(d + e + f + g + g / 4) rem 7]
where
	days :: {Day}
	days = {Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday}
	d = date.Date.day
	e = {#0,3,2,5,0,3,5,1,4,6,2,4}.[date.Date.mon-1]
	f = {#0,5,3,1}.[c rem 4]
	(c,g) = if (date.Date.mon >= 3)
		(y     / 100, y - 100 * c)
		((y-1) / 100, y - 100 * c - 1)
	y = date.Date.year

previous :: Day Date -> Date
previous day date
| dayOfWeek date === day = date
| otherwise = previous day $ timestampToGmDate $ minus 86400 $ utcDateToTimestamp date
where
	minus :: Int Timestamp -> Timestamp
	minus i (Timestamp t) = Timestamp (t-i)