Android Question [Solved] Calculate Easter Day

asales

Expert
Licensed User
Longtime User
I found these functions (in VB) that calculates easter day, but I could not convert to B4A (I tried but don't worked):
http://www.cpearson.com/excel/easter.aspx
http://www.codeproject.com/Tips/6630/Computing-Easter-Date-VB-Function

I tried to convert this function made in Delphi...

B4X:
function GetGoldenNumber (const Year: Word): Integer;
begin
   Result := Year mod 19 + 1;
End;

function GetEasterSunday (const Year: Word): TDateTime;
var
   C, I, J, H, G, L: Integer;
   D, M: Word;
begin
   G := GetGoldenNumber (Year) - 1;
   C := Year div 100;
   H := (C - C div 4 - (8 * C + 13) div 25 + 19 * G + 15) mod 30;
   I := H - (H div 28) * (1 - (H div 28) * (29 div (H + 1))*((21 - G) div 11));
   J := (Year + Year div 4 + I + 2 - C + C div 4) mod 7;

   L := I - J;
   M := 3 + (L + 40) div 44;
   D := L + 28 - 31 * (M div 4);
   Result := EncodeDate (Year, M, D);
End;

to this:

B4X:
Sub GetGoldenNumber (Year As Long) As Int
   Return Year Mod 19 + 1
End Sub

Sub GetEasterSunday (Year As Long) As Long
       Dim C, I, J, H, G, L As Int
       Dim D, M As Long

       G = GetGoldenNumber(Year) - 1
       C = Year / 100
       H = (C - C / 4 - (8 * C + 13) / 25 + 19 * G + 15) Mod 30
       I = H - (H / 28) * (1 - (H / 28) * (29 / (H + 1))*((21 - G) / 11))
       J = (Year + Year / 4 + I + 2 - C + C / 4) Mod 7

       L = I - J
       M = 3 + (L + 40) / 44
       D = L + 28 - 31 * (M / 4)

    Return DateTime.DateParse(M & "/" & D & "/" & Year)
End Sub

Label1.Text = DateTime.Date(GetEasterSunday(EditText1.Text))

but did not work too.

The easter sunday in 2015 is April 5 and in 2016 is March 27.

I appreciate any help to make this function works.
 

DonManfred

Expert
Licensed User
Longtime User
NO B4A-Code(!)... Just the info about the calculation to check it (found here)
B4X:
  a = J Mod 19
  b = J Mod 4
  c = J Mod 7
  d = (19 * a + 24) Mod 30
  e = (2 * b + 4 * c + 6 * d + 5) Mod 7
  OT = 22 + d + e
  OM = 3
  If OT > 31 Then
  OT = d + e - 9
  OM = 4
  End If
  If OT = 26 And OM = 4 Then
  OT = 19
  End If
  If OT = 25 And OM = 4 And d = 28 And e = 6 And a > 10 Then
  OT = 18
  End If

Where
J= Number of the year
OM= Month of the Easter Sunday
OT= Day of the Easter Sunday in this month

Original from: Peter Wünsche --- [email protected]-bamberg.de --- 25.07.95
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
remove that goldyear sub and use this instead

B4X:
Sub GetEasterSunday (Year As Long) As String
       Dim C, I, J, H, G, K,L,N As Int
       Dim D, M As Long
       G = Year Mod 19
       C = Year/100
       H = ((C - (C / 4) - (8 * C + 13) / 25) + 19 * G + 15) Mod 30
       I = H - (H / 28) * (1 - (H / 28) * (29 / (H + 1))*((21 - G) / 11))
       J = (Year + (Year / 4) + I + 2 - C + (C / 4)) Mod 7
       L = I - J
       M = 3 + ((L + 40) / 44)
       D = L + 28 - 31 * Floor(M / 4)             
    Return (M & "/" & D & "/" & Year)
End Sub

Log( GetEasterSunday(2015) )
Log( GetEasterSunday(2016) )


outputs

** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = true **
4/5/2015
3/27/2016
** Activity (main) Resume **
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
it did in the original but I didn't see the point of it as you want to display it as text anyway, not?
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
oh you mean to combine it with dateformat so that you get dd/mm/yyyy for us euros instead?
 
Upvote 0

NJDude

Expert
Licensed User
Longtime User
A slightly enhanced version of Sorex's code:
B4X:
'Format: L = Long date
Sub GetEasterSunday(Year As Long, Format As String) As String

    Private C, I, J, H, G, L As Int
    Private D, M As Long
    Private Month() As String
 
    Month = Array As String("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")

    G = Year Mod 19
    C = Year/100
    H = ((C - (C / 4) - (8 * C + 13) / 25) + 19 * G + 15) Mod 30
    I = H - (H / 28) * (1 - (H / 28) * (29 / (H + 1))*((21 - G) / 11))
    J = (Year + (Year / 4) + I + 2 - C + (C / 4)) Mod 7
    L = I - J
    M = 3 + ((L + 40) / 44)
    D = L + 28 - 31 * Floor(M / 4)             

    If Format.ToUpperCase = "L" Then
				
       Return (Month(M - 1) & " " & D & ", " & Year)
							
    Else
				
       Return (M & "/" & D & "/" & Year)
							
    End If

End Sub
 
Upvote 0

Fulvio75

Well-Known Member
Licensed User
A slightly enhanced version of Sorex's code:
B4X:
'Format: L = Long date
Sub GetEasterSunday(Year As Long, Format As String) As String

    Private C, I, J, H, G, L As Int
    Private D, M As Long
    Private Month() As String
 
    Month = Array As String("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")

    G = Year Mod 19
    C = Year/100
    H = ((C - (C / 4) - (8 * C + 13) / 25) + 19 * G + 15) Mod 30
    I = H - (H / 28) * (1 - (H / 28) * (29 / (H + 1))*((21 - G) / 11))
    J = (Year + (Year / 4) + I + 2 - C + (C / 4)) Mod 7
    L = I - J
    M = 3 + ((L + 40) / 44)
    D = L + 28 - 31 * Floor(M / 4)            

    If Format.ToUpperCase = "L" Then
               
       Return (Month(M - 1) & " " & D & ", " & Year)
                           
    Else
               
       Return (M & "/" & D & "/" & Year)
                           
    End If

End Sub

for 2024 and 2025 the day is wrong
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
for 2024 and 2025 the day is wrong

Use this sub

B4X:
public Sub GetEasterSunday(Year As Long) As String
'    int a, b, c, d, e, p, q, r, x, y, tag, monat, jahr ;
    Dim a, b, c, d, e, p, q, r, x, y, tag, monat, ptag, pmonat As Int
   
'    System.out.println("Berechnung des Osterdatums nach Gauss");
'    System.out.print("Jahreszahl : ");
'    jahr = Stdin.intEingabe();
'
'    //Es geht um die Berechnung der Größen d und e
'    //Dazu braucht man die 9 Hilfsgrößen a, b, c, p, n, q, r, x, y !!
'
    p = Year/100
    q = p/3
    r = p/4

    x = (15+p-q-r) Mod 30
    y = (4+p-r) Mod 7

    a = Year Mod 19
    b = Year Mod 4
    c = Year Mod 7

    d = (19*a+x) Mod 30
    e = (2*b+4*c+6*d+y) Mod 7
    If (d=29 And  e=6) Then
'        //=> Ostern am 19.April
    tag=19
        monat=4
    else if (d=28 And e=6) Then
'        //=> Ostern am 18.April
    tag=18
        monat=4
    else if (22+d+e < 32) Then
        '    //=>  Ostern am (22+d+e).März
    tag=22+d+e
        monat=3
    Else
        '// =>  Ostern am (d+e-9).April
    tag=d+e-9
        monat=4
    End If
'    System.out.print("Ostern ist/war am ");
    If (tag < 10) Then
        Log("0"&tag&"."&"0"&monat&"."&Year)
    Else
        Log(tag&"."&"0"&monat&"."&Year)
    End If
'
    If monat=3 Then
    ptag = tag-12
        pmonat=5
    else if (monat=4 And tag < 13) Then
    ptag = tag+19
        pmonat=5
    Else
    ptag = tag-12
        pmonat = 6
    End If
'    System.out.print("Easterday is ");
    If (ptag < 10) Then
        Return "0"&ptag&"."&"0"&pmonat&"."&Year
    Else
        Return ""&ptag&"."&"0"&pmonat&"."&Year
    End If
End Sub
 
Upvote 0

Fulvio75

Well-Known Member
Licensed User
Use this sub

B4X:
public Sub GetEasterSunday(Year As Long) As String
'    int a, b, c, d, e, p, q, r, x, y, tag, monat, jahr ;
    Dim a, b, c, d, e, p, q, r, x, y, tag, monat, ptag, pmonat As Int
 
'    System.out.println("Berechnung des Osterdatums nach Gauss");
'    System.out.print("Jahreszahl : ");
'    jahr = Stdin.intEingabe();
'
'    //Es geht um die Berechnung der Größen d und e
'    //Dazu braucht man die 9 Hilfsgrößen a, b, c, p, n, q, r, x, y !!
'
    p = Year/100
    q = p/3
    r = p/4

    x = (15+p-q-r) Mod 30
    y = (4+p-r) Mod 7

    a = Year Mod 19
    b = Year Mod 4
    c = Year Mod 7

    d = (19*a+x) Mod 30
    e = (2*b+4*c+6*d+y) Mod 7
    If (d=29 And  e=6) Then
'        //=> Ostern am 19.April
    tag=19
        monat=4
    else if (d=28 And e=6) Then
'        //=> Ostern am 18.April
    tag=18
        monat=4
    else if (22+d+e < 32) Then
        '    //=>  Ostern am (22+d+e).März
    tag=22+d+e
        monat=3
    Else
        '// =>  Ostern am (d+e-9).April
    tag=d+e-9
        monat=4
    End If
'    System.out.print("Ostern ist/war am ");
    If (tag < 10) Then
        Log("0"&tag&"."&"0"&monat&"."&Year)
    Else
        Log(tag&"."&"0"&monat&"."&Year)
    End If
'
    If monat=3 Then
    ptag = tag-12
        pmonat=5
    else if (monat=4 And tag < 13) Then
    ptag = tag+19
        pmonat=5
    Else
    ptag = tag-12
        pmonat = 6
    End If
'    System.out.print("Easterday is ");
    If (ptag < 10) Then
        Return "0"&ptag&"."&"0"&pmonat&"."&Year
    Else
        Return ""&ptag&"."&"0"&pmonat&"."&Year
    End If
End Sub
ok thanks I used this rudimentary method ? ?

B4X:
public Sub Get_EasterSunday(Year As Int) As Long

    Dim C, I, J, H, G, L As Int
    Dim Day As Int
    Dim Month As Int
     [B]Dim Days As Int = 0[/B]
   
    Try
       
        G = Year Mod 19
        C = Year/100
        H = ((C - (C / 4) - (8 * C + 13) / 25) + 19 * G + 15) Mod 30
        I = H - (H / 28) * (1 - (H / 28) * (29 / (H + 1))*((21 - G) / 11))
        J = (Year + (Year / 4) + I + 2 - C + (C / 4)) Mod 7
        L = I - J
        Month = 3 + ((L + 40) / 44)
        Day = L + 28 - 31 * Floor(Month / 4)

        DateTime.DateFormat = "MM/dd/yyyy"
       
        [B]Select Year
           
            Case 2024
                Days = 7

            Case 2025
                Days = 7

            Case 2028
                Days = 7

            Case 2031
                Days = 7

            Case Else
                Days = 0      
           
        End Select[/B]
       
        Return DateTime.Add(DateTime.DateParse(Month & "/" & Day & "/" & Year),0,0,[B]Days[/B])
       
    Catch
        Return DateZero
    End Try
               
End Sub
 
Upvote 0
Top