2008-10-22 4 views
6

Quelle est la manière la plus élégante de calculer le jour ouvrable précédent dans le script shell ksh?Comment calculer le jour ouvrable précédent dans un script shell ksh?

Ce que je suis jusqu'à présent est:

#!/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 

Comment puis-je faire la variable $ {} de DAY_DIFF à transmettre comme valeur et non en tant que chaîne?

+0

Vous avez laissé de côté samedi ... –

+0

Scratch qui - il est couvert par le réglage par défaut de DAY_DIFF = 1 avant que l'affaire ... Il serait plus clair si le défaut était dans le cas. –

+0

La réponse directe à la question "Comment ..." est: placer une citation avant et une autre après $ {DAY_DIFF} dans la commande perl. –

Répondre

0

Eh bien, si l'exécution de Perl compte dans le script, développez la réponse en Perl. La question suivante est: qu'est-ce qui définit un jour ouvrable? Êtes-vous un magasin/magasin ouvert le dimanche? Samedi? Ou un 9-5 du lundi au vendredi des affaires? Et les vacances? En supposant que vous pensez du lundi au vendredi et que les vacances soient provisoirement immatérielles, vous pouvez utiliser un algorithme en Perl qui note que wday sera 0 du dimanche au samedi 6, et donc si wday vaut 1, vous devez soustraire 3 * 86400 du temps(); si wday vaut 0, vous devez soustraire 2 * 86400; et si wday est 6, vous devez soustraire 1 * 86400. C'est ce que vous avez dans les choses shell Korn - il suffit de le faire dans le Perl à la place:

#!/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)); 

Cela ne suppose que vous avez le module POSIX; sinon, vous devrez faire à peu près le même printf() que vous avez utilisé. J'utilise aussi le format ISO 8601 pour les dates par préférence (également utilisé par XSD et SQL) - d'où le format illustré.

+0

Le jour ouvrable est un terme standard qui n'inclut jamais Sat et Sun. – jwg

2

Voici une solution qui n'utilise pas Perl. Il fonctionne à la fois avec ksh et 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 (e.g., Linux) 
    date -d "1970-01-01 00:00 UTC + $seconds seconds" $format 
else 
    # For BSD date (e.g., Mac OS X) 
    date -r $seconds $format 
fi 
3
#!/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) 
0

Cela devrait fonctionner pour Solaris et Linux. C'est vraiment compliqué sur Unix que vous ne pouvez pas utiliser les mêmes arguments de la ligne de commande sur tous les dérivés Unix.

Sur Linux, vous pouvez utiliser date -d '-d24 hour ago' pour obtenir le dernier jour sur Solaris son TZ=CET+24 date. Je suppose que les autres UNIX fonctionnent de la même manière que 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 
Questions connexes