-
-
Save datatypevoid/f4dd1f6439feaa588bb2aaf4f8f4361f to your computer and use it in GitHub Desktop.
export { EMoonPhase, EMoonPhaseName, MOON_PHASE_NAMES, moonPhase } | |
const { round, trunc: truncate } = Math | |
enum EMoonPhase { | |
New = 0, | |
WaxingCrescent, | |
QuarterMoon, | |
WaxingGibbous, | |
Full, | |
WaningGibbous, | |
LastQuarter, | |
WaningCrescent, | |
COUNT = 8 | |
} | |
enum EMoonPhaseName { | |
New = 'New', | |
WaxingCrescent = 'Waxing Crescent', | |
QuarterMoon = 'Quarter Moon', | |
WaxingGibbous = 'Waxing Gibbous', | |
Full = 'Full', | |
WaningGibbous = 'Waning Gibbous', | |
LastQuarter = 'Last Quarter', | |
WaningCrescent = 'Waning Crescent', | |
COUNT = 'COUNT' | |
} | |
const MOON_PHASE_NAMES: EMoonPhaseName[] = [ // Look-up table. | |
EMoonPhaseName.New, | |
EMoonPhaseName.WaxingCrescent, | |
EMoonPhaseName.QuarterMoon, | |
EMoonPhaseName.WaxingGibbous, | |
EMoonPhaseName.Full, | |
EMoonPhaseName.WaningGibbous, | |
EMoonPhaseName.LastQuarter, | |
EMoonPhaseName.WaningCrescent, | |
EMoonPhaseName.COUNT | |
] | |
// Reference: http://individual.utoronto.ca/kalendis/lunar/#FALC | |
// Also known as a synodic month. | |
// An average synodic month takes 29 days, 12 hours, 44 minutes, 3 seconds. | |
const LUNAR_CYCLE = 29.53058770576 | |
const DAYS_PER_YEAR = 365.25 | |
const DAYS_PER_MONTH = 30.6 | |
// Number of days since known new moon on `1900-01-01`. | |
const DAYS_SINCE_NEW_MOON_1900_01_01 = 694039.09 | |
interface IResult { name: EMoonPhaseName, phase: EMoonPhase } | |
// Ported from `http://www.voidware.com/moon_phase.htm`. | |
function moonPhase (date: Date = new Date()): IResult { | |
// let year = date.getYear() | |
let year: number = date.getFullYear() | |
let month: number = date.getMonth() | |
const day: number = date.getDay() | |
if (month < 3) { | |
year-- | |
month += 12 | |
} | |
month++ | |
let totalDaysElapsed: number = DAYS_PER_YEAR | |
* year | |
+ DAYS_PER_MONTH | |
* month | |
+ day | |
- DAYS_SINCE_NEW_MOON_1900_01_01 | |
totalDaysElapsed /= LUNAR_CYCLE // Divide by the lunar cycle. | |
let phase: number = truncate(totalDaysElapsed) | |
/* | |
Subtract integer part to leave fractional part of original | |
`totalDaysElapsed`. | |
*/ | |
totalDaysElapsed -= phase | |
// Scale fraction from `0-8`. | |
phase = round(totalDaysElapsed * 8) | |
phase = phase & 7 // `0` and `8` are the same so turn `8` into `0`. | |
if (phase >= EMoonPhase.COUNT || phase < EMoonPhase.New) | |
throw new Error(`Invalid moon phase: ${phase}`) | |
return { phase, name: MOON_PHASE_NAMES[phase] } | |
} |
Not sure about typescript, but if same as JS it looks to be some errors:
Date.prototype.getDay()
returns day of week, not day of month, use.getDate()
Date.prototype.getMonth()
is zero based, use.getMonth() + 1
DAYS_SINCE_NEW_MOON_1900_01_01
- not sure what that is ( 694039.09).
It is close to days from year 0 to March 1900 - more precisely Tuesday March 20th 1900, or Thursday 21st if one count form year 1. Wednesday 20th of March 1901 had a new moon at 12:52 UTC+0, but that is not 1st of January ... 1st of January 1900 had a new-moon at 13:51 (if I remember correctly), 693595 or 693597 days from 001-01-01 or 693961 MySQL TO_DAYS from 0000-00-00.
Does it have something to do with Julian/Gregorian/Roman calendars?
Here is a revised version, which works (also, added icons and an override)
export {
EMoonPhase,
moonIcons,
moonPhaseAlt,
EMoonPhaseName,
MOON_PHASE_NAMES,
moonPhase,
}
const { round, trunc: truncate } = Math
enum EMoonPhase {
New = 0,
WaxingCrescent,
QuarterMoon,
WaxingGibbous,
Full,
WaningGibbous,
LastQuarter,
WaningCrescent,
COUNT = 8,
}
const moonIcons: [
New: string,
WaxingCrescent: string,
QuarterMoon: string,
WaxingGibbous: string,
Full: string,
WaningGibbous: string,
LastQuarter: string,
WaningCrescent: string
] = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"]
enum EMoonPhaseName {
New = "New",
WaxingCrescent = "Waxing Crescent",
QuarterMoon = "Quarter Moon",
WaxingGibbous = "Waxing Gibbous",
Full = "Full",
WaningGibbous = "Waning Gibbous",
LastQuarter = "Last Quarter",
WaningCrescent = "Waning Crescent",
COUNT = "COUNT",
}
const MOON_PHASE_NAMES: EMoonPhaseName[] = [
// Look-up table.
EMoonPhaseName.New,
EMoonPhaseName.WaxingCrescent,
EMoonPhaseName.QuarterMoon,
EMoonPhaseName.WaxingGibbous,
EMoonPhaseName.Full,
EMoonPhaseName.WaningGibbous,
EMoonPhaseName.LastQuarter,
EMoonPhaseName.WaningCrescent,
EMoonPhaseName.COUNT,
]
// Reference: http://individual.utoronto.ca/kalendis/lunar/#FALC
// Also known as a synodic month.
// An average synodic month takes 29 days, 12 hours, 44 minutes, 3 seconds.
const LUNAR_CYCLE = 29.5305882 // 29.53058770576
const DAYS_PER_YEAR = 365.25
const DAYS_PER_MONTH = 30.6
// Number of days since known new moon on `1900-01-01`.
const DAYS_SINCE_NEW_MOON_1900_01_01 = 694039.09
interface IResult {
name: EMoonPhaseName
phase: EMoonPhase
icon: string
}
function moonPhaseAlt(date: Date = new Date()): IResult {
// let year = date.getYear()
let year: number = date.getFullYear()
let month: number = date.getMonth() + 1
const day: number = date.getDate()
return moonPhase(year, month, day)
}
// Ported from `http://www.voidware.com/moon_phase.htm`.
function moonPhase(year: number, month: number, day: number): IResult {
if (month < 3) {
year--
month += 12
}
month += 1
let totalDaysElapsed: number =
DAYS_PER_YEAR * year +
DAYS_PER_MONTH * month +
day -
DAYS_SINCE_NEW_MOON_1900_01_01
totalDaysElapsed /= LUNAR_CYCLE // Divide by the lunar cycle.
let phase: number = truncate(totalDaysElapsed)
/*
Subtract integer part to leave fractional part of original
`totalDaysElapsed`.
*/
totalDaysElapsed -= phase
// Scale fraction from `0-8`.
phase = round(totalDaysElapsed * 8)
if (phase >= 8) phase = 0 // `0` and `8` are the same so turn `8` into `0`.
if (phase >= EMoonPhase.COUNT || phase < EMoonPhase.New)
throw new Error(`Invalid moon phase: ${phase}`)
return { phase, name: MOON_PHASE_NAMES[phase], icon: moonIcons[phase] }
}
Here is a revised version, which works (also, added icons and an override)
export { EMoonPhase, moonIcons, moonPhaseAlt, EMoonPhaseName, MOON_PHASE_NAMES, moonPhase, } const { round, trunc: truncate } = Math enum EMoonPhase { New = 0, WaxingCrescent, QuarterMoon, WaxingGibbous, Full, WaningGibbous, LastQuarter, WaningCrescent, COUNT = 8, } const moonIcons: [ New: string, WaxingCrescent: string, QuarterMoon: string, WaxingGibbous: string, Full: string, WaningGibbous: string, LastQuarter: string, WaningCrescent: string ] = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"] enum EMoonPhaseName { New = "New", WaxingCrescent = "Waxing Crescent", QuarterMoon = "Quarter Moon", WaxingGibbous = "Waxing Gibbous", Full = "Full", WaningGibbous = "Waning Gibbous", LastQuarter = "Last Quarter", WaningCrescent = "Waning Crescent", COUNT = "COUNT", } const MOON_PHASE_NAMES: EMoonPhaseName[] = [ // Look-up table. EMoonPhaseName.New, EMoonPhaseName.WaxingCrescent, EMoonPhaseName.QuarterMoon, EMoonPhaseName.WaxingGibbous, EMoonPhaseName.Full, EMoonPhaseName.WaningGibbous, EMoonPhaseName.LastQuarter, EMoonPhaseName.WaningCrescent, EMoonPhaseName.COUNT, ] // Reference: http://individual.utoronto.ca/kalendis/lunar/#FALC // Also known as a synodic month. // An average synodic month takes 29 days, 12 hours, 44 minutes, 3 seconds. const LUNAR_CYCLE = 29.5305882 // 29.53058770576 const DAYS_PER_YEAR = 365.25 const DAYS_PER_MONTH = 30.6 // Number of days since known new moon on `1900-01-01`. const DAYS_SINCE_NEW_MOON_1900_01_01 = 694039.09 interface IResult { name: EMoonPhaseName phase: EMoonPhase icon: string } function moonPhaseAlt(date: Date = new Date()): IResult { // let year = date.getYear() let year: number = date.getFullYear() let month: number = date.getMonth() + 1 const day: number = date.getDate() return moonPhase(year, month, day) } // Ported from `http://www.voidware.com/moon_phase.htm`. function moonPhase(year: number, month: number, day: number): IResult { if (month < 3) { year-- month += 12 } month += 1 let totalDaysElapsed: number = DAYS_PER_YEAR * year + DAYS_PER_MONTH * month + day - DAYS_SINCE_NEW_MOON_1900_01_01 totalDaysElapsed /= LUNAR_CYCLE // Divide by the lunar cycle. let phase: number = truncate(totalDaysElapsed) /* Subtract integer part to leave fractional part of original `totalDaysElapsed`. */ totalDaysElapsed -= phase // Scale fraction from `0-8`. phase = round(totalDaysElapsed * 8) if (phase >= 8) phase = 0 // `0` and `8` are the same so turn `8` into `0`. if (phase >= EMoonPhase.COUNT || phase < EMoonPhase.New) throw new Error(`Invalid moon phase: ${phase}`) return { phase, name: MOON_PHASE_NAMES[phase], icon: moonIcons[phase] } }
🔥 🚀 👍 Love the icon addition.
This is awesome, thank you. I cleaned up some of the typescript, improved some variable names, and added the lunary day:
export const MOON_ICONS = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"] as const;
export const MOON_PHASE_NAMES = [
"New",
"Waxing Crescent",
"Quarter Moon",
"Waxing Gibbous",
"Full",
"Waning Gibbous",
"Last Quarter",
"Waning Crescent",
] as const;
/**
* Reference: http://individual.utoronto.ca/kalendis/lunar/#FALC - Also known as a synodic month.
* An average synodic month takes 29 days, 12 hours, 44 minutes, 3 seconds.
*/
export const LUNAR_CYCLE = 29.5305882; // 29.53058770576
export const DAYS_PER_YEAR = 365.25;
export const DAYS_PER_MONTH = 30.6;
/** The number of days between `0 AD` and the new moon on `1900-01-01`. */
export const NEW_MOON_REFERENCE = 694039.09;
// Ported from `http://www.voidware.com/moon_phase.htm`.
export const getMoonPhase = (date: Date = new Date()) => {
let year = date.getFullYear();
let month = date.getMonth() + 1;
const day = date.getDate();
if (month < 3) {
year -= 1;
month += 12;
}
month += 1;
const daysSinceZeroAd = DAYS_PER_YEAR * year + DAYS_PER_MONTH * month + day;
const daysSinceNewMoonReference = daysSinceZeroAd - NEW_MOON_REFERENCE;
const numberOfCyclesSinceReference = daysSinceNewMoonReference / LUNAR_CYCLE;
const percentageOfCycleComplete = numberOfCyclesSinceReference - Math.trunc(numberOfCyclesSinceReference);
// Scale fraction from 0 to 8
let phase = Math.round(percentageOfCycleComplete * 8);
if (phase >= 8) phase = 0; // `0` and `8` are the same so turn `8` into `0`.
// Scale fraction from 0 to `LUNAR_CYCLE`
const lunarDay = Math.round(percentageOfCycleComplete * LUNAR_CYCLE);
if (!MOON_PHASE_NAMES[phase]) throw new Error(`Invalid moon phase: ${phase}`);
return { lunarDay, name: MOON_PHASE_NAMES[phase], icon: MOON_ICONS[phase] };
};
This is awesome, thank you. I cleaned up some of the typescript, improved some variable names, and added the lunary day:
export const MOON_ICONS: [ New: string, WaxingCrescent: string, QuarterMoon: string, WaxingGibbous: string, Full: string, WaningGibbous: string, LastQuarter: string, WaningCrescent: string ] = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"]; export const MOON_PHASE_NAMES = [ "New", "Waxing Crescent", "Quarter Moon", "Waxing Gibbous", "Full", "Waning Gibbous", "Last Quarter", "Waning Crescent", ] as const; /** * Reference: http://individual.utoronto.ca/kalendis/lunar/#FALC - Also known as a synodic month. * An average synodic month takes 29 days, 12 hours, 44 minutes, 3 seconds. */ export const LUNAR_CYCLE = 29.5305882; // 29.53058770576 export const DAYS_PER_YEAR = 365.25; export const DAYS_PER_MONTH = 30.6; /** The number of days between `0 AD` and the new moon on `1900-01-01`. */ export const NEW_MOON_REFERENCE = 694039.09; // Ported from `http://www.voidware.com/moon_phase.htm`. export const getMoonPhase = (date: Date = new Date()) => { let year = date.getFullYear(); let month = date.getMonth() + 1; const day = date.getDate(); if (month < 3) { year -= 1; month += 12; } month += 1; const daysSinceZeroAd = DAYS_PER_YEAR * year + DAYS_PER_MONTH * month + day; const daysSinceNewMoonReference = daysSinceZeroAd - NEW_MOON_REFERENCE; const numberOfCyclesSinceReference = daysSinceNewMoonReference / LUNAR_CYCLE; const percentageOfCycleComplete = numberOfCyclesSinceReference - Math.trunc(numberOfCyclesSinceReference); // Scale fraction from 0 to 8 let phase = Math.round(percentageOfCycleComplete * 8); if (phase >= 8) phase = 0; // `0` and `8` are the same so turn `8` into `0`. // Scale fraction from 0 to `LUNAR_CYCLE` const lunarDay = Math.round(percentageOfCycleComplete * LUNAR_CYCLE); if (!MOON_PHASE_NAMES[phase]) throw new Error(`Invalid moon phase: ${phase}`); return { lunarDay, name: MOON_PHASE_NAMES[phase], icon: MOON_ICONS[phase] }; };
hey Eric can you send your emil or WhatsApp
GitHub doesn't allow users to share emails. What's up?
GitHub doesn't allow users to share emails. What's up?
i think her can not connect. i tried to inter to your website but dont work?
can you develop , calculate moon manzel?
Yes, I think that wouldn't be too hard to add with some investigation into calculating lunar degrees.
how can have contact with you?
sent you a repo collab
Yes, I think that wouldn't be too hard to add with some investigation into calculating lunar degrees.
how contact with you
You're cluttering up the gist man. I sent you a repo collaboration invite so you can contact me through the codebase.
You're cluttering up the gist man. I sent you a repo collaboration invite so you can contact me through the codebase.
i didnt have and received any thing
i accept it.now what?
This is my last message here. Check the README. My email is there.
Alright thanks!