Command-line hacking: creating a tide table

display This is another in my series of articles on doing off-beat and (I hope) interesting things with standard Linux command-line tools. In this post I'll demonstrate how to create a simple tide table, using shell arithmetic and the standard GNU `date` utility.

The idea is to enter the time and date of a specific high tide, and the shell commands then display a table of tide times for the following seven days, using simple date arithmetic. In the days before widespread Internet access, this actually was a common method for predicting tides -- you'd observe when the tide was high, then start a timer whose end point was the known interval between tides. You could (probably still can) buy wrist watches with this functionality built in. This sort of thing has largely been replaced by websites issued by maritime authorities; but the kind of place I like to vacation often doesn't have electricity, let alone Internet access. But I'm never very far from something that can run Linux.

A simple approach like the one I describe here only works in places that have regular tides, at intervals of 745 minutes (roughly twelve and a half hours). Most places on earth follow this pattern to some extent but, so far as I know, it isn't exact anywhere. For my purposes, if I get the low tide wrong by half an hour, it's of no great significance. If you have to get an super-tanker over a sand bar, that's a different matter.

My approach works because the GNU date utility is capable of a certain amount of date arithmetic. It can work out, for example, what time it will be a certain number of minutes after a specified time. The command line format is:

$ date --date="13:30 april 28 + 745 minutes"
Thu 29 Apr 01:55:00 BST 2021

That is, if high tide is at 13:30 on April 28, the next high tide will be 745 minutes later, at 01:55 on the 29th. Incidentally, the reason that tides are generally 745 minutes apart, and not 720 (twelve hours) is that the Moon orbits the Earth in the direction of the Earth's rotation. It takes an extra 25 minutes for the Earth to catch up to the same position it had with respect to the Moon every half-day.

Anyway, here is the command:

HIGH="13:30 april 28"; \ # Datum high tide
for n in {0..6}; \
  do ((h=$n*745+745)); ((l=$n*745+373)); \
  echo -n "Low  "; date --date="$HIGH + $l minutes"; \
  echo -n "High "; date --date="$HIGH + $h minutes"; \
done

And here is the output:

Low  Wed 28 Apr 19:43:00 BST 2021
High Thu 29 Apr 01:55:00 BST 2021
Low  Thu 29 Apr 08:08:00 BST 2021
High Thu 29 Apr 14:20:00 BST 2021
Low  Thu 29 Apr 20:33:00 BST 2021
High Fri 30 Apr 02:45:00 BST 2021
Low  Fri 30 Apr 08:58:00 BST 2021
High Fri 30 Apr 15:10:00 BST 2021
Low  Fri 30 Apr 21:23:00 BST 2021
High Sat  1 May 03:35:00 BST 2021
Low  Sat  1 May 09:48:00 BST 2021
High Sat  1 May 16:00:00 BST 2021
Low  Sat  1 May 22:13:00 BST 2021
High Sun  2 May 04:25:00 BST 2021

The statement

for n in {0..6}; do ... done

Creates a loop in which the variable n takes the values from 0 to 6 (inclusive). So this loop executes seven times in total, setting a new value for n each time.

This statement calculates the number of minutes the next high and low tide are from the original high tide, storing the results in h and l respectively.

  ((h=$n*745+745)); ((l=$n*745+373)); 

Because n starts at 0, the next high tide is not n*745, but (n+1)*745 -- but its fiddly to include the brackets in the shell expression, so I've expanded the expression out. The next low tide is half of 745 minutes (= 373 minutes) after the starting time. There probably are other ways to do this arithmetic, and it's worth bearing in mind that the Bash shell can only do arithmetic in integers -- but that's fine here.

When printing the result, note that echo -n prevents the echo command writing an end-of-line character; but date will write one, at least by default.

So that's it -- a simple way to generate a tide table using only the command line.