Quer aprender a descobrir a fase lunar de um dia apenas somando 3 a 4 números? Vamos ver mais a frente...
Ao estudar um pouco sobre as fases lunares, me deparei com um algoritmo muito interessante do matemático John Horton Conway. Ele cria um método para facilitar sabermos as fases lunares, sem a necessidade de cálculos elaborados, apenas com contas que conseguimos realizar mentalmente. Por isso, resolvi incrementar um pouco o algoritmo de fases lunares que eu havia feito e também implementar esse algoritmo mental. Se você ainda não viu a versão simplificada, para computadores, considerando somente o período sinódico, dê uma olhada aqui.
O algoritmo de Conway consiste em achar um padrão apenas utilizando contas simples para as fases lunares do século XX e XXI. Embora ele não tenha calculado os valores para os outros anos, creio que seja possível fazer apenas alterando um parâmetro na somatória final (tentarei posteriormente). A ideia desse algoritmo é que ele possa ser armazenado mentalmente para você saber as fases da lua, sem olhar para o céu.
Em resumo você considera apenas os dois últimos dígitos do ano, calcula o resto da divisão dele por 19 e se for maior que 9, subtraia 19. Multiplica o resultado por 11, calcula o resto da divisão por 30. Subtrai 4, para o século XX ou subtrai 8 para o século XXI e acha o resto da divisão por 30 novamente. Soma com o dia e o mês (se for janeiro ou fevereiro você soma 2). Se você achar difícil, olhe para o céu :D. Para o ano atual (2018), podemos já adiantar uma parte do algoritmo para facilitar o cálculo mental:
- resto da divisão de 18 (dois últimos dígitos) por 19 é 18
- como é maior que 9, subtraia 19; temos: 18-19 = -1
- multiplica o resultado por 11; temos: -1 * 11 = -11
- resto da divisão de -11 por 30 é 19
- como estamos no século XXI, subtrai 8; temos 19 - 8 = 11
- resto da divisão de 11 por 30 é 11
Essa a parte do cálculo que utiliza o ano. Então para o ano de 2018, você não precisa mais realizar nenhum cálculo, o valor obtido é 11 (pode decorar esse número, que até o fim desse ano ele é válido). Caso ache interessante, calcule para os outros anos. Para o dia e mês de hoje (05 de abril) é só fazer a seguinte conta:
- número obtido (no caso é 11) + dia + mês; temos: 11+5+4 = 20
- Se for janeiro ou fevereiro soma-se mais 2... não é o caso nosso
Com isso você só precisa saber o número 11 e somar com outros 2 números para saber o dia lunar que estamos. Que no caso é dia 20. Fácil, né? Para saber a fase da lua, você pode utilizar a seguinte tabela:
- Lua Nova - 0, 1, 29
- Crescente - de 2 a 6
- Quarto crescente - 7 e 8
- Crescente gibosa - de 9 a 13
- Cheia - de 14 a 16
- Minguante gibosa - de 17 a 21
- Quarto minguante - 22 e 23
- Minguante - de 24 a 28
Ou se preferir é só lembrar que quanto mais próximo do valor 15 estiver, mais cheia está a lua e assim não precisa decorar mais nada.
Com isso, resolvi implementar essa lógica do algoritmo, incrementando alguns valores. Ela pode ser encontrada aqui e aqui. O código está baseado na versão anterior (veja antes de utilizar o novo). Para a tabela de luas, criei uma função com condicionais (preciso melhorar):
public static MoonPhase getMoonPhaseConway(int lunarDay) { if(lunarDay<=28) { if(lunarDay>=24) { return MoonPhase.WANING_CRESCENT; } if(lunarDay>=22) { return MoonPhase.THIRD_QUARTER; } if(lunarDay>=17) { return MoonPhase.WANING_GIBBOUS; } if(lunarDay>=14) { return MoonPhase.FULL_MOON; } if(lunarDay>=9) { return MoonPhase.WAXING_GIBBOUS; } if(lunarDay>=7) { return MoonPhase.FIRST_QUARTER; } if(lunarDay>=2) { return MoonPhase.WAXING_CRESCENT; } } return MoonPhase.NEW_MOON; //0,1,29 }
E o código da lógica:
public static int getLunarDayConway(LocalDateTime ldt) { var year = ldt.getYear(); var month = ldt.getMonthValue(); var day = ldt.getDayOfMonth(); if(year < 1900 || year >= 2100) throw new RuntimeException("Date must be greater than 1900 and less than 2100"); var centS = -4.0; if(year > 2000) { centS = -8.3; } var lastTwoDigits = year%100.0; double vl = lastTwoDigits % 19; if(vl > 9) { vl-=19.0; } vl*=11.0; vl%=30; vl+=centS; vl+=month+day; if(month<3) { vl+=2; } vl = Math.round(vl)%30; return (int)((vl < 0) ? vl+30 : vl); }
Da linha 7 a 17 é o cálculo do valor referente ao ano, que no nosso caso (2018) é 11. E na linha 18 é a soma que fazemos do mês e do dia para descobrir o dia lunar.
Estou pesquisando sobre a possibilidade da terra estar com a rotação e translação mais rápida desde 1900 , Já podemos estar em dez anos ou mais de aditamento deste relógio! E os governos do mundo estão usando o horário de verão para jogar com o tempo esconder e confundir o povo.
Oi Thiago e como proceder quando o valor dá maior que 29?
exemplo: como saber a lua dia 29/12/2020?
Vc subtrai 29.
Para o ano de 2020 é só você pegar o dia+mês+3.
Hoje é dia 11/08/2020, então 11+8+3=22 (quarto minguante).
Para o seu exemplo: 29+12+3=44. Como é maior que 29, é só remover 29 --> 44-29=15, portanto, Lua Cheia!