当前月相
女士们先生们,我们离开了火星。好吧,至少我完成了过去几篇文章中关于火星着陆器的内容。我希望你们有机会尝试一下,并发现将飞行器降落在任何行星上都不是那么容易!
在研究火星着陆器项目时,我偶然发现另一个与太空相关的有趣的脚本问题。如何确定给定日期的月相?当然,有公式,你可以通过数学计算得知月球的自转周期是精确的——嗯……实际上,并没有那么简单。
恒星周期与朔望周期当然,你可以简单地说月球每 27.3 天绕地球运行一次,但那是相对于恒星的,即恒星轨道。月相(例如满月)之间的周期也称为朔望轨道,为 29.5 天。
因此,确定是否是满月的简单任务也涉及到一些数学计算。然后还有月球的照明水平相对于你在地球上的位置的问题。这很合理。智利蓬塔阿雷纳斯的满月与拉普兰的满月不同(尽管差别不大)。
长话短说,计算月球照明水平背后的数学运算并不像看起来那么简单。你可以取一个已知的满月日期和时间(例如,11 月 14 日上午 8:52 EST),并不断精确地加上 29.530 天或 42,523.20 分钟。
或者你可以抓取网站!但说真的,你也可以让别人来完成这项工作,对吧?我的意思是,这个专栏毕竟只是关于一个 shell 脚本。那么,让我们看看 Google 是怎么做的!如果你查看 Google 以了解当前月相,它实际上引用了一个网站,如图 1 所示。
图 1. Google 报告当前月相。
在 Moon Giant 网站上深入挖掘一下,你可以看到有两种基本形式的 URL 可以生成所需的数据:指定的日期或仅是作为日期的“today”。通过访问此网站进行测试:http://www.moongiant.com/phase/today。
指定日期,格式会稍微复杂一些:http://www.moongiant.com/phase/MM/DD/YYYY。
你可以使用它来找出美国新总统宣誓就职当天的月相:http://www.moongiant.com/phase/01/20/2017。(如果你猜是满月,那你就错了!)
月相,V1这意味着你可以非常容易地编写一个简洁的脚本,通过简单地使用 curl
或 GET
和这三个 URL 中的第一个来告诉你当前的月球照明水平
url="http://www.moongiant.com/phase/today"
pattern="Illumination:"
phase="$( curl -s "$url" | grep "$pattern" | tr ',' '\
' | grep "$pattern" | sed 's/[^0-9]//g')"
echo $phase
在我编写本文时(2016 年 10 月 3 日)快速运行脚本,输出结果相当令人困惑:“6”。六。这是什么意思?实际上,这只是照明水平,其他所有内容都从输出数据中删除了。
6% 的照明接近新月,但还差一点。新月实际上是在两天前的 10 月 1 日。
脚本中有趣的部分完全在 phase=
语句中。让我们解开它并仔细看看
curl -s "$url" |
grep "$pattern" |
tr ',' '\
' | grep "$pattern" |
sed 's/[^0-9]//g'
首先,如果你不熟悉 curl
,请阅读手册页。它是一个非常棒、功能非常强大的实用程序,可以让你调试 Web 服务器、向 Web 页面发送查询(就像你是各种 Web 浏览器一样)、与 FTP 服务器交互,当然,还可以抓取 Web 页面的源代码以进行进一步分析。我正在为这项任务使用后一种技能。
一旦页面的源代码流入,管道中的下一步是提取包含照明水平的行。结果证明正是“Illumination:”,但不幸的是,它并没有单独出现在 HTML 源代码行中。事实上,这是一个非常复杂的输出行!这实际上是接下来两行的工作。
tr
的调用将每个逗号转换为硬回车符,有效地将一个非常长的行分解成许多较短的行。然后再次调用 grep
以提取现在进一步隔离的照明水平指示器。
最后,通过让 sed
删除所有不是数字的内容来删除多余的数据。最终结果?像 Illumination: 6%
这样的输入变成 “6”,并存储在变量 phase
中。明白了吗?
现在可以增强输出了
echo "The moon's current illumination level: $phase%"
稍微更容易理解的输出!
但它是什么月相?然而,月相通常不是用其照明水平来描述的,并且还需要知道前一天的状态,因为这是你确定“盈”或“亏”的方式。
有些很容易:0% 是新月,25% 是四分之一月,50% 是半月,100% 是满月。或者真的是这样吗?实际上,月球有八个相位,而 50% 的照明被称为“四分之一月”,这令人困惑。
事实上,月相取决于它在新月 → 新月周期中的位置,因此满月之前的 50% 照明是“上弦月”相位,而满月之后的 50% 照明是“下弦月”相位——非常复杂。
再次,让我们简化一下。所以现在跳过盈亏,而是使用以下内容
-
0–5% = 新月。
-
6–45% = 眉月。
-
46–55% = 上弦月/下弦月。
-
56–95% = 凸月。
-
96–100% = 满月。
现在让我们编写代码。最简单的方法是使用一系列 if-then-else 语句
if [ $phase -lt 5 ] ; then
phasename="new"
elif [ $phase -lt 45 ] ; then
phasename="crescent"
elif [ $phase -lt 55 ] ; then
phasename="quarter"
elif [ $phase -lt 95 ] ; then
phasename="gibbous"
else
phasename="full"
fi
具有美观的结果
$ potm.sh
The moon is currently crescent with 11% illuminated.
让我们在本文中就此打住。在我的下一篇文章中,我将添加分析它是盈月还是亏月的能力(例如,将昨天的照明水平与今天的进行比较,以查看月球是变亮还是变暗)。