How to calculate months and display in shell scripting

I just want to know, how do we calculate the months in shell scripting.

If i give the input as 20-01-2011, the output should be 20-02-2011, 20-03-2011 or 20-04-2011........

How do i get this ?

Cheers.

not sure exactly what you mean...do you want all months for a given year ? or all successive months, or just next month?

here's a start point for you to have a play with:

#  for x in {1..12}; do printf "20-%02d-2011\n" $x ;done
20-01-2011
20-02-2011
20-03-2011
20-04-2011
20-05-2011
20-06-2011
20-07-2011
20-08-2011
20-09-2011
20-10-2011
20-11-2011
20-12-2011

HTH

ksh93 has date arithmetic.

Hi Tytalus,

Thanks for your time....

What I need is, for example I am providing the input as 01-01-2011.

The system should accept it and increment it by one month and should display the output as 01-02-2011.

Similarly if the input is 01-12-2011, the output should be 01-01-2012.

Any solution for this will be of great help.....

Cheers.

Your solution is not so simple as to add one to the month and to handle the year.

What if your input is: 01-31-2011

What is your expected output?

ms:/home/unxsa/functions>today
27May2011
ms:/home/unxsa/functions>today -p 30
26Jun2011
ms:/home/unxsa/functions>cat today
# Name: today
#
# Purpose: Prints today's date, plus or minus the given number of days.
#          Default is today's date.
#
# Date: 2006/06/08
#
# Version: 1.0
#
# Required Parameters:
# -------------------------------------------------------------------------
#
# Optional Parameters:
#   -f [format]- format of date to use
#   -p #- number of days to add
#   -m #- number of days to subtract
#   -c c- character to use in the date string
#   -s- use short year string
# -------------------------------------------------------------------------
#
# Change History:
#
# Date          Name            Comments
# _________________________________________________________________________
# 2006/06/08    selbyp          Created.
# 21 jan 2011   purdym          converted to ksh93
#
#
#
#
#
#
#
#
#
#
#
#



###################################################################################
# function
###################################################################################
function today {

   USAGE=":f:p:m:c:sh"

   FORMAT=0
   PLUS=0
   MINUS=0
   SEPCHAR=""
   SHORT=0

   if [[ $# -gt 0 ]]
   then
      while getopts "${USAGE}" OPT
      do
         case ${OPT} in
            f) FORMAT=${OPTARG};;
            p) PLUS=${OPTARG};;
            m) MINUS=${OPTARG};;
            c) SEPCHAR=${OPTARG};;
            s) SHORT=1;;
            h) cat <<EOF
Syntax:  today { [-p n] OR [-m n] } [-f FORMAT] [-c CHAR] [-s] [-h]
Parameters:
[-p n]-Print today's date, plus n days
[-m n]-Print today's date, minus n days
[-f FMT]-Print date using specified format (DMY/MDY/YMD), default looks like Jun092006
[-c c]-Separate dates using the character c
[-s]-Use a short year in the date
[-h]-View this help
Default:  Print today's date in the default format.
EOF
            return 0
            ;;
            ?) echo "today(): unrecognized option: ${OPT}"
            return 1;;
         esac
      done

      shift $((${OPTIND} - 1))
      ARGUMENTS=$@

      if (( ${PLUS} != 0 && ${MINUS} != 0 ))
      then
         RETCODE=1
         (( ${DEBUG} != 0 )) && print "today(): Attempted to add and subtract simultaneously."
         return $RETCODE
      fi

      if [[ ${FORMAT} -ne 0 && ${FORMAT} != "YMD" && ${FORMAT} != "MDY" && ${FORMAT} != "DMY" ]]
      then
         RETCODE=2
         (( ${DEBUG} != 0 )) && print "today(): Unrecognized format: ${FORMAT}"
         return $RETCODE
      fi

      if (( ${#SEPCHAR} > 1 ))
      then
         RETCODE=3
         (( ${DEBUG} -ne 0 )) && print "today(): Bad separating character: ${SEPCHAR}"
         return $RETCODE
      fi
   fi

   eval `date "+DAY=%d; MONTH=%m; YEAR=%Y`

   if (( $PLUS > 0 ))
   then
      DAY=$((DAY + PLUS))

   elif (( $MINUS > 0 ))
   then
      DAY=$((DAY - MINUS))

   fi

   if (( $DAY <= 0 ))
   then
      while (( $DAY <= 0 ))
      do
         MONTH=$((MONTH - 1))
         if (( $MONTH == 0 ))
         then
            YEAR=$(( YEAR - 1))
            MONTH=12
         fi
         set -A DAYS $(cal $MONTH $YEAR)
         XDAY=${DAYS[$((${#DAYS
[*]} - 1 ))]}
         DAY=$((XDAY + DAY))

      done
   else
      set -A DAYS $(cal $MONTH $YEAR)
      MAXDAY=${DAYS[$((${#DAYS
[*]} - 1 ))]}

       if (( $DAY > $MAXDAY ))
       then
          while (( $DAY > $MAXDAY ))
          do
             DAY=$((DAY - MAXDAY))
             MONTH=$((MONTH + 1))
             if (( MONTH > 12 ))
             then
                YEAR=$((YEAR + 1))
                MONTH=1
             fi
             set -A DAYS $(cal $MONTH $YEAR)
             MAXDAY=${DAYS[$((${#DAYS
[*]} - 1 ))]}
             done
          fi
       fi

       if (( $SHORT != 0 ))
       then
          if (( ${#YEAR} == 4 ))
          then
             OLD_YEAR=${YEAR}
             typeset -Z2 YEAR
             YEAR=$( echo ${OLD_YEAR} | cut -c 3-4 )

          elif (( ${#YEAR} != 2 ))
          then
             if [[ ! -z $DEBUG ]] && [[ $DEBUG -gt 0 ]]
             then
                echo "today(): what kind of year is this: ${YEAR}??"
                return 1
             fi
          fi
       fi

    typeset -Z2 F_DAY F_MONTH
    F_DAY=$DAY
    F_MONTH=$MONTH

       if [[ $FORMAT == "YMD" ]]
       then
          print "${YEAR}${SEPCHAR}${F_MONTH}${SEPCHAR}${F_DAY}"

       elif [[ $FORMAT == "DMY" ]]
       then
          print "${F_DAY}${SEPCHAR}${F_MONTH}${SEPCHAR}${YEAR}"

       elif [[ $FORMAT == "MDY" ]]
       then
          print "${F_MONTH}${SEPCHAR}${F_DAY}${SEPCHAR}${YEAR}"

       else
          case $F_MONTH in
             01) MONTH_STR=Jan;;
             02) MONTH_STR=Feb;;
             03) MONTH_STR=Mar;;
             04) MONTH_STR=Apr;;
             05) MONTH_STR=May;;
             06) MONTH_STR=Jun;;
             07) MONTH_STR=Jul;;
             08) MONTH_STR=Aug;;
             09) MONTH_STR=Sep;;
             10) MONTH_STR=Oct;;
             11) MONTH_STR=Nov;;
             12) MONTH_STR=Dec;;
          esac
       print ${F_DAY}${MONTH_STR}${YEAR}
    fi

}
read DATE; date -d "$DATE 1 month"