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

Moon.lunarPhase() anticipating moon phase #19

Open
sperardt opened this issue Jan 31, 2022 · 11 comments
Open

Moon.lunarPhase() anticipating moon phase #19

sperardt opened this issue Jan 31, 2022 · 11 comments
Assignees

Comments

@sperardt
Copy link

Hi Jason! Thanks for creating this library.
I have been using it for a couple of weeks and just noticed that the method Moon.lunarPhase(date); is returning "New Moon" phase on Jan 31, 2022 at 5pm EST. However, New Moon is going to be in effect on Feb 01, 2022 at 12:46 am EST.

@jasonsturges jasonsturges self-assigned this Jan 31, 2022
@jasonsturges
Copy link
Owner

@sperardt Hi, thanks.

Somewhat similar issue as determining when a sunset actually occurs (civil, nautical, or astronomical twilight).

It's a rounding issue, which has confused several people. This chart might help:

Phase Start Event End
New 0 1.84566173161
Waxing Crescent 1.84566173161 3.69132346322 5.53698519483
First Quarter 5.53698519483 7.38264692644 9.22830865805
Waxing Gibbous 9.22830865805 11.07397038966 12.91963212127
Full 12.91963212127 14.76529385288 16.61095558449
Waning Gibbous 16.61095558449 18.4566173161 20.30227904771
Last Quarter 20.30227904771 22.14794077932 23.99360251093
Waning Crescent 23.99360251093 25.83926424254 27.68492597415
New 27.68492597415 29.53058770576

I think the terms "start" and "end" need clarity, but the "event" is the actual moment in time.

So, halfway through the 3.691 days of the phase, it rounds up to the next upcoming cycle.

image

Instead of starting at the moment 0 and lasting until the exact moment of the next phase, it's offset to report the closest event. Once you're closer to the New Moon phase than the previous phase, it rounds to New Moon.

Application here is like reporting current weather, but several people have expressed either confusion or desire for this to work differently. Some are planning around exact moments in time; others seem to want the phase from event to next event.

Any recommendation there as to how you'd like to use / configure this?

@jasonsturges
Copy link
Owner

Design wise, I'd like to keep this simple / functional, but I think it's getting to the point there needs to be some kind of options / params config passed to the functions.

Some kind of:

Moon.function(date, { ...options })

I really like date being the only data model for this, but maybe an options parameter where you could specify:

  • cycleStart: event
  • cycleStart: round

Or something like that here...

@sperardt
Copy link
Author

sperardt commented Feb 2, 2022

Hi @jasonsturges !
Thanks for replying and sorry for not getting back to you yesterday. I had a quite busy day.

Yeah, I thought it could be a rounding issue.

So, I am using the library on an astrological mobile app where I display the moon phase + a little description about the moon phase. And it got my attention since my moon calendar were saying that was still waning crescent but was getting new moon from the library.

Do you know why we are having issues with rounding? I mean, the actual number of decimal places is higher than the ones you listed above? Or it is a Js function you are using that is rounding the number?

@sperardt
Copy link
Author

sperardt commented Feb 2, 2022

Aff.. I sent the previous comment when I wanted to add a new line haha

Moon.function(date, { ...options }) I also prefer having just the date as a parameter, but having a new parameter can be easier to implement and control what type the calculations need to be done. If !{... options} you treat as it is today

@jasonsturges
Copy link
Owner

This operates like a weather app, and rounds on purpose. It will show waning crescent starting 1.85, even though that phase occurs at 3.69 - and will continue to show through 5.54 until the next phase is closer.

Several people have contacted me regarding astrology usage - I'm unsure how the phase is leveraged or calcualted, but someone also pointed out that astrological calendars bounce to a 30th lunar day.

Lunar vs lunisolar calendars align lunar months with the solar year through different intercalation - approximately 29.5 days, although it appears some calendars alternate between 29 and 30 day synodic months to complete one year of 12 lunations.

Here, using the Gregorian calendar, this fraction normalizes years (and leap years) providing accuracy for the next 31,000 years at which point this calculation will be 1-day behind.

Think it's time to alter this library to accept a config payload, and I might make the default to start on the day... I'll get back to you shortly.

@jasonsturges
Copy link
Owner

Think I'm going to change the calculation to report phase at the event, then add a closestPhase() function to retain the original intent of this library - weather station graphics implementation.

Although I still like an options payload context.

Should have this updated in the next couple of days.

@sperardt
Copy link
Author

sperardt commented Feb 8, 2022

Thanks @jasonsturges !

@jasonsturges
Copy link
Owner

Still evaluating whether I like this, and need to run test cycles of the next several days, but I've landed at:

Moon options, in which cycle start at the event in the northern hemisphere:

export type MoonOptions = {
  readonly cycleStart: CycleStart;
  readonly hemisphere: Hemisphere;
};

export const defaultMoonOptionsFactory = (): MoonOptions => ({
  cycleStart: CycleStart.EVENT,
  hemisphere: Hemisphere.NORTHERN,
});

@vedmakk
Copy link

vedmakk commented Feb 14, 2022

Hi, I just stumbled into the same "issue" with something executing before the actual full moon due to how the library behaves. I think your suggestion to provide an options/config param is a good approach and we would be able to switch back and forth between different behaviours (exact or rounding) based on what the needs of different applications are. Happy to help if needed (at least with testing).

@jasonsturges
Copy link
Owner

@sperardt @protyze I've come to the conclusion that presentation concerns need separation from this calculation. As this was originally used to display graphics, there needs to be angle / percentage functions for visual display separate of reported phase.

This is also confounded by primary and intermediary phases.

I'm just going to shift this calculation to align with immediate needs.

Although, I do like the configuration options - that will assist implementing other feedback, but that will come later.

@vedmakk
Copy link

vedmakk commented Feb 16, 2022

That makes sense and people can actually implement their own calculation / phase-mapping using .lunarAgePercent() if they need to – which is what I use now to react more accurate to a specific phase or "age" of the moon in my application. But this follows the whole cycle from new moon to new moon. Maybe a helper method that returns a value between 0 and 1 and expresses how much the moon is "lit" at a specific date. 1 = full, 0 = new, 0.5 is either first or third quarter depending on isWaning(), isWaxing() or lunarPhase().

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

3 participants