2

I am writing a shell script, and need to calculate the first and last days of a quarter from the current date. This is for use in Ingres 10 SQL statements triggered from within the script. The Ingres runs on a Solaris server with ksh.

So, if today is 31/01/17, I would want to calculate the following

  1. the first date of the current quarter (01/01/17)
  2. the last date of the current quarter (31/03/17). It would be OK here to return an exclusive to date if necessary (i.e. 01/04/17)
  3. the first date of the previous quarter (01/10/16)
  4. the last date of the previous quarter (31/12/16). An exclusive-to result of 01/01/17 would also be OK.

Can anyone please help? I've seen questions related to getting the quarter number but that's not really helping.

I've tried the following but its not working as the variables are not being populated in the case statement

CURR_MONTH=`date +%m`
echo "Current month num = $CURR_MONTH"

CURR_YEAR=`date +%Y`
echo "Current year = $CURR_YEAR"

let "LAST_YEAR = $CURR_YEAR - 1"
echo "Last year = $LAST_YEAR"


case $CURR_MONTH in
05) CURR_Q_FROM = 01.04.${CURR_YEAR}
CURR_Q_TO = "30.06.${CURR_YEAR}"
PREV_Q_FROM = "01.01.${CURR_YEAR}"
PREV_Q_TO = "31.03.${CURR_YEAR}" ;;
esac

echo "Current Q From = $CURR_Q_FROM"
echo "Current Q To = $CURR_Q_TO"
echo "Prev Q From = $PREV_Q_FROM"
echo "Prev Q To = $PREV_Q_TO"

I get the following output

Current month num = 05
Current year = 2017
Last year = 2016
Month to be extracted = April 2017
./stats_report_monthly.sh[85]: CURR_Q_FROM:  not found
./stats_report_monthly.sh[86]: CURR_Q_TO:  not found
./stats_report_monthly.sh[87]: PREV_Q_FROM:  not found
./stats_report_monthly.sh[88]: PREV_Q_TO:  not found
Current Q From =
Current Q To =
Prev Q From =
Prev Q To =
6
  • Do you need to run date on the Solaris host?
    – Jeff Schaller
    Commented May 5, 2017 at 12:39
  • assume so, as I don't know what other alternative would be available to get the current date? Commented May 5, 2017 at 12:40
  • Theoretically you could generate the dates somewhere else, like a gnu Linux box (which has more features) then transfer the dates or a resulting sql script to the Solaris box.
    – Jeff Schaller
    Commented May 5, 2017 at 12:41
  • 1
    You can use the date command to get the current month. Then you have one of 4 choices of which quarter it is. From there you have 4 cases to calculate the years and days. You can can hard code days and months and need to retrieve year an maybe subtract one if in first quarter and you need previous quarter. Commented May 5, 2017 at 12:52
  • 1
    @JeffSchaller thank you, shellcheck.net looks awesome! :) Commented May 5, 2017 at 15:21

1 Answer 1

2

With ksh93 (also /bin/sh on Solaris 11):

#! /usr/bin/ksh -
eval "$(printf '%(y=%Y m=%-m)T')"
first=$(printf '%(%F)T' "$y-$(((m-1)/3*3+1))-1")
last=$(printf '%(%F)T' "$first next 2 months last day")
echo "$first $last"

first2=$(printf '%(%F)T' "$first last 3 months")
last2=$(printf '%(%F)T' "$first2 next 2 months last day")
echo "$first2 $last2"

Example:

$ ./quarter
2017-04-01 2017-06-30
2017-01-01 2017-03-31
$ faketime 2017-01-31 ./quarter
2017-01-01 2017-03-31
2016-10-01 2016-12-31

Using your approach, that would be:

eval "$(date +'y=%Y m=%m')"
case $m in
  (0[1-3])
     echo "$y-01-01 $y-03-31"
     echo "$((y-1))-10-01 $((y-1))-12-31";;
  (0[4-6])
     echo "$y-04-01 $y-06-30"
     echo "$y-01-01 $y-03-31";;
  (0[7-9])
     echo "$y-07-01 $y-09-30"
     echo "$y-04-01 $y-06-30";;
  (*)
     echo "$y-10-01 $y-12-31"
     echo "$y-07-01 $y-09-30"
esac

In any case, note that the syntax of variable assignments in Bourne-like shells is:

var=value

No space on either side of =.

8
  • I tried first section and got './test.sh[3]: (m-1)/3*3+1: bad number' error. I tried to find out which version of ksh I have and none of the three solutions in the Q in this post unix.stackexchange.com/questions/199900/… helped. Commented May 9, 2017 at 10:27
  • @Ben, is it Solaris 11 or older? On Solaris 11, /bin/sh, /bin/ksh and /bin/ksh93 are ksh93u while /usr/xpg4/bin/sh is based on ksh88i (Bourne shell in /usr/sunos/bin/sh). You'll have no luck with Solaris 10 and older where /bin/sh is a Bourne shell (!), /bin/ksh and /usr/xpg4/bin/sh are based on ksh88i, /usr/dt/bin/dtksh (if installed) based on ksh93d (from over 20 years ago!) Commented May 9, 2017 at 10:41
  • It's Solaris 10. We are getting new M10 servers soon which I'm hoping will have Solaris 11 on, I'll check. Commented May 9, 2017 at 10:48
  • @Ben, Then you can use the second approach which should work with any POSIX shell (/usr/xpg4/bin/sh or /bin/ksh in Solaris 10). Commented May 9, 2017 at 10:49
  • Thanks, I didn't know how powerful printf was, I found this with explains more. blog.fpmurphy.com/2008/10/… Commented May 9, 2017 at 11:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .