Dia 30 de março iniciou o período de Pessach (ou páscoa) judaica. O interessante é que as festas judaicas são calculadas de acordo com as fases da lua e dias lunares, baseado num calendário luni-solar (períodos da lua e sol). Aproveitei o período para aprender um pouco de Java 10 com o uso da declaração var, lambdas e a API de data e hora que foi introduzida no Java 8. Para isso criei um aplicativo que calcula as fases lunares.
A lua passa por todas as suas fases em um período com mais ou menos 29,5 dias, também chamado de lunação. Esse período é conhecido como mês sinódico. É diferente do período que ela circunda a terra (27,3 dias), que é conhecido como mês sideral. Essa diferença é referente ao movimento orbital da Terra em torno do sol.
Para calcular as fases da lua, a ideia é bem simples. É preciso conhecer uma data com lua nova. No exemplo utilizei dia 07 de janeiro de 1970. Como o ciclo é de 29,5 dias, é necessário calcular a diferença entre essas datas e o resto da divisão pelo período sinódico e temos o número de dias lunares que passou à partir de uma lua nova. Pois a cada 29,5 dias temos uma outra lua nova. Ou seja:
DiaLunar = (DiaVerificar - DataDaLuaNova) mod PeriodoSinótico
Para saber o tipo de luas, é só verificar a quantidade de dias do período sinótico (29,5 dias) e dividir pela quantidade de luas (8 no caso), que dá aproximadamente 3,7. Então a cada 3,7 dias temos um novo tipo de lua.
Criei um enum para as fases da lua para ficar melhor organizado o código:
static enum MoonPhase { NEW_MOON, // Nova WAXING_CRESCENT, // Crescente FIRST_QUARTER, // Quarto crescente WAXING_GIBBOUS, // Crescente gibosa FULL_MOON, // Cheia WANING_GIBBOUS, // Minguante gibosa THIRD_QUARTER, // Quarto minguante WANING_CRESCENT; // Minguante }
Criei duas constantes para serem utilizadas posteriormente em outros códigos:
public static final long SYNODIC_PERIOD = 2551442877L; //29.530588854 days public static final LocalDateTime KNOWN_NEW_MOON = LocalDate.of(1970, Month.JANUARY, 7).atStartOfDay();
A lua nova é início do mês para os judeus e é chamada de ראש חודש ou Rosh Chodesh, traduzido como cabeça do mês. Nesse dia se comemora a Festa da Lua Nova, 14 dias após esse dia é lua cheia, e no primeiro mês judaico (Nisan ou Abibe) é onde inicia o Pessach. Para se recuperar o dia lunar, que começa a contar à partir da primeira lua nova do mês, é necessário calcular a diferença entre uma lua nova conhecida e a data a ser verificada e ver o resto da divisão pelo período sinódico:
public static int getLunarDay(LocalDateTime day) { var lunarDay = (int) Duration.ofMillis(Duration.between(KNOWN_NEW_MOON, day).toMillis() % SYNODIC_PERIOD).toDays(); return lunarDay; }
Com isso, para saber a fase atual da lua é só dividir pela diferença de cada lua, que, como dito anteriormente, é de aproximadamente 3,7 dias:
public static MoonPhase getMoonPhase(int lunarDay) { var phaseNum = (int)Math.floor(lunarDay/3.7); return MoonPhase.values()[phaseNum]; }
E para usar os dados utilizei o método main para imprimir a data, o dia lunar e a fase da lua de agora até 1 mês para frente:
public static void main(String[] args) { var now = LocalDateTime.now(); var end = now.plusMonths(1); Stream.iterate(now, date -> date.plusDays(1)) .limit(ChronoUnit.DAYS.between(now, end)) .forEach(MoonUtils::printLunarAnalysis); } private static void printLunarAnalysis(LocalDateTime ldt) { var df = DateTimeFormatter .ofLocalizedDate(FormatStyle.SHORT) .withLocale(new Locale("pt", "br")); var lunarDay = getLunarDay(ldt); var moonPhase = getMoonPhase(lunarDay); System.out.println("Data: " + ldt.format(df)); System.out.println("Dia lunar: " + lunarDay); System.out.println("Fase da lua (provável): " + moonPhase); System.out.println(); }
Nas linhas 4 a 6 estou utilizando expressões lambda junto com a interação do Java 8 e method reference. A inferência da declaração var do Java 10, que está em todo código, também funciona adequadamente. Com isso, aprendemos utilizar alguns dos novos recursos do Java e, caso você necessite em alguma aplicação ou calendário, conseguimos descobrir qual fase da lua estamos.
[…] 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 lunar 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. […]