This repository has been archived by the owner on Jun 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathutils.go
154 lines (129 loc) · 3.95 KB
/
utils.go
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package workalendar
import (
"time"
)
type easterType int8
//Easter methods
const (
EasterJulian easterType = 1
EasterOrthodox easterType = 2
EasterWestern easterType = 3
)
//FindLastMonday returns the last monday of month
func FindLastMonday(date time.Time) time.Time {
lastDay := time.Date(date.Year(), date.Month()+1, 1, 1, 0, 0, 0, time.UTC)
numDays := []int{-6, -7, -1, -2, -3, -4, -5}
date = lastDay.AddDate(0, 0, numDays[int(lastDay.Weekday())])
return date
}
//FindFirstMonday returns the next monday
func FindFirstMonday(date time.Time) time.Time {
day := (8 - int(date.Weekday())) % 7
date = date.AddDate(0, 0, day)
return date
}
//FindWorkingDay returns 1st working day (monday)
func FindWorkingDay(date time.Time) time.Time {
if date.Weekday() == time.Saturday {
return date.AddDate(0, 0, 2)
}
if date.Weekday() == time.Sunday {
return date.AddDate(0, 0, 1)
}
return date
}
//EasterSunday returns easter day
func EasterSunday(year int) time.Time {
return easter(year, EasterWestern)
}
func easter(year int, method easterType) time.Time {
var (
i, j, e, c, h, p, d, m, y, g int
)
y = year
g = y % 19
e = 0
if method < EasterWestern {
// Old method
i = (19*g + 15) % 30
j = (y + y/4 + i) % 7
if method == EasterOrthodox {
// Extra dates to convert Julian to Gregorian date
e = 10
if y > 1600 {
e = e + y/100 - 16 - (y/100-16)/4
}
}
} else {
// New method
c = y / 100
h = (c - c/4 - (8*c+13)/25 + 19*g + 15) % 30
i = h - (h/28)*(1-(h/28)*(29/(h+1))*((21-g)/11))
j = (y + y/4 + i + 2 - c + c/4) % 7
}
// p can be from -6 to 56 corresponding to dates 22 March to 23 May
// (later dates apply to method 2, although 23 May never actually occurs)
p = i - j + e
d = 1 + (p+27+(p+6)/40)%31
m = 3 + (p+26)/30
return time.Date(int(y), time.Month(m), int(d), 0, 0, 0, 0, time.UTC)
}
/*"""
This method was ported from the work done by GM Arts,
on top of the algorithm by Claus Tondering, which was
based in part on the algorithm of Ouding (1940), as
quoted in "Explanatory Supplement to the Astronomical
Almanac", P. Kenneth Seidelmann, editor.
This algorithm implements three different easter
calculation methods:
1 - Original calculation in Julian calendar, valid in
dates after 326 AD
2 - Original method, with date converted to Gregorian
calendar, valid in years 1583 to 4099
3 - Revised method, in Gregorian calendar, valid in
years 1583 to 4099 as well
These methods are represented by the constants:
* ``EASTER_JULIAN = 1``
* ``EASTER_ORTHODOX = 2``
* ``EASTER_WESTERN = 3``
The default method is method 3.
More about the algorithm may be found at:
`GM Arts: Easter Algorithms <http://www.gmarts.org/index.php?go=415>`_
and
`The Calendar FAQ: Easter <https://www.tondering.dk/claus/cal/easter.php>`_
"""
if not (1 <= method <= 3):
raise ValueError("invalid method")
# g - Golden year - 1
# c - Century
# h - (23 - Epact) mod 30
# i - Number of days from March 21 to Paschal Full Moon
# j - Weekday for PFM (0=Sunday, etc)
# p - Number of days from March 21 to Sunday on or before PFM
# (-6 to 28 methods 1 & 3, to 56 for method 2)
# e - Extra days to add for method 2 (converting Julian
# date to Gregorian date)
y = year
g = y % 19
e = 0
if method < 3:
# Old method
i = (19*g + 15) % 30
j = (y + y//4 + i) % 7
if method == 2:
# Extra dates to convert Julian to Gregorian date
e = 10
if y > 1600:
e = e + y//100 - 16 - (y//100 - 16)//4
else:
# New method
c = y//100
h = (c - c//4 - (8*c + 13)//25 + 19*g + 15) % 30
i = h - (h//28)*(1 - (h//28)*(29//(h + 1))*((21 - g)//11))
j = (y + y//4 + i + 2 - c + c//4) % 7
# p can be from -6 to 56 corresponding to dates 22 March to 23 May
# (later dates apply to method 2, although 23 May never actually occurs)
p = i - j + e
d = 1 + (p + 27 + (p + 6)//40) % 31
m = 3 + (p + 26)//30
*/