From 116f908662204a0e91897cb701987c036f42985f Mon Sep 17 00:00:00 2001 From: spiders Date: Fri, 24 Jan 2025 18:13:28 +0000 Subject: [PATCH] Delete foxtime.lua --- foxtime.lua | 620 ---------------------------------------------------- 1 file changed, 620 deletions(-) delete mode 100644 foxtime.lua diff --git a/foxtime.lua b/foxtime.lua deleted file mode 100644 index 12ca27d..0000000 --- a/foxtime.lua +++ /dev/null @@ -1,620 +0,0 @@ -#!/usr/bin/lua - ---[[ foxtime version ᚢ.0 please read until the next 🐇 - -foxclock is a fuzzy clock for fuzzy aminals. it uses a heretical take on the -ancient method of unequal, or seasonal, hours which was displaced by the -unceasing tide of standardization, where the daylight and the nightdark are each -divided into 7 sections (not the traditional 12), so that the length of a day -hour and a night hour are only the same on equinoxes. summerday hours are long -and lazy, winterday hours are fleeting and glittering. - -the non-suncalc parts of this software were written by someone and their friend, -© a year of bnuuys. they are distributed under the Little Aminal Public License. -you are free to use, redistribute, modify, destroy, love, hate, pet, kiss, or -fuck the software ("the software") under the following conditia: - - - you agree ur cute soft little aminal in a big wide world - - if ur plant/mycelium/rock/ocean/ghost/star/house/superorganism or something - Else, that's cool too actually, don't worry about it. - - u'll affirm your animality(/beingness) in some way today, such as by - - sniffing at a berry - - stretching your wings - - feeling sunlight on your skin - - feeling wind in your fur - - feeling a tree looking back at you - - you will help a worm or snail in their time of need - - you will remember how sugar smells when it is poured into a bowl - - you will know how it feels for a robin to startle you awake - - you will think about what it would have been like to grow up by the sea - - you will never be normal again - - you will change - - you will change - - you will change - - YOU WILL CHANGE - - you will learn to tell the hours by looking at the light of the world - - you will know this is a map and not the territory - - you will redistribute this license along with the code ---]] - --- it is currently hardcoded to be in seattle. (its bring your own coordinates --- go look 'em up urself) also if you use this above the arctic circle it will --- probably break. if you have ideas for timekeeping in the arctic, reach out to --- me by searching tirelessly for someone who keeps changing their name, their --- face, their body, their language, and you lose hope you will ever know who i --- am, until one day, you see me on a train and you somehow just Know that it is --- Me, and you work up the courage to approach me but just as you clear your --- throat, I get off the train, and you stand asweved in the twilight. or find --- me on horny trans discord servers. -local lat = 47.6 -local lng = -122.3 --- set this to false in the summer -local winter_mode=true --- set this to true if you want a table of hours!! -local print_timetable_mode=false - --- change these to whatever you want. add as many seasons as you want. add --- impossible seasons. add more hours, subtract more hours. add local seasons. --- add dreaming-seasons. rearrange the hour names. you are alive in a world --- where men no longer believe in unicorns and time is running out and all we --- can do is love each other and make magic. - --- foxtime will adjust fine if you make it have more or fewer hours. -local day_hour_names -local night_hour_names -if winter_mode then - -- winter - day_hour_names = { - "halo", - "steam", - "pang", - "mill", - "glean", - "gleam", - "glance" - } - - night_hour_names = { - "gloam", - "glow", - "glim", - "nill", - "dream", - "seem", - "frost" - } -else - -- summer - day_hour_names = { - "dew", - "stir", - "snack", - "mill", - "sprawl", - "brill", - "honey" - } - night_hour_names = { - "owl's light", - "still", - "snuck", - "nill", - "dream", - "seem", - "robin's light" - } -end - -local Early_Name = "early" -local Mid_Name = "mid" -local Late_Name = "late" - --- 🐇 - --- now begins Most Of Suncalc.Lua which we just copypasted into here -- --- Thanks suncalc.lua! -- - ---[[ -Copyright (c) 2014, Vladimir Agafonkin -All rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: - - 1. Redistributions of source code must retain the - above copyright notice, this list of conditions - and the following disclaimer. - - 2. Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---]] - --- for simple translation of javascript ternary comparison operator ?: -local function ternary(a, b, c) if a then return b end return c end - --- shortcuts for easier to read formulas - -local PI = math.pi -local sin = math.sin -local cos = math.cos -local tan = math.tan -local asin = math.asin -local atan = math.atan -local acos = math.acos -local rad = PI / 180 - --- sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas - - --- date/time constants and conversions - -local dayS = 60 * 60 * 24 -local J1970 = 2440588 -local J2000 = 2451545 - -local function toJulian(date) return date / dayS - 0.5 + J1970 end -local function fromJulian(j) return (j + 0.5 - J1970) * dayS end -local function toDays(date) return toJulian(date) - J2000 end - - --- general calculations for position - -local e = rad * 23.4397 -- obliquity of the Earth - -local function rightAscension(l, b) return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)) end -local function declination(l, b) return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)) end - -local function azimuth(H, phi, dec) return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)) end -local function altitude(H, phi, dec) return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)) end - -local function siderealTime(d, lw) return rad * (280.16 + 360.9856235 * d) - lw end - -local function astroRefraction(h) - if (h < 0) then -- the following formula works for positive altitudes only. - h = 0 end -- if h = -0.08901179 a div/0 would occur. - - -- formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. - -- 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad: - return 0.0002967 / math.tan(h + 0.00312536 / (h + 0.08901179)) -end - --- general sun calculations - -local function solarMeanAnomaly(d) return rad * (357.5291 + 0.98560028 * d) end - -local function eclipticLongitude(M) - - local C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)) -- equation of center - local P = rad * 102.9372 -- perihelion of the Earth - - return M + C + P + PI -end - -local function sunCoords(d) - - local M = solarMeanAnomaly(d) - local L = eclipticLongitude(M) - - return { - dec = declination(L, 0), - ra = rightAscension(L, 0) - } -end - - -local SunCalc = {} - - --- calculates sun position for a given date and latitude/longitude - -SunCalc.getPosition = function (date, lat, lng) - - local lw = rad * -lng - local phi = rad * lat - local d = toDays(date) - - local c = sunCoords(d) - local H = siderealTime(d, lw) - c.ra - - return { - azimuth = azimuth(H, phi, c.dec), - altitude = altitude(H, phi, c.dec) - } -end - - --- sun times configuration (angle, morning name, evening name) - -SunCalc.times = { - {-0.833, 'sunrise', 'sunset' }, - { -0.3, 'sunriseEnd', 'sunsetStart' }, - { -6, 'dawn', 'dusk' }, - { -12, 'nauticalDawn', 'nauticalDusk'}, - { -18, 'nightEnd', 'night' }, - { 6, 'goldenHourEnd', 'goldenHour' } -} - --- adds a custom time to the times config - -SunCalc.addTime = function (angle, riseName, setName) - table.insert(SunCalc.times, {angle, riseName, setName}) -end - - --- calculations for sun times - -local J0 = 0.0009 - -local function julianCycle(d, lw) return math.floor(0.5 + (d - J0 - lw / (2 * PI))) end - -local function approxTransit(Ht, lw, n) return J0 + (Ht + lw) / (2 * PI) + n end -local function solarTransitJ(ds, M, L) return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L) end - -local function hourAngle(h, phi, d) return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))) end -local function observerAngle(height) return -2.076 * math.sqrt(height) / 60 end - --- returns set time for the given sun altitude -local function getSetJ(h, lw, phi, dec, n, M, L) - - local w = hourAngle(h, phi, dec) - local a = approxTransit(w, lw, n) - return solarTransitJ(a, M, L) -end - - --- calculates sun times for a given date, latitude/longitude, and, optionally, --- the observer height (in meters) relative to the horizon - -SunCalc.getTimes = function (date, lat, lng, height, times) - times = times or SunCalc.times - height = height or 0 - - local lw = rad * -lng - local phi = rad * lat - - local dh = observerAngle(height) - - local d = toDays(date) - local n = julianCycle(d, lw) - local ds = approxTransit(0, lw, n) - - local M = solarMeanAnomaly(ds) - local L = eclipticLongitude(M) - local dec = declination(L, 0) - - local Jnoon = solarTransitJ(ds, M, L) - - local h0, Jset, Jrise - - - local result = { - solarNoon = fromJulian(Jnoon), - nadir = fromJulian(Jnoon - 0.5) - } - - for _, time in ipairs(times) do - - h0 = (time[01] + dh) * rad - - Jset = getSetJ(h0, lw, phi, dec, n, M, L) - Jrise = Jnoon - (Jset - Jnoon) - - result[time[2]] = fromJulian(Jrise) - result[time[3]] = fromJulian(Jset) - end - - return result -end - --- 🦊 🦊 🦊 🦊 🦊 --- okay suncalc over now we are in the foxtime zone -- - --- this is a utility function for printing out tables -local function tprint (tbl, indent) - if not indent then indent = 0 end - local toprint = string.rep(" ", indent) .. "{\r\n" - indent = indent + 2 - for k, v in pairs(tbl) do - toprint = toprint .. string.rep(" ", indent) - if (type(k) == "number") then - toprint = toprint .. "[" .. k .. "] = " - elseif (type(k) == "string") then - toprint = toprint .. k .. "= " - end - if (type(v) == "number") then - toprint = toprint .. v .. ",\r\n" - elseif (type(v) == "string") then - toprint = toprint .. "\"" .. v .. "\",\r\n" - elseif (type(v) == "table") then - toprint = toprint .. tprint(v, indent + 2) .. ",\r\n" - else - toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n" - end - end - toprint = toprint .. string.rep(" ", indent-2) .. "}" - print(toprint) - end - -local function hoursLater(date, h) - -- dayS is a constant - return date + h * dayS / 24 -end - - ---[[ -So let's say that time_list is a **list** of times, in time-order. Like this: - -{ - { -10, "sunset yesterday" }, - { -5, "sunrise today" }, - { 5, "sunset today" }, - { 10, "sunrise tomorrow" } -} - -And then say `now` is 0. We want to know the two times we are inbetween. So in -this case we would return "sunrise today", "sunset today" to show we are in the -day-part of today. That's what this function does. - -You need to make sure that there are enough times here that we are in between -two of them. If not... well that'd be weird. -]] -local function when_even_are_we(now, time_list) - for i in 1, #time_list - 1 do - -- event time and name - local etime_prev, ename_prev = table.unpack(time_list[i]) - local etime_next, ename_next = table.unpack(time_list[i + 1]) - - if now >= etime_prev and now < etime_next then - -- We are inbetween these two times - return ename_prev, ename_next - end - end -end - - - ---[[ -This little friend will convert all our fun friendly hour names and say when -they happen in the silly little world of "24 hour" that the "humans" like to -use. -]] -local function print_hour_timetable(fuzziest_time, suntimes) - local day_length = suntimes.sunset - suntimes.sunrise - local night_length = (60 * 60 * 24) + suntimes.sunrise - suntimes.sunset - - -- We want to print the night first if its night, and the day first if its - -- day. then we print the other. - local first, second - - -- We start off with these in day, night order. But then if it's night we - -- swap them. The start time just needs to be the start of *a* segment, it - -- doesn't really need to be exactly today's segment because itll be close - -- enough. - first = { - start = suntimes.sunrise, - length = day_length, - names = day_hour_names - } - second = { - start = suntimes.sunset, - length = night_length, - names = night_hour_names - } - if fuzziest_time == 'night' then - -- swap for night - local tmp = first - first = second - second = tmp - end - - -- Do the first, then the second. - for _, seg in ipairs({first, second}) do - -- How long is a hour? - local hourlen = seg.length / #seg.names - - -- Now go through the segment, one hourlength at a time. Print out what - -- 24-hour time it would be, and our hour name. - for i = 1, #seg.names do - local t = math.floor(seg.start + (i - 1) * hourlen) - -- 24hour date, without the day - - -- For some reason lua5.4 on debian doesn't support %l in strftime, - -- so we use %I which formats it with a leading 0, and then replace - -- that with a space. lol - local time_of_day_normalpeople = os.date('%I:%M %p', t):gsub('^0', ' ') - local hour_name = seg.names[i] - print(time_of_day_normalpeople .. ' - ' .. hour_name) - end - end -end - -local function print_hour_timetable_for_date(date) - -- HEY BUDDY YOU CANT BE COPY PASTING LAT/LNG LIKE THAT BUDDY - -- probably somethings in the code should rearrange... - local time = os.time(date) - --[[ - local lat = 47.6 - local lng = -122.3 --]] - local suntimes = SunCalc.getTimes(time, lat, lng) - - print_hour_timetable("day", suntimes) -end - - ---[[ -For anything that wants to use us as a library, here's how they can do it! Any -function we put in "module" is a thing they can use -]] -local foxtime = {} - -function foxtime.what_time_is_it(now) - - -- tprint(SunCalc.getPosition(now, lat, lng)) - -- tprint(SunCalc.getTimes(now, lat, lng)) - - --[[ - This gives us the times of a bunch of interesting solar events, with their - absolute timestamp in seconds since the epoch. Some of them will be before - Now, and some of them will be after Now. Specifically, we have: - - nadir - - nightEnd - - nauticalDawn - - dawn - - sunrise - - sunriseEnd - - goldenHour - - goldenHourEnd - - solarNoon - - sunsetStart - - sunset - - dusk - - nauticalDusk - - night - ]] - local suntimes = SunCalc.getTimes(now, lat, lng) - - --[[ - We want to know if it is day time or not time. If we are between sunrise and - sunset for the day, then that means it's day time! Otherwise it is night. It - is up to you, really, whether to use the start or end of the sunrise and - sunset. but for now we will use `sunrise` and `sunset` - ]] - local fuzziest_time - local seg_start - local seg_end - if now > suntimes.sunrise and now < suntimes.sunset then - -- DAY - fuzziest_time = 'day' - seg_start = suntimes.sunrise - seg_end = suntimes.sunset - else - -- NIGHT - fuzziest_time = 'night' - --[[print(now) - print(suntimes.sunrise) - print(suntimes.sunset) - --]] - --[[ - If we are on the left of sunrise, then the segment ends at sunrise and - starts at the *previous days* sunset. If we are on the right of sunset, - then sunset is when the segment started and it will end on tomorrows - sunrise. - --]] - if now < suntimes.sunrise then - --[[ - For now, do the inaccurate but maybe close enough thing of taking - 24 hours off of today's number. This will be least accurate around - the equinox and most accurate around the solstice. - --]] - seg_start = suntimes.sunset - 60 * 60 * 24 - seg_end = suntimes.sunrise - else - - seg_start = suntimes.sunset - seg_end = suntimes.sunrise + 60 * 60 * 24 - --print(seg_start) - --print(seg_end) - end - end - - --[[ - Now we want to know how far through the current time-section we are. We want - this as like a fraction out of 1.0, because we're going to re-scale it to - our own fucked up time system :3 :3 :3 - ]] - local seg_progression = (now - seg_start) / (seg_end - seg_start) - - --[[ - now we re-scale it to ""hours"", which are some number of divisions of the - segment. We will use the length of the names list to decide this, that way - we don't need to remember to update both places when we make changes. Plus - then you can have the day and night have different number of hours, and isnt - that kinda neat? - ]] - local num_hours - if fuzziest_time == 'day' then - num_hours = #day_hour_names - else - num_hours = #night_hour_names - end - local current_hour = math.floor(seg_progression * num_hours) - --[[print("current hour") - print(current_hour)--]] - - --[[ - If seg_progression is **exactly** 1.0, then current_hour can be num_hours. - Which is weird. For a very small instant you might have that, if the maths - work out that way. But that adds a secret num_hours + 1 hour which doesnt - fit. So if current_hour == num_hours we should make it be num_hours - 1 for - that instant. - ]] - if current_hour == num_hours then - current_hour = num_hours - 1 - end - - --[[ - But what is this hour named?? Let's find out! Don't forget to add 1, because - current_hour from the maths we did will be from 0 to (num_hours - 1) - ]] - local hour_name - if fuzziest_time == 'day' then - hour_name = day_hour_names[current_hour + 1] - else - hour_name = night_hour_names[current_hour + 1] - end - - --[[ let's do math to find out how far we are within the hour ]] - local hour_length = (seg_end - seg_start) / num_hours - --[[]] - local current_hour_start = seg_start + ((current_hour)*hour_length) - local current_hour_progress = (now - current_hour_start) / hour_length - --print(string.format("now %s current_hour %s seg_start %s seg_end %s hour_length %s current_hour_start %s current_hour_progress", now, current_hour, seg_start, seg_end, hour_length, current_hour_start, current_hour_progress)) - local minute_name - if current_hour_progress < 0 then - minute_name = "errneg" - elseif current_hour_progress <= 0.33 then - minute_name = Early_Name - elseif current_hour_progress <= 0.66 then - minute_name = Mid_Name - elseif current_hour_progress <= 1 then - minute_name = Late_Name - else minute_name = "errpos" - end - --[[ - And now we know what time it is! - ]] - - if print_timetable_mode then - print_hour_timetable("day", suntimes) - end - return string.format("%s %s", minute_name, hour_name) -end - -local function mane() - local now = os.time() - - print(foxtime.what_time_is_it(now)) -end - - --- swap these comments out to use this as a library (for instance, to put this on koreader) - --- return foxtime -mane()