'VB.Net Easter Sunday Calculation wrong date output
I am trying to write an application that allows a user to input the year and the program will output the date (month and day) of Easter Sunday for the year.
But I keep on getting the wrong output for the day and sometimes the month
here is my code:
Dim year As Integer
Dim month As Integer
Dim day As Integer
Dim a, b, c, d, e, f, g, h, i, j, k As Integer
Console.WriteLine("Enter a year from 1900 to 2099 to calculate the date of Easter Sunday: ")
year = Integer.Parse(Console.ReadLine())
'Calculation of the date
a = year Mod 19 + 1
b = year / 100
c = year Mod 100
d = b / 4
e = b Mod 4
f = (8 * b + 13) / 25
g = (19 * a + b - d - f + 15) Mod 30
h = c / 4
i = c Mod 4
j = (a + 11 * g) / 319
k = (2 * e + 2 * h - i - g + j + 32) Mod 7
month = (g - j + k + 90) / 25
day = (g - j + k + month + 19) Mod 32
Console.WriteLine("")
'Shows the result
If month = 1 Then
Console.WriteLine("Easter Sunday in year " & year & " is January " & day)
ElseIf month = 2 Then
Console.WriteLine("Easter Sunday in year " & year & " is February " & day)
ElseIf month = 3 Then
Console.WriteLine("Easter Sunday in year " & year & " is March " & day)
ElseIf month = 4 Then
Console.WriteLine("Easter Sunday in year " & year & " is April " & day)
ElseIf month = 5 Then
Console.WriteLine("Easter Sunday in year " & year & " is May " & day)
ElseIf month = 6 Then
Console.WriteLine("Easter Sunday in year " & year & " is June " & day)
ElseIf month = 7 Then
Console.WriteLine("Easter Sunday in year " & year & " is July " & day)
ElseIf month = 8 Then
Console.WriteLine("Easter Sunday in year " & year & " is August " & day)
ElseIf month = 9 Then
Console.WriteLine("Easter Sunday in year " & year & " is September " & day)
ElseIf month = 10 Then
Console.WriteLine("Easter Sunday in year " & year & " is October " & day)
ElseIf month = 11 Then
Console.WriteLine("Easter Sunday in year " & year & " is November " & day)
ElseIf month = 12 Then
Console.WriteLine("Easter Sunday in year " & year & " is December " & day)
End If
the output
Enter a year from 1900 to 2099 to calculate the date of Easter Sunday:
1900
Easter Sunday in year 1900 is April 8
The output should be April 15
Enter a year from 1900 to 2099 to calculate the date of Easter Sunday:
1900
Easter Sunday in year 1901 is April 25
The output should be April 7
Solution 1:[1]
I am not going to get into how your calculation is wrong, but I guess you are using a function to calculate the date found on SO as a basis of your calculation, because it looks a little similar. The critical difference is how many times doubles are cast to int, which may change the result along the way.
It's in c#, but converted to vb.net:
Public Shared Function EasterSunday(ByVal year As Integer) As DateTime
Dim day As Integer = 0
Dim month As Integer = 0
Dim g As Integer = year Mod 19
Dim c As Integer = CInt(year / 100)
Dim h As Integer = (c - CInt((c / 4)) - CInt(((8 * c + 13) / 25)) + 19 * g + 15) Mod 30
Dim i As Integer = h - CInt((h / 28)) * (1 - CInt((h / 28)) * CInt((29 / (h + 1))) * CInt(((21 - g) / 11)))
day = i - ((year + CInt((year / 4)) + i + 2 - c + CInt((c / 4))) Mod 7) + 28
month = 3
If day > 31 Then
month += 1
day -= 31
End If
Return New DateTime(year, month, day)
End Function
But it is not a perfect analog because of the rounding differences. I have run both the vb.net and c# methods and can inspect differences in the intermediary values along the way:
The big issue is the division operator / is not the same in both languages. In VB.Net you should change to the \ Operator
Fixed converted c# to vb.net code:
Public Shared Function EasterSunday(ByVal year As Integer) As DateTime
Dim day As Integer = 0
Dim month As Integer = 0
Dim g As Integer = year Mod 19
Dim c As Integer = year \ 100
Dim h As Integer = (c - (c \ 4) - ((8 * c + 13) \ 25) + 19 * g + 15) Mod 30
Dim i As Integer = h - (h \ 28) * (1 - (h \ 28) * (29 \ (h + 1)) * ((21 - g) \ 11))
day = i - ((year + (year \ 4) + i + 2 - c + (c \ 4)) Mod 7) + 28
month = 3
If day > 31 Then
month += 1
day -= 31
End If
Return New DateTime(year, month, day)
End Function
and you can get rid of that ridiculous If Else chain, and just use some string formatting
Dim easterSundayDate = EasterSunday(year)
Console.WriteLine($"Easter Sunday in year {easterSundayDate:yyyy} is {easterSundayDate:MMMM} {easterSundayDate:dd}")
Easter Sunday in year 1900 is April 15
Finally, do you realize you are marginalizing the Eastern Orthodox? :)
Solution 2:[2]
Look at the comments,
Public Shared Function EasterCalc(whYear As Integer) As DateTime
'http://catholicism.about.com/od/holydaysandholidays/f/Calculate_Date.htm
'http://en.wikipedia.org/wiki/Computus#Algorithms
'easter - code copied, haven't a clue why it does what it does
' but it does work
'VB .Net implementation of:
'http://aa.usno.navy.mil/faq/docs/easter.php
Dim y As Integer = whYear
Dim c, d, i, j, k, l, m, n As Integer
c = y \ 100
n = y Mod 19
k = (c - 17) \ 25
i = c - c \ 4 - (c - k) \ 3 + 19 * n + 15
i = i Mod 30
i = i - (i \ 28) * (1 - (i \ 28) * (29 \ (i + 1)) * ((21 - n) \ 11))
j = y + y \ 4 + i + 2 - c + c \ 4
j = j Mod 7
l = i - j
m = 3 + (l + 40) \ 44
d = l + 28 - 31 * (m \ 4)
Dim rv As DateTime = New DateTime(y, m, d)
Return rv
End Function
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | djv |
| Solution 2 | dbasnett |


