The ErrorIf you've ever tried to run a Linux-based Bash script on a Mac, you've probably hit this wall. Instead of calculating a date, your terminal spits out this frustrating block of text:
date: illegal option -- d
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Why This HappensThe problem boils down to lineage. Linux distributions like Ubuntu or Debian use GNU Coreutils. In the GNU version of date, the -d flag is what you use to parse strings like "yesterday" or "30 days ago."
macOS is different. It is based on BSD, which uses a completely different version of the date utility. On a Mac, the -d flag is actually used to set Daylight Saving Time values. If you want to do date math using the native Mac command, you have to use the -v flag instead. Because the syntax is so different, scripts written for Linux almost always break on macOS.
Solution 1: Install GNU Coreutils (The Pro Fix)The cleanest way to fix this is to bring the GNU tools to your Mac. This allows you to run Linux-style commands without rewriting your entire script library. You can do this in about two minutes using Homebrew.
1. Install HomebrewIf you haven't joined the Homebrew club yet, paste this into your terminal to install the package manager:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
2. Install CoreutilsNext, install the GNU utility suite. This package is small—usually under 15MB—and installs quickly:
brew install coreutils
After the installation finishes, the GNU version of the date command is available as gdate. It works exactly like the date command on Linux:
gdate -d "yesterday"
Solution 2: Make Your Script Cross-PlatformAre you sharing your scripts with a team? You can't always assume everyone has coreutils installed. A better approach is to add a small logic check at the top of your script to detect the operating system and choose the right command automatically.
Example Script Snippet:```
Detect if we are running on macOS (Darwin)
if [[ "$OSTYPE" == "darwin"* ]]; then if command -v gdate > /dev/null 2>&1; then DATE_CMD="gdate" else echo "Required dependency 'coreutils' missing. Install it with: brew install coreutils" exit 1 fi else DATE_CMD="date" fi
Now use $DATE_CMD instead of 'date'
$DATE_CMD -d "2024-01-01 + 5 days"
## Solution 3: The Alias ShortcutIf you just want to run commands manually and don't want to type the letter 'g' every time, you can map `date` to `gdate` in your shell configuration. This is a great local fix for your personal workflow.
- Open your Zsh config: `nano ~/.zshrc`- Add this line at the bottom: `alias date='gdate'`- Refresh your shell: `source ~/.zshrc`**Note:** This alias only works in your interactive terminal. It won't fix standalone `.sh` files because shell scripts don't inherit aliases by default.
## VerificationLet's make sure everything is running smoothly. Try calculating a specific date in the future:
gdate -d "2024-12-25 + 1 year" +"%Y-%m-%d"
If the terminal returns `2025-12-25`, you're all set. You can also double-check the version to confirm you're using the GNU suite:
gdate --version
The first line of the output should read something like `date (GNU coreutils) 9.4`.
## Prevention Tips- **Standardize on gdate:** If your team uses both Macs and Linux servers, make it a rule to use `gdate` in all scripts and include `coreutils` in your macOS setup documentation.- **Consider Python:** For complex date logic, use a Python one-liner. Python's `datetime` module works identically on every OS, saving you from the BSD vs. GNU headache entirely.- **Check your flags:** Before porting a heavy script, run `man date` on your Mac. It’s a quick way to see just how different the BSD flags are compared to what you're used to on Linux.

