Skip to content

Instantly share code, notes, and snippets.

@criztovyl
Created January 26, 2016 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save criztovyl/f625d1c1ab450a285a36 to your computer and use it in GitHub Desktop.
Save criztovyl/f625d1c1ab450a285a36 to your computer and use it in GitHub Desktop.
Calculates differences between months, also across years.
#!/bin/bash
# Script for calculating month differences
# Copyright (C) 2016 Christoph "criztovyl" Schulz
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if [[ "$1" =~ ^-{0,2}h(elp)?$ ]]; then
echo -e "Usage: $0 YYYY-MM YYYY-MM\n first one is start, second one end."
echo " Both dates can be \"-\" when should be read from stdin."
echo " When both are \"-\", start date is read first."
echo " Use \"\" for use default value, e.g. when using default start but custom end."
echo "Defaults:"
echo " MONTHDIFF_X_DEFAULT: Default string value, X must be START or END."
echo " MONTHDIFF_X_DEFAULT_EXEC: Command that returns default value, X must be START or END."
echo " Will look for string value first and then for command."
echo " Examples:"
echo " MONTHDIFF_START_DEFAULT=\"2015-09\""
echo " MONTHDIFF_END_DEFAULT_EXEC=\"date +%Y-%m\""
exit
fi
EXIT_DATE_INVALID=5
EXIT_MISSING_DATE=6
# Determine defaults
for name in start end; do
var=MONTHDIFF_${name^^}_DEFAULT
if [ "${!var}" ]; then
eval $name"_default"=${!var}
else
var=$var"_EXEC"
[ "${!var}" ] && eval $name"_default"=`${!var}`
fi
done
start=$1
end=$2
for name in start end; do
[ "${!name}" == "-" ] && read $name;
[ -z "${!name}" ] && eval $name=\$$name"_default"
done
[ -z "$start" ] || [ -z "$end" ] && { echo "Missing start and/or end date."; exit $EXIT_MISSING_DATE; }
yearNmonth(){
# Args: varName
# Returns: String that would create an array with index 0 year and index 1 month. (Use it with eval)
varName=$1
RE_yearNmonth='([[:digit:]]{4})-0?([[:digit:]]{1,2})'; [[ "${!varName}" =~ $RE_yearNmonth ]] || { echo "exit $EXIT_DATE_INVALID"; exit; }
echo "declare $varName=(${BASH_REMATCH[1]} ${BASH_REMATCH[2]})"
}
echo "From $start to $end" >&2
eval $(yearNmonth "start")
eval $(yearNmonth "end")
# start to end
# yyyy-aa to zzzz-bb: x=( a-b + 12*(y-z) )*(-1)
echo $(( ( ${start[1]}-${end[1]} + 12*(${start[0]}-${end[0]}) )*(-1) ))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment