How to calculate previous working day in ksh shell script?

What is the most elegant way to calculate the previous working day in a ksh script shell?

What I got so far:

#!/bin/ksh set -x DAY_DIFF=1 case `date '+%a'` in "Sun") DAY_DIFF=2 ;; "Mon") DAY_DIFF=3 ;; esac PREV_DT=`perl -e '($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time()-${DAY_DIFF}*24*60*60);printf "%4d%02d%02d",$year+1900,$mon+1,$mday;'` echo $PREV_DT 

How do I convert the variable $ {DAY_DIFF} as a value, and not as a string?

+6
date shell ksh
source share
4 answers
 #!/bin/ksh # GNU date is a veritable Swiss Army Knife... ((D=$(date +%w)+2)) if [ $D -gt 3 ]; then D=1; fi PREV_DT=$(date -d "-$D days" +%F) 
+3
source share

Here is a solution that does not use Perl. It works with both ksh and sh .

 #!/bin/ksh diff=-1 [ `date +%u` == 1 ] && diff=-3 seconds=$((`date +%s` + $diff * 24 * 3600)) format=+%Y-%m-%d if date --help 2>/dev/null | grep -q -- -d ; then # GNU date (eg, Linux) date -d "1970-01-01 00:00 UTC + $seconds seconds" $format else # For BSD date (eg, Mac OS X) date -r $seconds $format fi 
+2
source share

Well, if Perl is calculated as part of a script, then create a response to Perl. The next question is what determines the working day. Are you a store / shop that is open on Sunday? Saturday? Or 9-5 from Monday to Friday? What about the holidays?

Assuming you think Monday through Friday and the holidays are temporarily irrelevant, then you can use the Perl algorithm, which notes that wday will be 0 on Sunday after 6 on Saturday, and so if wday is 1, you need to subtract 3 * 86400 from time to time (); if wday is 0, you need to subtract 2 * 86400; and if wday is 6, you need to subtract 1 * 86400. This is what you have in the Korn shell - just do it in Perl:

 #!/bin/perl -w use strict; use POSIX; use constant SECS_PER_DAY => 24 * 60 * 60; my(@days) = (2, 3, 1, 1, 1, 1, 1); my($now) = time; my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now); print strftime("%Y-%m-%d\n", localtime($now - $days[$wday] * SECS_PER_DAY)); 

This assumes that you have a POSIX module; if not, you will need to do approximately the same printf () as you. I also use the ISO 8601 format for preference dates (also used by XSD and SQL) - hence the illustrated format.

0
source share

This should work for Solaris and Linux. It really complicates Unix that you cannot use the same command line arguments for all Unix derivatives.

On Linux, you can use date -d '-d24 hour ago' to get the last day on Solaris - TZ=CET+24 date . I think other UNIX's work just like Solaris.

 #!/usr/bin/ksh lbd=5 # last business day (1=Mon, 2=Thu ... 6=Sat, 7=Sun) lbd_date="" # last business day date function lbdSunOS { typeset back=$1 typeset tz=`date '+%Z'` # timezone lbd_date=`TZ=${tz}+$back date '+%Y%m%d'` } function lbdLinux { typeset back=$1 lbd_date=`date -d "-d$back hour ago"` } function calcHoursBack { typeset lbd=$1 typeset dow=`date '+%u'` # day of the week if [ $dow -ge $lbd ] then return $(((dow-lbd)*24)) else return $(((dow-lbd+7)*24)) fi } # Main calcHoursBack $lbd lbd`uname -s` $? echo $lbd_date 
0
source share

All Articles