Date Parsing and Arithmetic on macOS

I recently wrote a shell script that required both date parsing and date arithmetic. The pertinent bits for this post are that the script:

  • Accepted a date as a parameter
  • Accepted a number of days as a parameter
  • Iterated through the dates to generate specific strings in “year-month-day” format, e.g., “20230225” for February 25, 2023

Seemed simple enough. A little googling and some experimentation gave me this snippet that worked on Linux:

for ((i = 0; i < $2; i++)); do
  current=$(date +%Y%m%d -d "$1 + $i days")
  echo $current
done

Running this on Linux, with a start date of February 25, 2023, and a run of 10 days, produced this:

$ ./dates.sh 20230225 10
20230225
20230226
20230227
20230228
20230301
20230302
20230303
20230304
20230305
20230306

Running this on the target platform, macOS, produced this:

$ ./dates.sh 20230225 10
date: illegal time format
usage: date [-jnRu] [-r seconds|file] [-v[+|-]val[ymwdHMS]]
            [-I[date | hours | minutes | seconds]]
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
[repeated 10 times]

OK, so date differs between the platforms. So I typed man date, giggled a little, discovered the -j, -f, and -v flags, and put them together like this:

current=$(date -jf '%Y%m%d' "$1" -v +"$i"d '+%Y%m%d')

Running that gave me this:

$ ./dates.sh 10
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023
Sat Feb 25 11:39:56 EST 2023

So I googled and I fussed with the -v format and the output format and got frustrated. Just when I was about to rewrite it all in Python, which I know about as well as I know Italian, I tried putting the -v flag first:

#!/bin/bash

for ((i = 0; i < $2; i++)); do
  current=$(date -v +"$i"d -jf '%Y%m%d' "$1" '+%Y%m%d')
  echo $current
done

And that gave me this:

$ ./dates.sh 20230225 10
20230225
20230226
20230227
20230228
20230301
20230302
20230303
20230304
20230305
20230306

Order matters, I guess, with the macOS date command. Increment, parse, output. YMMV.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.