Created
June 14, 2023 11:36
-
-
Save BenMakesGames/19d5a1155ea3ef8fa0b816f16cbabeae to your computer and use it in GitHub Desktop.
DateTimeOffset extension methods for computing the current phase of the moon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class DateTimeOffsetExtensions | |
{ | |
private const double MoonCycleLength = 29.53058868; | |
public static MoonPhase ComputeMoonPhase(this DateTimeOffset dt) | |
{ | |
return dt.GetMoonAge() switch | |
{ | |
< 1.84566 => MoonPhase.NewMoon, | |
< 5.53699 => MoonPhase.WaxingCrescent, | |
< 9.22831 => MoonPhase.FirstQuarter, | |
< 12.91963 => MoonPhase.WaxingGibbous, | |
< 16.61096 => MoonPhase.FullMoon, | |
< 20.30228 => MoonPhase.WaningGibbous, | |
< 23.99361 => MoonPhase.ThirdQuarter, | |
< 27.68493 => MoonPhase.WaningCrescent, | |
_ => MoonPhase.NewMoon | |
}; | |
} | |
public static long GetJulianDay(this DateTimeOffset dt) | |
{ | |
var year = dt.Year; | |
var month = dt.Month; | |
var day = dt.Day; | |
if (month < 3) | |
{ | |
month += 12; | |
year -= 1; | |
} | |
return day + (153 * month - 457) / 5 + 365 * year + (year / 4) - (year / 100) + (year / 400) + 1721119; | |
} | |
/// <summary> | |
/// Returns the age of the moon in days. (0 = new moon, 14ish = full moon) | |
/// </summary> | |
public static double GetMoonAge(this DateTimeOffset dt) | |
{ | |
var julianDay = dt.GetJulianDay(); | |
var interpolatedPhase = (julianDay - 2451550.1) / MoonCycleLength; | |
// normalize interpolated phase to be between 0 and 1: | |
interpolatedPhase -= Math.Floor(interpolatedPhase); | |
if(interpolatedPhase < 0) | |
interpolatedPhase++; | |
return interpolatedPhase * MoonCycleLength; | |
} | |
} | |
public enum MoonPhase | |
{ | |
NewMoon, | |
WaxingCrescent, | |
FirstQuarter, | |
WaxingGibbous, | |
FullMoon, | |
WaningGibbous, | |
ThirdQuarter, | |
WaningCrescent | |
} | |
public static class MoonPhaseExtensions | |
{ | |
public static string ToEmoji(this MoonPhase phase) => phase switch | |
{ | |
MoonPhase.NewMoon => "π", | |
MoonPhase.WaxingCrescent => "π", | |
MoonPhase.FirstQuarter => "π", | |
MoonPhase.WaxingGibbous => "π", | |
MoonPhase.FullMoon => "π", | |
MoonPhase.WaningGibbous => "π", | |
MoonPhase.ThirdQuarter => "π", | |
MoonPhase.WaningCrescent => "π", | |
_ => throw new ArgumentOutOfRangeException(nameof(phase), phase, null) | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment