如何在ksh shell脚本中计算上一个工作日?

时间:2008-10-22 00:15:26

标签: shell date ksh

在shell ksh脚本中计算上一个工作日的最优雅方法是什么?

到目前为止我得到的是:

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

如何将$ {DAY_DIFF}变量作为值而不是字符串传输?

4 个答案:

答案 0 :(得分: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)

答案 1 :(得分:2)

这是一个不使用Perl的解决方案。它适用于kshsh

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

答案 2 :(得分:0)

好吧,如果运行Perl算作脚本的一部分,那么在Perl中开发答案。接下来的问题是 - 什么定义了工作日?你是周日营业的商店/商店吗?星期六?或周一至周五9-5的业务?假期怎么样?

假设你想周一到周五,假期暂时不重要,那么你可以在Perl中使用一个算法,它注意周日的星期日到星期六的星期日为0,因此如果星期日是1,你需要减去3 * 86400 from time();如果wday为0,则需要减去2 * 86400;如果wday是6,你需要减去1 * 86400.这就是你在Korn shell中所拥有的东西 - 只需在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));

这假设你有POSIX模块;如果没有,那么你需要做与你使用的大致相同的printf()。我还优先使用ISO 8601格式的日期(也由XSD和SQL使用) - 因此说明的格式。

答案 3 :(得分:0)

这适用于Solaris和Linux。在Unix上实际上很复杂,你不能在所有Unix派生上使用相同的命令行参数。

在Linux上,您可以使用date -d '-d24 hour ago'来获取最后一天 在Solaris上TZ=CET+24 date。我猜其他UNIX的工作方式与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