An open API service indexing awesome lists of open source software.

https://github.com/mountaineerbr/shelldatediff

Calculate time differences with shell builtins. Check moon phases, Easter dates and next Friday 13th.
https://github.com/mountaineerbr/shelldatediff

bash date-calculation datediff easter-calculation ksh lunar-phases shell time-interval zsh

Last synced: 26 days ago
JSON representation

Calculate time differences with shell builtins. Check moon phases, Easter dates and next Friday 13th.

Awesome Lists containing this project

README

          

# shellDatediff
Calculate time differences with shell builtins.

![Showing off datediff.sh script](https://gitlab.com/mountaineerbr/etc/-/raw/main/gfx/datediff_intro.gif)

Shell utility for calculating time intervals between dates. Works with Ksh, Bash, and Zsh.

The project contains a small shell library to calculate **elapsed time between dates** as **compound time ranges** and as **single-unit fractions** - all while handling timezone offsets.

The script works with ISO-8601 and UNIX timestamps directly. It can optionally leverage `C-code date` to process diverse date formats as input.

Beyond time intervals, it offers a few helpful calendar functions for day-to-day use.

## Index

★ Click to expand! ★

- 1. [Features](#-features)
- 2. [Installation](#installation)
- 3. [Usage Examples](#usage-examples)
- 3.1 [Time elapsed between two dates](#time-elapsed-between-two-dates)
- 3.2 [Result layout](#result-layout)
- 3.3 [Single time unit result](#single-time-unit-result)
- 3.4 [Decimal plates](#decimal-plates)
- 3.5 [Table view](#table-view)
- 3.6 [Next Friday the 13th](#check-next-friday-the-13th)
- 3.7 [Check leap years](#check-whether-year-is-leap)
- 3.8 [Lunar calendars](#generate-lunar-phase-calendar)
- 3.9 [Carnaval, Easter and Corpus Christi](#carnaval-easter-and-corpus-christi)
- 4. [More Examples](#more-examples)
- 5. [Dependencies](#dependecies)
- 6. [Debugging dependencies](#debugging-dependencies)
- 7. [Help](#help)
- 8. [Project Source](#project-source)
- 9. [See Also](#see-also)

## ✨ Features

- Date input as *ISO-8601* or *UNIX time*
- Optionally warps `C-code date` to parse various date formats
- Timezone offset aware, heeds environment `$TZ`
- Check whether year is leap
- Calculate moon / lunar phases
- Calculate Easter, Carnaval, and Corpus Christi dates
- Check for next Friday the 13th (or any day-of-week/month combination)
- _Stdin_ _input_ (pipe) support

## Installation

Place [datediff.sh](datediff.sh) in your `$PATH` and make it executable.

```
chmod +x /path/to/datediff.sh
```

The script is compatible with `ksh`, `bash`, and `zsh`; the shebang may be changed as needed.

Arch Linux users can install the [PKGBUILD from the AUR](https://aur.archlinux.org/packages/datediff.sh) with an AUR helper:

```
yay -S datediff.sh
```

## Usage Examples

### Time elapsed between two dates

If only one date is specified, the first date is assumed to be **now**.

```
% datediff.sh -u 2008-01-15 2024-09-11

DATES
2008-01-15T00:00:00+00:00 1200355200
2024-09-11T00:00:00+00:00 1726012800
RANGES
16Y 07M 03W 06D 00h 00m 00s
16.7 years | 199.9 months | 869.1 weeks | 6084.0 days | 146016.0 hours | 8760960.0 mins | 525657600 secs
```

Setting `option -u` performs all date calculations in UTC.
It also influences how the underlying `C-code date` programme processes dates.

A single float time frame result may be calculated [when specified as the last positional argument](#single-time-unit-result).

Set `options -vvv` to filter the main output layout for specific fields (main function).

For example, calculate the **compound time range** _only_:

```
% datediff.sh -vv 2025-03-30T12:33:58 2031-04-17T04:34:10

6Y 00M 02W 03D 16h 00m 12s
```

Mind that input dates must be ISO-8601 or UNIX time.
When available, `C-code date` is leveraged to parse
user input in various date formats.

### Result layout

The main function is verbose by default and
prints two sections with processed dates (**DATES**) and time range results (**RANGES**).

The user can filter out which fields are going to be calculated and displayed.

Set the verbose `option -v` up to three times to select different layouts in
the main function. Setting `-v` in other functions decreases verbose.

Set **option -v** once to print all single unit results _only_:

```
% datediff.sh -v 2008-01-15

17.4 years | 209.3 months | 910.3 weeks | 6371.8 days | 152923.3 hours | 9175400.5 mins | 550524032 secs
```

**Note:** Examples in this group run on 2025-06-25.

Compound time range (`AST date` style):

```
% datediff.sh -vvv 2008-01-15

17Y05M01W03D01h00m00s
```

### Single time unit result

The user can optionally set the last positional parameter as exactly
`y`, `mo`, `w`, `d`, `m` or `s` to print only the specific single-unit result:

```
% datediff.sh 2008-01-15 2025-06-25 mo

209.3 months
```

### Decimal plates

The number of decimal plates shown in float results can be set with `option -[num]`,
where _num_ is an integer. For three decimal plates, the incantation should start as
`datediff.sh -3`.

Results are subject to rounding for improved precision!

### Table view

**Print results in table layout** with `options -tt` at the
command line incantation (single-unit intervals):

```
% datediff.sh -3 -t -u 2008-01-15 2025-06-25

Years 17.440
Months 209.323
Weeks 910.143
Days 6371.000
Hours 152904.000
Mins 9174240.000
Secs 550454400
```

### Check **next Friday the 13th**

Using the _current date_ by default, run on _2025-06-25_:

```
% datediff.sh -F Fri 13

Fri, 13 Feb 2026 is 233 days away
```

Check any combination of **day-in-week** and **day-in-month**:

Optionally specify a *start date* for the search.

```
% datediff.sh -F Mon 1 2030-01-01

Mon, 01 Apr 2030 is 90 days away
```

Set `options -FF` to print the following 10 date matches as a list!

### Check whether **year is leap**

```
% datediff.sh -l 2032

leap year -- 2032
```

The _exit code is 1_ if a year _is not_ leap.

Set `option -v` to decrease verbose.

### Generate **lunar phase calendar**

```
% datediff.sh -m 2030-01

2030-01-01 Waning Crescent
2030-01-03 New Moon
2030-01-07 Waxing Crescent
2030-01-10 First Quarter
2030-01-14 Waxing Gibbous
2030-01-18 Full Moon
2030-01-21 Waning Gibbous
2030-01-25 Last Quarter
2030-01-29 Waning Crescent
```

Port of the NetHack `phase_of_the_moon()` code;
as an approximation, its results may differ slightly from actual moon phases.

For multiple-month calendar:

```
% datediff.sh -m 2030-{01..12}

#OR

% datediff.sh -m 2030
```

Setting `option -m` without an argument shows the moon phase for current date.

### **Carnaval**, **Easter** and **Corpus Christi**

```
% datediff.sh -ee 2030

Carnaval Easter CorpusChristi
2030-03-05 2030-04-21 2030-06-20

```

Set multiple years to calculate a table of dates:

```
% datediff.sh -ee 20{23..30}
Carnaval Easter CorpusChristi
2023-02-21 2023-04-09 2023-06-08
2024-02-13 2024-03-31 2024-05-30
2025-03-04 2025-04-20 2025-06-19
2026-02-17 2026-04-05 2026-06-04
2027-02-09 2027-03-28 2027-05-27
2028-02-29 2028-04-16 2028-06-15
2029-02-13 2029-04-01 2029-05-31
2030-03-05 2030-04-21 2030-06-20
```

The dates are for the _Western_ _Church_.

## More Examples

Check further [examples at the man page](man#examples).

## Dependencies

- `Ksh93`, `Bash`, or `Zsh`
- `GNU`/`BSD`/`AST`/`Busybox` `date` (optional)
- Basic Calculator `bc` and Desk Calculator `dc` (optional)

### Debugging dependencies

- `datedff.debug.sh` script
- Hroptatyr's `C-code datediff`

## Help

Please, check script help page with `datediff.sh -h`
or the [online man page](man/README.md).

## Project Source

- GitLab
- GitHub

Extensively tested, see [testing scripts](tests/), [notes](tests/d-test.sh#L78-L186), and [man page](man/README.md).

## See Also

- C-code `dateutils/datediff`, *Hroptatyr*, .
- C-code `datediff`, *William C. Hammel*, .
- Python `PDD`, *Jarun*, .
- *AST* `date`, see elapsed time _option_ _-E_, .
- *GNU* `units`, .
- \`\`Calendrical calculation'', *Dershowitz* and *Reingold*, 1990, .

---




Datediff.sh script dark theme logo
   
Datediff.sh script light theme logo