Guest User

Untitled

a guest
Apr 29th, 2026
27
0
Never
5
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.95 KB | None | 0 0
  1. # Parses niph's lunations calculator at https://github.com/dlebansais/PgMoon/blob/master/PgMoon-Plugin/PhaseCalculator.Lunations.cs
  2. # this is itself from PG code shared by Citan and should be 100% accurate
  3. # the output is a TSV of dates (starting at the relatively arbitrary 4/11/2021)
  4.  
  5. # requires python 3.9+. On Windows machines, it also depends on an up-to-date tzdata package
  6. # (python -m pip install tzdata)
  7.  
  8. import datetime
  9. import re
  10. from zoneinfo import ZoneInfo
  11. from typing import IO
  12.  
  13.  
  14. LINEMATCH_RE = re.compile(
  15.     r'new\(\) \{ Index = (?P<index>\d+), NewMoon = ParseDateTime\("(?P<new_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), WaxingCrescentMoon = ParseDateTime\("(?P<waxing_crescent_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), QuarterMoon = ParseDateTime\("(?P<quarter_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), WaxingGibbousMoon = ParseDateTime\("(?P<waxing_gibbous_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), FullMoon = ParseDateTime\("(?P<full_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), WaningGibbousMoon = ParseDateTime\("(?P<waning_gibbous_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), LastQuarterMoon = ParseDateTime\("(?P<last_quarter_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), WaningCrescentMoon = ParseDateTime\("(?P<waning_crescent_moon>\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)"\), Duration = ParseTimeSpan\("(?P<duration>\d+\.\d+):00:00"\) },'
  16. )
  17. IGNORE = {
  18.     "namespace PgMoon;",
  19.     "",
  20.     "/// <summary>",
  21.     "/// Represents a moon phase calculator.",
  22.     "/// </summary>",
  23.     "public partial class PhaseCalculator",
  24.     "{",
  25.     "private static readonly Lunation[] LunationTable =",
  26.     "[",
  27.     "];",
  28.     "}",
  29. }
  30. SKIP_TO_THIS_DATE = datetime.datetime(2021, 4, 11, tzinfo=datetime.UTC)
  31.  
  32. lunation_to_sheet = (
  33.     ("new_moon", "New"),
  34.     ("waxing_crescent_moon", "Waxing Crescent"),
  35.     ("quarter_moon", "First Quarter"),
  36.     ("waxing_gibbous_moon", "Waxing Gibbous"),
  37.     ("full_moon", "Full"),
  38.     ("waning_gibbous_moon", "Waning Gibbous"),
  39.     ("last_quarter_moon", "Third Quarter"),
  40.     ("waning_crescent_moon", "Waning Crescent"),
  41. )
  42.  
  43.  
  44. def main(f: IO, tformat: str):
  45.     last_phase_dt, last_phase_sheet_name = None, None
  46.     for line in f.readlines():
  47.         stripped = line.strip()
  48.         if stripped in IGNORE:
  49.             continue
  50.         if lunation := LINEMATCH_RE.match(stripped):
  51.             idx = int(lunation["index"])
  52.             # duration = datetime.timedelta(days=float(lunation["duration"]))
  53.             #  ^ also available if needed, the total duration of the lunation
  54.             for phase_idx, phase_sheet_name in lunation_to_sheet:
  55.                 phase_start_dt = (
  56.                     datetime.datetime.strptime(lunation[phase_idx], "%m/%d/%Y %H:%M:%S")
  57.                     .replace(tzinfo=datetime.UTC)
  58.                     .astimezone(tz=ZoneInfo("US/Eastern"))
  59.                 )
  60.  
  61.                 if phase_start_dt < SKIP_TO_THIS_DATE:
  62.                     continue
  63.                 if phase_start_dt.hour != 0:
  64.                     raise Exception(
  65.                         f"{idx=} had phase not at midnight Eastern {phase_idx=},{phase_start_dt=}"
  66.                     )
  67.                 if last_phase_dt:
  68.                     for i in range((phase_start_dt - last_phase_dt).days):
  69.                         print(
  70.                             f"{(last_phase_dt + datetime.timedelta(days=i)).strftime('%#m/%#d/%Y')}\t{last_phase_sheet_name}"
  71.                         )
  72.                 last_phase_dt = phase_start_dt
  73.                 last_phase_sheet_name = phase_sheet_name
  74.         else:
  75.             raise Exception(f"didn't match:\n{stripped}, add to ignore or adjust regex")
  76.  
  77.     assert last_phase_dt
  78.     print(f"{last_phase_dt.strftime(tformat)}\t{last_phase_sheet_name}")
  79.  
  80.  
  81. if __name__ == "__main__":
  82.     import platform
  83.  
  84.     if platform.system() == "Windows":
  85.         format = "%#m/%#d/%Y"
  86.     else:
  87.         format = "%-m/%-d/%Y"
  88.  
  89.     with open("PhaseCalculator.Lunations.cs") as f:
  90.         main(f, format)
  91.  
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment