[HN Gopher] Show HN: Tiny Moon - Swift library to calculate the ...
___________________________________________________________________
Show HN: Tiny Moon - Swift library to calculate the moon phase
Tiny Moon is a tiny Swift library to calculate the moon phase for
any given date, works super fast, and works completely offline.
All of this started when I realized that we only have 12, sometimes
13, full moon's in a year. That doesn't seem like that many. I set
out to build a MacOS app to remind me when a full moon occurs, so
that I could take a moment and step outside to appreciate it. The
MacOS app I ended up creating can be found at
https://apps.apple.com/us/app/tiny-moon/id6502374344 along with the
source code [0], all powered by the Tiny Moon library. I knew that
I wanted the app to work offline, so working with a network request
was out of the picture. Taking inspiration from SunCalc [1] and
Moontool for Windows [2], I decided to create my own library and
wrote Tiny Moon as a Swift Package to power my app. The app tries
to be as minimal as possible, does what it does very fast, and
works completely offline. [0]
https://github.com/mannylopez/TinyMoonApp [1]
https://github.com/mourner/suncalc [2]
https://www.fourmilab.ch/moontoolw/
Author : mannylopez
Score : 67 points
Date : 2024-07-25 15:17 UTC (7 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| jes5199 wrote:
| nice! I have needed this before. I think you're using the Meeus
| algorithm from Astronomical Algorithms? it's a classic, great
| choice
| mannylopez wrote:
| Yes, pretty much every good library I came across referenced
| Meeus' Astronomical Algorithms [0] book and formulas. Those
| were a bit dense for me to fully parse, but Dr. Louis Strous`
| page [1] on finding the position of the moon helped simplify it
| for me (although that implementation is less accurate, I
| think).
|
| The algorithm in Moontool for Windows [2], which Tiny Moon is
| based off of, is based off of Meeus' algorithm.
|
| 0.
| https://www.agopax.it/Libri_astronomia/pdf/Astronomical%20Al...
|
| 1. https://aa.quae.nl/en/reken/hemelpositie.html#4
|
| 2. https://www.fourmilab.ch/moontoolw/
| ks2048 wrote:
| Nice work. Just FYI for anybody else - it adds an icon to status
| bar (if that's what it's called? - top right icons). I thought it
| was going to open an app window and didn't notice the icon, so
| thought it wasn't working. (In hindsight, it's clear from
| screenshots in app store).
| asrael_io wrote:
| I think it's called the menu bar, and apps that don't open
| windows (with an icon in the menu bar) are known as "menu bar
| apps". Until recently, these were a PITA to implement with
| Apple's SDK. Thankfully they provided API support sometime I
| think starting with macOS 13... before that it was pretty
| kludgy.
| rgovostes wrote:
| The menus themselves are called "menu bar extras":
| https://developer.apple.com/design/human-interface-
| guideline...
| shainvs wrote:
| Is there a plan to add this for linux / windows? Either way,
| super cool project
| mannylopez wrote:
| Good news! According to Swift Package Index [0], Tiny Moon is
| already compatible with Linux environments.
|
| 0. https://swiftpackageindex.com/mannylopez/TinyMoon/
| robsh wrote:
| The following formula will return the closest moon phase emoji
| in Excel:
|
| =LET(phase,MOD(ROUND(MOD(NOW(),29.5275)/3.691,0)-2,8)+1,UNICHAR
| (127760+phase)))
| 082349872349872 wrote:
| Here's a tiny calculator for moon phase that I kludged up ca.
| 2018 but (at least as of this month) is still tracking the full
| moon (which makes sense given that the algo came out of a dead
| tree source from over half a century ago?): _=min
| lphase = lambda y,m,d: _( lkp(ph,p) for lkp in
| [lambda t,x: _(v for (kl,v),(kh,w) in
| zip(t,t[1:]) if kl <= x < kh)] for daynum in [lambda
| y,m,d: daynum(y-1,m+12,d) if m<3 else
| y*365 + y//4 - y//100 + y//400 + (153*m+3)//5 + d]
| for o in [daynum(y,m,d)-daynum(2000,1,6)] for p
| in [o%29.53] # mean; varies significantly! for ph in
| [[(0,"new"),(0.5,"waxing crescent"),(7,"first quarter"),
| (8,"waxing gibbous"),(14.5,"full"),(15.5,"waning gibbous"),
| (21.7,"last quarter"),(22.7,"waning crescent"),(29,"new"),
| (30,None)]] )
| madcaptenor wrote:
| So this is just saying that the phase of the moon is the day
| mod 29.53, starting from a new moon on 2000-01-06. That's about
| a minute off the actual mean length of a lunation - I guess the
| error from that approximation is less than the approximation in
| your "varies significantly"?
|
| (For what it's worth - 29.53 * 300 = 8859 exactly, and
| 2000-01-06 + 8859 days = 2024-04-08, and I am quite sure there
| was a new moon on the latter date because of the solar
| eclipse.)
| 082349872349872 wrote:
| Yes. (any cultures that have a purely lunar calendar could do
| away with all the date fiddling? but then again, I guess
| they'd just _know_ when the next full moon would be...)
|
| [If that constant is only a minute off, it ought to be good
| for a few centuries more, and I'm not planning on being
| around longer than decades, so probably good enough for my
| purposes.]
| gmiller123456 wrote:
| I think the point is that the lunations vary by a couple of
| days within a year, so you might confuse users by stating a
| phase is on the wrong day when they are unaware a low
| accuracy algorithm is being used. But that algorithm
| probably would be good enough for just drawing an icon,
| since the differences would be imperceptable.
|
| Honestly, I recommend people use the most accurate
| algorithm they practically can, even if it's overkill for
| the given application. This just avoids user confusion when
| different apps give different answers, even if it's not
| significant.
|
| E.g., I have ported VSOP87 which gives the position of the
| moon and planets to sub-arcsecond accuracy to a couple of
| dozen languages. They are much, much longer than the
| "snippets", but are not impractical, and users won't notice
| much difference in application size or computation time.
| https://github.com/gmiller123456/vsop87-multilang
| gmiller123456 wrote:
| I have a site with a lot of these stand alone "snippets" so that
| you don't have to include/port an entire astronomy library just
| to get the Sun rise/set times, etc.
| https://www.celestialprogramming.com/
|
| Most of them are written in JavaScript only, but specifically
| written to be easy to port to other languages.
| kickingvegas wrote:
| Side note, if you use Emacs you can get the phases of the Moon by
| pressing "M" in either calendar or Org Agenda.
| eesmith wrote:
| With M-x lunar-phases you get the next three lunar months;
| something like: Thursday, June 6, 2024: New
| Moon 8:40am (EDT) Friday, June 14, 2024: First Quarter
| Moon 1:20am (EDT) .. I removed a few lines ...
| Monday, August 19, 2024: Full Moon 2:24pm (EDT) Monday,
| August 26, 2024: Last Quarter Moon 5:34am (EDT
|
| Also, M-x sunrise-sunset computes sunrise and sunset after you
| give it lat/long.
| ChrisMarshallNY wrote:
| I don't really have use for this, but I must compliment the
| author on a job well-done. The code is well-structured, well-
| documented, well-tested, and well-designed.
| mannylopez wrote:
| Thank you! I was a technical writer before learning how to
| program, so it's important for me to write well-documented and
| well-tested code.
|
| Doing so also allowed me to completely remove and replace my
| first attempt at implementing the moon phase algorithm when it
| turned out to be not-accurate enough (the values were off by
| about 4 hours).
| rubiquity wrote:
| I know a lot of people into fishing that would love this as an
| app to quickly check the moon phase on a given date when planning
| a multi-day fishing trip or deciding when to go out. Apex
| predators are typically less hungry around and during a full moon
| due to the extra light making hunting at night easy.
| whartung wrote:
| And then, there was an anecdote!
|
| I bought my friends daughter a watch for her birthday. She was,
| like, 12 or something. I got it at Target.
|
| And it had a moon phase dial! How about that?!
|
| So I was determined to set it accurately for her.
|
| To wit I started dredging through the internet. And to be
| completely honest, I'm not quite sure how I was doing that,
| having nothing but a Netcom.com shell account available to me.
| Perhaps I was using Lynx, or using some mail gateway, or who
| knows what. It wasn't no 10 seconds on Google, I'll tell you
| that.
|
| In the end, I stumbled upon some code for my HP-48. Aha! This
| should do nicely!
|
| Somehow, I got the code into the calculator. Did I type it in?
| Did I download it over Kermit? Who knows. Times were moving fast
| back then. Somehow, someway, however, I got that code in and
| calculated away.
|
| Finally! ACCURATE results. Done with precision and math and
| engineering. Done Right!
|
| To wit, I then proceeded to get the watch set properly.
|
| And...it was a fashion watch for a 12 year old girl from Target.
| This may come as a shock to some, I was obviously taken aback by
| it, however -- the moon phase did not work. It was just a moon on
| a dial that moved, though some undetermined mechanism. It could
| not be set independently.
|
| Oh.
___________________________________________________________________
(page generated 2024-07-25 23:04 UTC)