-
Notifications
You must be signed in to change notification settings - Fork 1
/
EasterCalculatorFunc
81 lines (71 loc) · 5.7 KB
/
EasterCalculatorFunc
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
// Power Query Easter Calculator
//Created By: Szilárd Kantor szilard.kantor@gmail.com
/**
* Calculate Easter, Good Friday, Pentecost
* @param {number|text|date|datetime} yearNumOrDateOrDateTime Current year number It must be between 1583 and 2299.
* @param {null|number|text} holidayName The name of the holiday or its distance from Easter in days The allowed values are: Easter, EasterSunday, EasterMonday, GoodFriday, Pentecost, PentecostSunday, PentecostMonday or day modifier -2, 0, 1, 49, 50
* @param {null|logical} gregorian calendar when null or false, julian calendar when true
* @returns {date} Calculated Easter, Good Friday, Pentecost
*/
let
EasterDate = (yearNumOrDateOrDateTime as any, optional holidayName as any, optional julianCalendar as any) as date =>
let
getYear = yearNumOrDateOrDateTime,
getHolidayName = if holidayName = null or holidayName = "" then null
else try Number.From(holidayName) otherwise Text.Replace(Text.Lower(holidayName), " ", ""),
getJulianCalendar = if julianCalendar = "true" or julianCalendar = true then true
else if julianCalendar = null or julianCalendar = "null" or julianCalendar = "" or julianCalendar = "false" or julianCalendar = false then false
else error Error.Record("Invalid julianCalendar value", "The julianCalendar can only be null, true or false!"),
/*yearNum = try Number.From(getYear)
otherwise try Date.Year(Date.From(getYear))
otherwise Date.Year(Date.From(DateTime.FromText(getYear))) ,*/
yearNum = if Value.Is(getYear, type datetime) then Date.Year(Date.From(getYear))
else if Value.Is(getYear, type date) then Date.Year(getYear)
else try Number.From(getYear)
otherwise try Date.Year(Date.From(getYear))
otherwise try Date.Year(Date.From(DateTime.FromText(getYear)))
otherwise error Error.Record("Invalid year parameter", "Unknown format"),
year = if yearNum >= 1583 and yearNum <= 2299 then yearNum
else error Error.Record("Invalid year range", "The year can only be between 1583 and 2299! Your year: " & Text.From(yearNum)),
holidayMod = if getHolidayName = null or
getHolidayName = 0 or
getHolidayName = "easter" or
getHolidayName = "eastersunday" then 0
else if getHolidayName = -2 or
getHolidayName = "goodfriday" then -2
else if getHolidayName = 1 or
getHolidayName = "eastermonday" then 1
else if getHolidayName = 49 or
getHolidayName = "pentecost" or
getHolidayName = "pentecostsunday" then 49
else if getHolidayName = 50 or
getHolidayName = "pentecostmonday" then 50
else error Error.Record("Invalid holidayName", "Your value is " & Text.From(getHolidayName) & " The allowed values are: Easter, EasterSunday, EasterMonday, GoodFriday, Pentecost, PentecostSunday, PentecostMonday or day modifier -2, 0, 1, 49, 50"),
//https://hu.wikipedia.org/wiki/H%C3%BAsv%C3%A9tsz%C3%A1m%C3%ADt%C3%A1s#Gauss_m%C3%B3dszere
M = if getJulianCalendar then 15
else if year >= 1583 and year <= 1699 then 22
else if year >= 1700 and year <= 1899 then 23
else if year >= 1900 and year <= 2199 then 24
else if year >= 2200 and year <= 2299 then 25
else error Error.Record("Invalid year range", "The year can only be between 1583 and 2299!"),
N = if getJulianCalendar then 6
else if year >= 1583 and year <= 1699 then 2
else if year >= 1700 and year <= 1899 then 3
else if year >= 1800 and year <= 1899 then 4
else if year >= 1900 and year <= 2099 then 5
else if year >= 2100 and year <= 2199 then 6
else if year >= 2200 and year <= 2299 then 0
else error Error.Record("Invalid year range", "The year can only be between 1583 and 2299!"),
a = Number.Mod(year, 19),
b = Number.Mod(year, 4),
c = Number.Mod(year, 7),
d = Number.Mod((19 * a + M), 30),
e = Number.Mod((2 * b + 4 * c + 6 * d + N), 7),
month = if d + e < 10 then 3 else 4,
preDay = if month = 3 then d + e + 22 else d + e - 9,
day = if month = 4 and preDay = 25 and d = 28 and e = 6 and a > 10 then 19
else if month = 4 and preDay = 26 then 19 else preDay,
Result = Date.AddDays(#date(year, month, day), holidayMod)
in Result
in
EasterDate