624 lines
19 KiB
Lua
624 lines
19 KiB
Lua
#!/usr/bin/lua
|
|
|
|
--[[ foxclock version ᚢ.1 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.
|
|
|
|
-- foxclock 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
|
|
|
|
-- change the prefix for the part of the hour
|
|
-- make them unfur. make them blossom. make them shake.
|
|
local Early_Name = "early"
|
|
local Mid_Name = "mid"
|
|
local Late_Name = "late"
|
|
|
|
-- 🐇 🐇 🐇 🐇 🐇 🐇 🐇 🐇
|
|
-- you now no longer have to read the code unless you're using this as
|
|
-- a library then also have a look at the last few lines.
|
|
|
|
-- 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 foxclock 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 foxclock = {}
|
|
|
|
function foxclock.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(foxclock.what_time_is_it(now))
|
|
end
|
|
|
|
|
|
-- swap these comments out to use this as a library (for instance, to put this on koreader)
|
|
|
|
-- return foxclock
|
|
mane()
|