A Windows systray application that displays the current lunar phase.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
4.3 KiB

using System;
using System.Collections.Generic;
namespace LunaWin
{
class LunaCalc
{
/// <summary>
/// get array of lunar phases
/// </summary>
public static List<LunaPhase> Phases
{
get { return _phases; }
}
/// <summary>
/// array of lunar phases
/// </summary>
private static List<LunaPhase> _phases = new List<LunaPhase>
{
new LunaPhase() {
Id = "new",
Name = "New Moon",
Start = 0,
End = 1,
Icon = "🌑",
Utf = "1F311"
},
new LunaPhase() {
Id = "waxc",
Name = "Waxing Crescent",
Start = 1,
End = 6.38264692644,
Icon = "🌒",
Utf = "1F312"
},
new LunaPhase() {
Id = "firstq",
Name = "First Quarter",
Start = 6.38264692644,
End = 8.38264692644,
Icon = "🌓",
Utf = "1F313"
},
new LunaPhase() {
Id = "waxg",
Name = "Waxing Gibbous",
Start = 8.38264692644,
End = 13.76529385288,
Icon = "🌔",
Utf = "1F314"
},
new LunaPhase() {
Id = "full",
Name = "Full Moon",
Start = 13.76529385288,
End = 15.76529385288,
Icon = "🌕",
Utf = "1F315"
},
new LunaPhase() {
Id = "wang",
Name = "Waning Gibbous",
Start = 15.76529385288,
End = 21.14794077932,
Icon = "🌖",
Utf = "1F316"
},
new LunaPhase() {
Id = "lastq",
Name = "Last Quarter",
Start = 21.14794077932,
End = 23.14794077932,
Icon = "🌗",
Utf = "1F317"
},
new LunaPhase() {
Id = "wanc",
Name = "Waning Crescent",
Start = 23.14794077932,
End = 28.53058770576,
Icon = "🌘",
Utf = "1F318"
},
new LunaPhase() {
Id = "new2",
Name = "New Moon",
Start = 28.53058770576,
End = 29.53058770576,
Icon = "🌑",
Utf = "1F311"
},
new LunaPhase() {
Id = "default",
Name = "Failed to calculate.",
Icon = "🌙",
Utf = "1F319"
}
};
/// <summary>
/// get lunar constant (total days in a lunar phase)
/// </summary>
public static double LunarDays
{
get { return _lunarDays; }
}
/// <summary>
/// lunar constant (total days in a lunar phase)
/// </summary>
private static double _lunarDays = 29.53058770576;
/// <summary>
/// get total seconds in a lunar phase
/// </summary>
public static double LunarSecs
{
get { return _lunarSecs; }
}
/// <summary>
/// total seconds in a lunar phase
/// </summary>
private static double _lunarSecs = LunarDays * (24 * 60 * 60);
/// <summary>
/// get datetime of first full moon in 2000
/// </summary>
public static DateTime BaseDate
{
get { return _baseDate; }
}
/// <summary>
/// datetime of first full moon in 2000
/// </summary>
// private static DateTime _baseDate = DateTime.Parse("2000-01-6 18:14:00Z");
private static DateTime _baseDate = new DateTime(2000, 01, 6, 18, 14, 00, DateTimeKind.Utc);
public LunaPhase CurrentPhase(DateTime inputDate = default)
{
LunaPhase currPhase = new LunaPhase();
DateTime currDate = inputDate == default ? DateTime.UtcNow : inputDate.ToUniversalTime();
// get total seconds between current and base datetime
double totalSecs = (currDate - BaseDate).TotalSeconds;
// make sure TotalSecs is positive
totalSecs = totalSecs < 0 ? totalSecs * -1 : totalSecs;
// calculate total seconds into current lunar cycle
double CurrSecs = totalSecs % LunarSecs;
// current position in lunar cycle
double CurrFrac = CurrSecs / LunarSecs;
// days into current cycle
double CurrDays = CurrFrac * LunarDays;
// search phase array for CurrDays value to fall between start and finish doubles
currPhase = Phases.Find(p => CurrDays >= p.Start && CurrDays <= p.End);
return currPhase;
}
}
/// <summary>
/// creates a single lunar phase
/// </summary>
class LunaPhase
{
/// <summary>
/// lunar phase shortname
/// </summary>
public string Id;
/// <summary>
/// lunar phase friendly name
/// </summary>
public string Name;
/// <summary>
/// start of lunar phase
/// </summary>
public double Start;
/// <summary>
/// end of lunar phase
/// </summary>
public double End;
/// <summary>
/// emoji icon
/// </summary>
public string Icon;
/// <summary>
/// unicode value
/// </summary>
public string Utf;
}
}