Skip to content

Instantly share code, notes, and snippets.

# matthewmcvickar/current_moon_phase.md Last active Sep 6, 2017

A failed attempt at converting the moon-phase finding Ruby script to a Bash shell script.

## Trying to Convert the Ruby Moon Phase-finder to Bash

2013-04-02, 10:28pm

Below is my feeble attempt to convert the moon-phase Ruby script into Bash.

Unfortunately, this doesn't work for two reasons:

1. I don't know shell scripting very well.
2. Bash arithmetic can't handle anything other than integers.

There is a chance that cal() or date() could handle some of this, but I don't understand either of them well enough. I also have a suspicion that the way I'm using 'Julian' in this code is an inaccurate descriptor of what's being calculated. I should have read up on moon phase calculating or read through the source of the other libraries around GitHub that are doing this, but I was rushing to make this a fast, fun thing so I didn't get mired in the literature like I want to now.

In any case, here's as far as I got before giving up for the night.

 # Convert a date to Julian. function convert_to_julian { a=(14-\$2)/12 y=\$1+4800-a m=(12*a)-3+\$2 converted_date=\$((\$3 + \$((\$((153*\$m+2))/5)) + \$((365*\$y)) + \$((\$y/4)) - \$((\$y/100)) + \$((\$y/400)) - \$((32045)))) } # Define the phases of the moon. function get_moon_phase { convert_to_julian \$1 \$2 \$3 | date +%Y\ %m\ %d today=\$converted_date convert_to_julian 2000 1 6 converter=\$converted_date phase_number=\$((\$((\$today - \$converter))%29)) if [ phase_number -lt "1.84566" ]; then phase_icon="🌑" # new elif [ phase_number -lt "5.53699" ]; then phase_icon="🌒" # waxing crescent elif [ phase_number -lt "9.22831" ]; then phase_icon="🌓" # first quarter elif [ phase_number -lt "12.91963" ]; then phase_icon="🌔" # waxing gibbous elif [ phase_number -lt "16.61096" ]; then phase_icon="🌕" # full elif [ phase_number -lt "20.30228" ]; then phase_icon="🌖" # waning gibbous elif [ phase_number -lt "23.99361" ]; then phase_icon="🌗" # last quarter elif [ phase_number -lt "27.68493" ]; then phase_icon="🌘" # waning crescent else phase_icon="🌑" # new fi } get_moon_phase echo \$phase_icon

### m8x60mm commented Apr 13, 2015

 If you want to take your bash-fu to the next level, I recommend reading the FAQ and other bash-related materials at wooledge.org. A very old trick for doing floating-point math when only integer math is available: remap the number space. For example, suppose your code never needs a number greater than 2,000, less than 0, or with more than 5 digits after the decimal point. In that case you could just multiply everything by 100,000, and the biggest number should still be within the 2,147,483,647 limit on typical 32-bit systems. Of course, it's much more general to just use the suggestions in the above-mentioned bash FAQ, but I'd probably do the remap thing in the trivial cases just because it's, well, a trivial case.
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.