-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.lua
More file actions
98 lines (84 loc) · 4.12 KB
/
Copy pathmain.lua
File metadata and controls
98 lines (84 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
local function getMoonPhase(year, month, day) --function to calculate the moon phase based on the provided date
-- Known New Moon reference point: January 6, 2000
local refYear = 2000 --new moon after new year 2000
local refMonth = 1
local refDay = 6
-- Synodic month (days it takes to complete a full lunar cycle)
local synodicMonth = 29.5305882 --in days
-- Convert Gregorian date to Julian Day (approximate)
if month < 3 then
year = year - 1
month = month + 12
end
month = month + 1
local c = 365.25 * year --year in days
local e = math.floor(30.6 * month) --month in days
local julianDays = c + e + day - 694039.09 --Julian days
-- Calculate days elapsed since the reference new moon
local daysElapsed = julianDays % synodicMonth --days since the last new moon
-- Percentage of the lunar cycle completed (0.0 to 1.0)
local percent = daysElapsed / synodicMonth --percentage of the lunar cycle completed
-- Map the cycle to an 8-phase index (0-7)
local phaseIndex = math.floor((daysElapsed / synodicMonth) * 8 + 0.5) % 8
local phaseNames = { --moon phase names corresponding to the 8-phase indexes
"New Moon",
"Waxing Crescent",
"First Quarter",
"Waxing Gibbous",
"Full Moon",
"Waning Gibbous",
"Last Quarter",
"Waning Crescent"
}
return {
percent = percent,
index = phaseIndex,
name = phaseNames[phaseIndex + 1],
age = daysElapsed
}
end
local function promptNumber(message, default, min, max) --prompt user for a number with default and range validation
while true do
io.write(string.format("%s [%d]: ", message, default))
local input = io.read() --read user input
-- Use default if user just hits Enter
if input == "" then return default end
local num = tonumber(input) --convert input to number
if num and num >= min and num <= max then --clamp the number to the specified range (min to max)
return num
end
print(string.format("Invalid entry. Please enter a number between %d and %d.", min, max)) --prompt user again if input is invalid
end
end
local year = tonumber(arg[1]) --parse command line arguments for year, month, and day
local month = tonumber(arg[2])
local day = tonumber(arg[3])
if not year or not month or not day then --if any of the date components are missing, prompt the user for input
print("--- Moon Phase Calculator ---")
print("Press Enter to accept the current date defaults.\n")
local today = os.date("*t")
year = promptNumber("Enter Year", today.year, 1970, 2100) --prompt date input with current date as default
month = promptNumber("Enter Month", today.month, 1, 12)
-- Basic max day validation based on month
local max_days = 31
if month == 4 or month == 6 or month == 9 or month == 11 then
max_days = 30
elseif month == 2 then
-- Leap year check
if (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) then max_days = 29 else max_days = 28 end
end
day = promptNumber("Enter Day", today.day, 1, max_days)
end
local date = { year = year, month = month, day = day }
if not year or not month or not day then --if no valid date is provided, default to today's date
print("No valid date provided. Defaulting to today's date.")
local current_date = os.date("*t")
year = tonumber(current_date.year)
month = tonumber(current_date.month)
day = tonumber(current_date.day)
date = { year = year, month = month, day = day }
end
local currentPhase = getMoonPhase(date.year, date.month, date.day) --get the moon phase for the provided date
print("Current Phase: " .. currentPhase.name) --current moon phase name
print("Cycle Progress: " .. string.format("%.2f%%", currentPhase.percent * 100) .. "%") --current moon cycle progress as a percentage
print("Moon Age: " .. string.format("%.2f", currentPhase.age) .. " days") --current moon age in days