Find day of the week from the first day of January from the date of Easter

1

I have a college job in which I should build a C calendar from the Easter date of a given year. I can find the date of Easter and build the calendar correctly in ASCII art, but I can not find the day of the week of January 1.

This Wikipedia page is written:

  

The basic approach to all methods is to find an 'anchor date': a known pair (for example: January 1, 1800, a Wednesday), determine the number of days between the anchor date and the date which you want to find, and use module 7 (% 7 or mod 7) to find the code for the new day of the week.

I then decided to apply this concept in my program, the snippet looked like this:

if(mes_pascoa == 3)
    dia_semana = (dia_pascoa + bissexto + 28 + 31) % 7;
else if(mes_pascoa == 4)
    dia_semana = (dia_pascoa + bissexto + 31 + 28 + 31) % 7;

However, the value of the day of the week is incorrect, even with the correct implementation of the code. For example, for mes_pascoa = 3 and dia_pascoa = 31 that was easter of 2013 therefore bissexto = 0 , the dia_semana value should be 2, since January 1, 2013 dropped on a Tuesday. However, my snippet is returning 6 for dia_semana .

My question is, is there a mistake in my code or in this concept I used? I would also like to know if there is any other C code implementation that can help me.

    
asked by anonymous 16.05.2015 / 17:30

3 answers

1

It seems that this concept on the Wikipedia page itself is incorrect or misunderstood by me, but I have found a solution that serves me well:

To arrive on January 1st from any date, you must calculate the number of days between the two dates and make the 7th. The result will give the day of the first Sunday of the month. We must subtract this result from 8 to get the day of the week of January 1st. For example:

  

For 2013, the distance between the date of Easter (31/3) and 1 January is 90 days. The module of 90 by 7 is 6 (so 6/1 was a Sunday). We must now return 5 units of the 7 possible "daytime" codes (with 0 being Sunday on January 1st and 7 being Sunday after the first week of the month), or 6 days out of 8 available between the first and second week . With that, we get code 2, which represents Tuesday.

In code it can be represented as follows:

#include <stdio.h>
/* Descobridor de 1º de Janeiro a partir da data da páscoa */
typedef struct{
    int dia, mes, ano, cod_semana;
} Data;

Data dia_janeiro(Data data){
    Data d; 
    int ano = data.ano, bissexto = 0;
    while(ano % 100 == 0)
        ano /= 100;
    if(ano % 4 == 0)
        bissexto = 1;

    d.dia = 1;
    d.mes = 1;
    d.ano = data.ano;

    if(data.mes == 3)
        d.cod_semana = 8 - ((data.dia + 28 + 31 + bissexto) % 7);
    else if(data.mes == 4)
        d.cod_semana = 8 - ((data.dia + 31 + 28 + 31 + bissexto) % 7);
    if(d.cod_semana > 6) d.cod_semana -= 7;
    return d;
}

int main(){
    Data pascoa;
    pascoa.dia = 31;
    pascoa.mes = 3;
    pascoa.ano = 2013;
    printf("Código do 1º de Janeiro: %d.\n", dia_janeiro(pascoa).cod_semana);
    return 0;
}

Change pascoa.dia , pascoa.mes and pascoa.ano to any valid values from an easter date and you will have the day of the week in code from January 1st of the respective year.

    
17.05.2015 / 21:36
1

Sums should be subtractions. If from Easter Sunday you want to "walk backwards", for January 1 ... subtract!

if(mes_pascoa == 3)
    dia_semana = (dia_pascoa - bissexto - 28 - 31) % 7;
else if(mes_pascoa == 4)
    dia_semana = (dia_pascoa - bissexto - 31 - 28 - 31) % 7;

Some implementations make 'strange' modules when there are negative numbers. I added a large enough value to the calculation to avoid negative numbers.

if(mes_pascoa == 3)
    dia_semana = ((dia_pascoa - bissexto - 28 - 31) + 700) % 7;
else if(mes_pascoa == 4)
    dia_semana = ((dia_pascoa - bissexto - 31 - 28 - 31) + 700) % 7;
    
16.05.2015 / 17:42
1

What about ignoring Easter and using the C library?

#include <stdio.h>
#include <time.h>

int main(void) {
    const char *ds[] = {"Domingo", "Segunda", "Terca",
                        "Quarta", "Quinta", "Sexta", "Sabado"};
    struct tm tm = {0};
    tm.tm_mday = 1;
    tm.tm_mon = 0; // Janeiro
    tm.tm_year = 113; // 2013
    tm.tm_isdst = 0;
    mktime(&tm); // normalizar tm
    printf("1 de Janeiro de %d calhou em %s.\n",
          tm.tm_year + 1900, ds[tm.tm_wday]);
    return 0;
}

You can view code working on ideone .

    
17.05.2015 / 21:56