Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consider adding multiple language, and next new moon/full moon? Here is my code #43

Open
talpx0 opened this issue Mar 4, 2024 · 1 comment

Comments

@talpx0
Copy link

talpx0 commented Mar 4, 2024

export function calculateMoonPhase(currentDate: Date): number {
  const newMoonDate = new Date(Date.UTC(2019, 0, 6, 1, 28, 0)); // Reference New Moon date
  const lunarCycleLength = 29.53; // Average length of the lunar cycle in days
  const diffInDays = (currentDate.getTime() - newMoonDate.getTime()) / (1000 * 3600 * 24);
  const moonPhase = (diffInDays % lunarCycleLength) / lunarCycleLength;
  return moonPhase;
}


export function estimateNextMoonPhases(currentDate: Date): { nextNewMoon: string, nextFullMoon: string} {
  const currentMoonPhase = calculateMoonPhase(currentDate);
  const lunarCycleLength = 29.53; // Average length of the lunar cycle in days

  let daysUntilNextNewMoon = lunarCycleLength * (1 - currentMoonPhase);
  if (currentMoonPhase >= 0 && currentMoonPhase < 0.5) {
      daysUntilNextNewMoon = lunarCycleLength * (0.5 - currentMoonPhase);
  }

  let daysUntilNextFullMoon = lunarCycleLength * (0.5 - currentMoonPhase);

  if (currentMoonPhase >= 0.5) {
      daysUntilNextFullMoon = lunarCycleLength * (1 - currentMoonPhase) + (lunarCycleLength / 2);
  }

  const nextNewMoon = formatMMDDDate(new Date(currentDate.getTime() + daysUntilNextNewMoon * 24 * 3600 * 1000));
  const nextFullMoon = formatMMDDDate(new Date(currentDate.getTime() + daysUntilNextFullMoon * 24 * 3600 * 1000));
  return { nextNewMoon, nextFullMoon };
}


export function getMoonPhaseName(moonPhase: number): string {
  if(moonPhase < 0.03 || moonPhase > 0.97) {
      return "NewMoon";
  } else if(moonPhase < 0.22) {
      return "WaxingCrescent";
  } else if(moonPhase < 0.28) {
      return "FirstQuarter";
  } else if(moonPhase < 0.47) {
      return "WaxingGibbous";
  } else if(moonPhase < 0.53) {
      return "FullMoon";
  } else if(moonPhase < 0.72) {
      return "WaningGibbous";
  } else if(moonPhase < 0.78) {
      return "LastQuarter";
  } else {
      return "WaningCrescent";
  }
}


export function getMoonPhasesForPeriod(currentDate: Date = new Date()): MoonPhase[] {
    const todayMoonPhaseNumber = calculateMoonPhase(currentDate);
    const todayMoonPhaseName = getMoonPhaseName(todayMoonPhaseNumber);
    const { nextNewMoon, nextFullMoon } = estimateNextMoonPhases(currentDate);
  
    const today: MoonPhase = {
      date: formatMMDDDate(currentDate),
      moonPhaseIcon: MoonPhaseIcons[todayMoonPhaseName],
      name: todayMoonPhaseName,
    };
  
    const nextNewMoonPhase: MoonPhase = {
      date: nextNewMoon,
      moonPhaseIcon: MoonPhaseIcons["NewMoon"],
      name: "NewMoon",
    };
  
    const nextFullMoonPhase: MoonPhase = {
      date: nextFullMoon,
      moonPhaseIcon: MoonPhaseIcons["FullMoon"],
      name: "FullMoon",
    };
  
    // Determine the sequence based on current phase
    let phases: MoonPhase[];
    if (todayMoonPhaseNumber < 0.5) {
      // Today -> Next Full Moon -> Next New Moon
      phases = [today, nextFullMoonPhase, nextNewMoonPhase];
    } else {
      // Today -> Next New Moon -> Next Full Moon
      phases = [today, nextNewMoonPhase, nextFullMoonPhase];
    }
  
    return phases;
}
@jasonsturges
Copy link
Owner

Appreciate sharing the ideas and implementation.

Internationalization support was something I had considered based on the lunar phase enumeration, but adds a hefty amount of complexity.

Any i18n implementation and corresponding translations would be local to that project.

Similar requests for next cycles have been made, in #30, and pull request in #17.

My formula has a small margin of error that I never had time to resolve. There are some other aspects in regards to how this library handles time windows versus events.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants